1- #set the minimum cmake version required
1+ # Set the minimum cmake version required
22cmake_minimum_required (VERSION 3.18.0)
33
4- #set the name of the project
4+ # Tell CMake to re-run configuration when these files change (get around Qt issues with stale CMake files)
5+ set (_cmake_files_to_watch
6+ "${CMAKE_SOURCE_DIR} /CMakeLists.txt"
7+ "${CMAKE_SOURCE_DIR} /CMakePresets.json"
8+ )
9+
10+ # Watch any helper .cmake files under cmake/
11+ file (GLOB_RECURSE _cmake_helper_files "${CMAKE_SOURCE_DIR} /cmake/*.cmake" )
12+ list (APPEND _cmake_files_to_watch ${_cmake_helper_files} )
13+
14+ # Append to the directory property so CMake will reconfigure when these change
15+ set_property (DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${_cmake_files_to_watch} )
16+ #message(STATUS "CMake will reconfigure when these change: ${_cmake_files_to_watch}")
17+
18+ # Set the project name
519project (SerialPrograms)
620
7- #enable c++ 23
21+ # Enable C++ 23
822set (CMAKE_CXX_STANDARD 23)
923set (CMAKE_CXX_STANDARD_REQUIRED ON )
1024
11- #produce clang tidy file
25+ # Produce clang tidy file
1226set (CMAKE_EXPORT_COMPILE_COMMANDS ON )
1327#set(CMAKE_VERBOSE_MAKEFILE ON)
1428
1529set (CMAKE_AUTOMOC ON )
1630set (CMAKE_AUTORCC ON )
1731set (CMAKE_AUTOUIC ON )
1832
19- # Set root dir for convenience
20- set (PROJECT_ROOT_DIR "${CMAKE_SOURCE_DIR} /.." )
21- get_filename_component (PROJECT_ROOT_DIR "${CMAKE_SOURCE_DIR} /.." ABSOLUTE )
22-
2333add_custom_target (build -time-make-directory ALL
2434 COMMAND ${CMAKE_COMMAND} -E make_directory Assembly/)
2535
2636# Find repo root folder path
27- string (FIND "${CMAKE_CURRENT_SOURCE_DIR} " "Arduino-Source-Internal" internal_repro_position) # determine if this is an internal repo
28- if (internal_repro_position EQUAL -1) # no "Arduino-Source-Internal" substr in the current source dir
29- # we are building the public repo
30- set (REPO_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR} /../" )
37+ string (FIND "${CMAKE_CURRENT_SOURCE_DIR} " "Arduino-Source-Internal" internal_repo_position)
38+
39+ # Determine if this is an internal repo and normalize REPO_ROOT_DIR
40+ if (internal_repo_position EQUAL -1)
41+ # We are building the public repo
42+ set (REPO_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR} /../" )
43+ else ()
44+ # We are building the internal repo
45+ set (REPO_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR} /../../../" )
46+ endif ()
47+
48+ # Determine environment
49+ if (DEFINED ENV{GITHUB_ACTIONS})
50+ message (STATUS "Detected CI environment, skipping file deployment" )
51+ set (DEPLOY_FILES FALSE )
52+ else ()
53+ message (STATUS "Detected local dev environment" )
54+ set (PACKAGES_DIR "${REPO_ROOT_DIR} /Packages" )
55+
56+ # Add a custom command to clone Packages
57+ if (NOT EXISTS "${PACKAGES_DIR} /.git" )
58+ add_custom_command (
59+ OUTPUT "${PACKAGES_DIR} /.git"
60+ COMMAND ${CMAKE_COMMAND} -E echo "Cloning Packages repo..."
61+ COMMAND ${CMAKE_COMMAND} -E make_directory "${PACKAGES_DIR} "
62+ COMMAND git clone --branch master https://github.com/PokemonAutomation/Packages "${PACKAGES_DIR} "
63+ WORKING_DIRECTORY "${REPO_ROOT_DIR} "
64+ COMMENT "Cloning Packages repository"
65+ VERBATIM
66+ )
67+ endif ()
68+
69+ list (APPEND _cmake_files_to_watch "${PACKAGES_DIR} /.git" )
70+ # Add a custom target which we will depend on in executable_add() later on
71+ add_custom_target (
72+ PackagesRepo
73+ DEPENDS "${PACKAGES_DIR} /.git"
74+ )
75+
76+ # Set paths for post-build deployment
77+ set (FIRMWARE_DIR "${PACKAGES_DIR} /PABotBase/PABotBase-Switch" )
78+ set (SCRIPTS_DIR "${PACKAGES_DIR} /SerialPrograms/Scripts" )
79+ set (RESOURCES_DIR "${PACKAGES_DIR} /SerialPrograms/Resources" )
80+
81+ if (PACKAGE_BUILD)
82+ set (DEST_DIR "$<TARGET_FILE_DIR:SerialPrograms>/Output" )
83+ set (DEPLOY_DIR "${DEST_DIR} /Binaries64" )
3184 else ()
32- # we are building the internal repo
33- set (REPO_ROOT_DIR "${CMAKE_CURRENT_SOURCE_DIR} /../../../ " )
85+ set (DEST_DIR "$<TARGET_FILE_DIR:SerialPrograms>" )
86+ set (DEPLOY_DIR "${DEST_DIR} " )
3487 endif ()
3588
89+ set (DEPLOY_FILES TRUE )
90+ endif ()
91+
3692#Find threads library
3793set (THREADS_PREFER_PTHREAD_FLAG ON )
3894find_package (Threads REQUIRED)
3995
40- #find Qt
96+ # Define the major version of Qt to search for
4197if (NOT QT_MAJOR)
4298 set (QT_MAJOR 6)
4399endif ()
44- find_package (Qt${QT_MAJOR} COMPONENTS Widgets SerialPort Multimedia MultimediaWidgets REQUIRED)
100+
101+ # Make sure CI builds work without going overboard with per-platform directory shenanigans
102+ if (NOT DEPLOY_FILES)
103+ find_package (Qt${QT_MAJOR} COMPONENTS Widgets SerialPort Multimedia MultimediaWidgets REQUIRED)
104+ endif ()
105+
106+ # Find Qt and windeployqt.exe relative to the Qt bin dir
107+ if (WIN32 AND DEPLOY_FILES)
108+ # Define the base Qt installation directory
109+ if (PREFERRED_QT_DIR AND PREFERRED_QT_VER)
110+ set (QT_CANDIDATE_DIR "${PREFERRED_QT_DIR} /${PREFERRED_QT_VER} /msvc2022_64/lib/cmake" )
111+ endif ()
112+
113+ # Set default base directory just in case, validate that Qt specified in CMakePresets.json exists
114+ # Otherwise search out the latest available in the default Qt directory.
115+ set (QT_BASE_DIR "C:/Qt" )
116+ if (QT_CANDIDATE_DIR AND EXISTS "${QT_CANDIDATE_DIR} " )
117+ message (STATUS "Using preferred Qt directory for Qt${QT_MAJOR} ${PREFERRED_QT_VER} : ${QT_CANDIDATE_DIR} " )
118+ set (CMAKE_PREFIX_PATH "${QT_CANDIDATE_DIR} " )
119+ find_package (Qt${QT_MAJOR} ${PREFERRED_QT_VER} COMPONENTS Widgets SerialPort Multimedia MultimediaWidgets REQUIRED)
120+ else ()
121+ # Find all subdirectories in the Qt base directory
122+ find_package (Qt${QT_MAJOR} COMPONENTS Widgets SerialPort Multimedia MultimediaWidgets REQUIRED)
123+ file (GLOB QT_SUBDIRS LIST_DIRECTORIES true "${QT_BASE_DIR} /${QT_MAJOR} *" )
124+
125+ # Filter and sort the directories to find the latest version
126+ list (SORT QT_SUBDIRS)
127+ list (REVERSE QT_SUBDIRS)
128+
129+ # Get the first directory in the sorted list (latest version)
130+ list (GET QT_SUBDIRS 0 QT_LATEST_DIR)
131+
132+ # Debug message to verify the latest Qt directory
133+ if (QT_LATEST_DIR)
134+ message (STATUS "Latest Qt directory for Qt${QT_MAJOR} : ${QT_LATEST_DIR} " )
135+ set (CMAKE_PREFIX_PATH "${QT_LATEST_DIR} /msvc2022_64/lib/cmake" )
136+ else ()
137+ message (FATAL_ERROR "No Qt${QT_MAJOR} installation found in ${QT_BASE_DIR} " )
138+ endif ()
139+ endif ()
140+
141+ # Find windeployqt.exe for Qt dependency deployment
142+ get_target_property (qt_core_location Qt${QT_MAJOR} ::Core LOCATION )
143+ get_filename_component (qt_bin_dir "${qt_core_location} " DIRECTORY )
144+ find_program (WINDEPLOYQT_EXECUTABLE windeployqt
145+ HINTS "${qt_bin_dir} "
146+ PATH_SUFFIXES ../bin bin
147+ REQUIRED
148+ )
149+ endif ()
150+
45151#disable deprecated Qt APIs
46152add_compile_definitions (QT_DISABLE_DEPRECATED_BEFORE=0x050F00)
47153
@@ -2449,7 +2555,7 @@ if (APPLE)
24492555
24502556 # make sure Packages repo, https://github.com/PokemonAutomation/Packages is placed in the same folder as this Arduino-Source repo
24512557 # so the post-build command can copy the resources folder Packages/SerialPrograms/Resources/ into the built app bundle:
2452- set (RESOURCES_PATH "${REPO_ROOT_DIR} ../Packages/SerialPrograms/Resources" )
2558+ set (RESOURCES_PATH "${REPO_ROOT_DIR} / ../Packages/SerialPrograms/Resources" )
24532559 message (STATUS "Set Resources folder path from Packages repo: ${RESOURCES_PATH} " )
24542560 add_custom_command (
24552561 TARGET SerialPrograms
@@ -2458,7 +2564,28 @@ if (APPLE)
24582564 "${RESOURCES_PATH} "
24592565 "$<TARGET_FILE_DIR:SerialPrograms>/../Resources"
24602566 )
2461- else () # WIN and Linux:
2567+ elseif (WIN32 AND DEPLOY_FILES)
2568+ # Set directories and file dependencies (we HAVE to depend on a file for build-time extraction/git clone to work)
2569+ set (OPENCV_DEBUG_ZIP "${REPO_ROOT_DIR} /3rdPartyBinaries/opencv_world4110d.zip" )
2570+ set (OPENCV_DEBUG "${REPO_ROOT_DIR} /3rdPartyBinaries/opencv_world4110d.dll" )
2571+
2572+ set (DISCORD_ZIP "${REPO_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win.zip" )
2573+ set (DISCORD_LIB_DEBUG "${REPO_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win/lib/debug/discord_partner_sdk.lib" )
2574+ set (DISCORD_LIB_RELEASE "${REPO_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win/lib/release/discord_partner_sdk.lib" )
2575+
2576+ list (APPEND _cmake_files_to_watch "${DISCORD_LIB_DEBUG} " )
2577+ list (APPEND _cmake_files_to_watch "${DISCORD_LIB_RELEASE} " )
2578+ list (APPEND _cmake_files_to_watch "${OPENCV_DEBUG} " )
2579+
2580+ add_custom_target (ExtractDependencies
2581+ COMMENT "Extracting 3rd party dependencies..."
2582+ DEPENDS ${DISCORD_LIB_DEBUG} ${DISCORD_LIB_RELEASE} ${OPENCV_DEBUG}
2583+ )
2584+
2585+ add_executable (SerialPrograms WIN32 ${MAIN_SOURCES} )
2586+ add_dependencies (SerialPrograms ExtractDependencies)
2587+ add_dependencies (SerialPrograms PackagesRepo)
2588+ else ()
24622589 add_executable (SerialPrograms WIN32 ${MAIN_SOURCES} )
24632590endif ()
24642591
@@ -2477,19 +2604,6 @@ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../Internal/SerialPrograms/Internal0.
24772604 target_sources (SerialPrograms PRIVATE ../../Internal /SerialPrograms/Internal1.cpp)
24782605endif ()
24792606
2480- #extract opencv_world4110d.dll from archive on Windows Debug build, extract Discord Social SDK
2481- if (WIN32 )
2482- file (ARCHIVE_EXTRACT
2483- INPUT ${CMAKE_CURRENT_SOURCE_DIR} /../3rdPartyBinaries/opencv_world4110d.zip
2484- DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} /../3rdPartyBinaries/
2485- )
2486-
2487- file (ARCHIVE_EXTRACT
2488- INPUT ${CMAKE_CURRENT_SOURCE_DIR} /../3rdPartyBinaries/discord_social_sdk_win.zip
2489- DESTINATION ${CMAKE_CURRENT_SOURCE_DIR} /../3rdPartyBinaries/
2490- )
2491- endif ()
2492-
24932607#add include directory
24942608target_include_directories (SerialPrograms SYSTEM PRIVATE ../3rdParty/)
24952609target_include_directories (SerialPrograms PRIVATE ../ ../../Internal / Source /)
@@ -2796,26 +2910,111 @@ SET_SOURCE_FILES_PROPERTIES(
27962910)
27972911endif ()
27982912
2913+ if (WIN32 AND NOT DEPLOY_FILES)
2914+ file (GLOB MY_DLLS
2915+ "../3rdPartyBinaries/*.dll"
2916+ )
2917+ file (COPY ${MY_DLLS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR} )
27992918
2919+ message (STATUS "Extracting opencv_world4110d" )
2920+ file (ARCHIVE_EXTRACT
2921+ INPUT ${REPO_ROOT_DIR} /3rdPartyBinaries/opencv_world4110d.zip
2922+ DESTINATION ${REPO_ROOT_DIR} /3rdPartyBinaries/
2923+ )
28002924
2925+ set (DISCORD_SDK_ZIP "${REPO_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win.zip" )
2926+ set (DISCORD_SDK_DIR "${REPO_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win" )
2927+ if (EXISTS "${DISCORD_SDK_ZIP} " AND NOT EXISTS "${DISCORD_SDK_DIR} " )
2928+ message (STATUS "Extracting Social SDK" )
2929+ file (ARCHIVE_EXTRACT
2930+ INPUT "${DISCORD_SDK_ZIP} "
2931+ DESTINATION "${REPO_ROOT_DIR} /3rdPartyBinaries"
2932+ )
2933+ endif ()
2934+ endif ()
28012935
2802- if (WIN32 )
2803- #copy needed dlls
2804- #file(COPY *.dll DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
2805- file (GLOB MY_DLLS
2806- "../3rdPartyBinaries/*.dll"
2807- )
2808- file (COPY ${MY_DLLS} DESTINATION ${CMAKE_CURRENT_BINARY_DIR} )
2809-
2810- # Copy discord_social_sdk DLL based on build type
2811- add_custom_command (
2812- TARGET SerialPrograms
2813- POST_BUILD
2814- COMMAND ${CMAKE_COMMAND} -E copy
2815- $<IF:$<CONFIG:Debug>,"${PROJECT_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win/bin/debug/discord_partner_sdk.dll" ,"${PROJECT_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win/bin/release/discord_partner_sdk.dll" >
2816- $<TARGET_FILE_DIR:SerialPrograms>/Binaries64/discord_partner_sdk.dll
2817- COMMENT "Copying Discord SDK DLL to Binaries64"
2818- )
2936+ if (WIN32 AND DEPLOY_FILES)
2937+ # Ensure target dirs and copy content folders
2938+ set (DEPLOY_CMDS)
2939+ list (APPEND DEPLOY_CMDS
2940+ COMMAND ${CMAKE_COMMAND} -E echo "[Deploy] Ensure deploy dir exists: ${DEPLOY_DIR} "
2941+ COMMAND ${CMAKE_COMMAND} -E make_directory ${DEPLOY_DIR}
2942+
2943+ COMMAND ${CMAKE_COMMAND} -E echo "[Deploy] Copying resources to destination dir: ${DEST_DIR} /Resources"
2944+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${RESOURCES_DIR} "${DEST_DIR} /Resources"
2945+
2946+ COMMAND ${CMAKE_COMMAND} -E echo "[Deploy] Copying firmware to destination dir: ${DEST_DIR} /PABotBase"
2947+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${FIRMWARE_DIR} "${DEST_DIR} /PABotBase"
2948+
2949+ COMMAND ${CMAKE_COMMAND} -E echo "[Deploy] Copying scripts to destination dir: ${DEST_DIR} /Scripts"
2950+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${SCRIPTS_DIR} "${DEST_DIR} /Scripts"
2951+ )
2952+
2953+ # Run windeployqt for the current config
2954+ if (WINDEPLOYQT_EXECUTABLE)
2955+ list (APPEND DEPLOY_CMDS
2956+ COMMAND ${CMAKE_COMMAND} -E echo "[Deploy] Running windeployqt"
2957+ COMMAND "${WINDEPLOYQT_EXECUTABLE} "
2958+ --dir "${DEPLOY_DIR} "
2959+ $<IF:$<CONFIG:Debug>,--debug,--release>
2960+ $<TARGET_FILE:SerialPrograms>
2961+ )
2962+ else ()
2963+ message (WARNING "windeployqt not found, skipping Qt deployment." )
2964+ endif ()
2965+
2966+ # Copy Discord SDK DLL (config-specific)
2967+ list (APPEND DEPLOY_CMDS
2968+ COMMAND ${CMAKE_COMMAND} -E echo "[Deploy] Copying Discord SDK DLL"
2969+ COMMAND ${CMAKE_COMMAND} -E copy
2970+ $<IF:$<CONFIG:Debug>,${REPO_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win/bin/debug/discord_partner_sdk.dll,${REPO_ROOT_DIR} /3rdPartyBinaries/discord_social_sdk_win/bin/release/discord_partner_sdk.dll>
2971+ ${DEPLOY_DIR} /discord_partner_sdk.dll
2972+ )
2973+
2974+ # Copy all 3rdPartyBinaries *.dll (computed at configure-time)
2975+ file (GLOB THIRD_PARTY_DLLS "${REPO_ROOT_DIR} /3rdPartyBinaries/*.dll" )
2976+ foreach (DLL IN LISTS THIRD_PARTY_DLLS)
2977+ message (STATUS "Adding deploy command for 3rd party DLL: ${DLL} " )
2978+ list (APPEND DEPLOY_CMDS COMMAND ${CMAKE_COMMAND} -E copy "${DLL} " "${DEPLOY_DIR} /" )
2979+ endforeach ()
2980+
2981+ # Copy the built exe and pdb (pdb guarded for existence)
2982+ list (APPEND DEPLOY_CMDS
2983+ COMMAND ${CMAKE_COMMAND} -E echo "[Deploy] Copying built exe and pdb"
2984+ COMMAND ${CMAKE_COMMAND} -E rename $<TARGET_FILE:SerialPrograms> "${DEPLOY_DIR} /$<TARGET_FILE_NAME:SerialPrograms>"
2985+ COMMAND ${CMAKE_COMMAND} -E rename $<TARGET_PDB_FILE:SerialPrograms> "${DEPLOY_DIR} /$<TARGET_PDB_FILE_NAME:SerialPrograms>"
2986+ )
2987+
2988+ add_custom_target (DeployRuntime ALL
2989+ DEPENDS SerialPrograms ExtractDependencies PackagesRepo
2990+ COMMENT "Deploying runtime (Qt, packages, DLLs) to ${DEPLOY_DIR} "
2991+ VERBATIM
2992+ ${DEPLOY_CMDS}
2993+ )
2994+
2995+ # Extract Discord SDK build-time, if it doesn't already exist
2996+ if (NOT EXISTS "${DISCORD_LIB_DEBUG} " OR NOT EXISTS "${DISCORD_LIB_RELEASE} " )
2997+ message (STATUS "Discord SDK not found, extracting from zip..." )
2998+ add_custom_command (
2999+ OUTPUT "${DISCORD_LIB_DEBUG} " "${DISCORD_LIB_RELEASE} "
3000+ COMMAND ${CMAKE_COMMAND} -E tar xf "${DISCORD_ZIP} "
3001+ WORKING_DIRECTORY "${REPO_ROOT_DIR} /3rdPartyBinaries"
3002+ DEPENDS "${DISCORD_ZIP} "
3003+ COMMENT "Extracting Discord SDK"
3004+ )
3005+ endif ()
3006+
3007+ # Extract OpenCV debug DLL build-time, if it doesn't already exist
3008+ if (NOT EXISTS "${OPENCV_DEBUG} " )
3009+ message (STATUS "OpenCV debug DLL not found, extracting from zip..." )
3010+ add_custom_command (
3011+ OUTPUT "${OPENCV_DEBUG} "
3012+ COMMAND ${CMAKE_COMMAND} -E tar xf "${OPENCV_DEBUG_ZIP} "
3013+ WORKING_DIRECTORY "${REPO_ROOT_DIR} /3rdPartyBinaries"
3014+ DEPENDS "${OPENCV_DEBUG_ZIP} "
3015+ COMMENT "Extracting OpenCV debug DLL"
3016+ )
3017+ endif ()
28193018endif ()
28203019
28213020if (QT_MAJOR GREATER_EQUAL 6)
0 commit comments