Skip to content

Commit 419fd7f

Browse files
authored
Merge pull request #681 from Koi-3088/main
[Windows] Ready-to-run local build
2 parents 809b90b + 7701052 commit 419fd7f

File tree

2 files changed

+351
-48
lines changed

2 files changed

+351
-48
lines changed

SerialPrograms/CMakeLists.txt

Lines changed: 247 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,153 @@
1-
#set the minimum cmake version required
1+
# Set the minimum cmake version required
22
cmake_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
519
project(SerialPrograms)
620

7-
#enable c++ 23
21+
# Enable C++23
822
set(CMAKE_CXX_STANDARD 23)
923
set(CMAKE_CXX_STANDARD_REQUIRED ON)
1024

11-
#produce clang tidy file
25+
# Produce clang tidy file
1226
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
1327
#set(CMAKE_VERBOSE_MAKEFILE ON)
1428

1529
set(CMAKE_AUTOMOC ON)
1630
set(CMAKE_AUTORCC ON)
1731
set(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-
2333
add_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
3793
set(THREADS_PREFER_PTHREAD_FLAG ON)
3894
find_package(Threads REQUIRED)
3995

40-
#find Qt
96+
# Define the major version of Qt to search for
4197
if(NOT QT_MAJOR)
4298
set(QT_MAJOR 6)
4399
endif()
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
46152
add_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})
24632590
endif()
24642591

@@ -2477,19 +2604,6 @@ if (EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../../Internal/SerialPrograms/Internal0.
24772604
target_sources(SerialPrograms PRIVATE ../../Internal/SerialPrograms/Internal1.cpp)
24782605
endif()
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
24942608
target_include_directories(SerialPrograms SYSTEM PRIVATE ../3rdParty/)
24952609
target_include_directories(SerialPrograms PRIVATE ../ ../../Internal/ Source/)
@@ -2796,26 +2910,111 @@ SET_SOURCE_FILES_PROPERTIES(
27962910
)
27972911
endif()
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()
28193018
endif()
28203019

28213020
if (QT_MAJOR GREATER_EQUAL 6)

0 commit comments

Comments
 (0)