forked from macroquest/macroquest
-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
269 lines (232 loc) · 10.1 KB
/
CMakeLists.txt
File metadata and controls
269 lines (232 loc) · 10.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
# ============================================================================
# Dual-Purpose Build System
# ============================================================================
# This CMake configuration serves two purposes:
#
# 1. PROJECT FILE GENERATION
# - Generates platform-specific Visual Studio solutions
# - Solution: build/solution/MacroQuest.sln
# - Auto-detects architecture from BuildType.h
# - Regenerate with: .\gen_solution.ps1
# - Useful when upstream changes occur to the solution
#
# 2. COMPLETE BUILD CHAIN
# - Build directly via CMake without opening Visual Studio
# - Command: cmake --build build/solution --config Release
# - Ideal for CI/CD pipelines and automated builds
#
# CLEANING:
# To clean CMake files only: Remove-Item -Recurse build
# where build is the build directory.
#
# MANUAL GENERATION (if needed):
# cmake -B build/solution -G "Visual Studio 17 2022" -A x64
# ============================================================================
# TODO: Fix the loader cmake
cmake_minimum_required(VERSION 3.30)
# ============================================================================
# Requirements checks
# ============================================================================
# Only Visual Studio generators make sense for MQ due to architecture restrictions
if(NOT CMAKE_GENERATOR MATCHES "Visual Studio")
message(FATAL_ERROR "Only Visual Studio generators are viable for MacroQuest compilation")
endif()
# Validate architecture is specified for Visual Studio generator
# vcpkg triplet setup MUST be before project() call, do it here because it's convenient
# Determine architecture from CMAKE_GENERATOR_PLATFORM (set by -A flag)
if(CMAKE_GENERATOR_PLATFORM STREQUAL "x64")
set(VCPKG_TARGET_TRIPLET "x64-windows-static" CACHE STRING "")
set(VCPKG_ARCH "x64" CACHE STRING "")
elseif(CMAKE_GENERATOR_PLATFORM STREQUAL "Win32")
set(VCPKG_TARGET_TRIPLET "x86-windows-static" CACHE STRING "")
set(VCPKG_ARCH "x86" CACHE STRING "")
elseif(NOT CMAKE_GENERATOR_PLATFORM)
message(FATAL_ERROR
"Architecture must be specified with -A flag:\n"
" Win32: cmake -B build_win32 -G \"Visual Studio 17 2022\" -A Win32\n"
" x64: cmake -B build_x64 -G \"Visual Studio 17 2022\" -A x64\n"
)
else()
message(FATAL_ERROR
"Only Win32 and x64 platforms are supported. Got: ${CMAKE_GENERATOR_PLATFORM}"
)
endif()
set(VCPKG_INSTALL_OPTIONS "--allow-unsupported")
message(STATUS "Configuring for platform: ${CMAKE_GENERATOR_PLATFORM}")
# ============================================================================
# Options
# ============================================================================
option(MQ_REGENERATE_SOLUTION "Just generate a macroquest solution file from vcxproj files" OFF)
option(MQ_BUILD_PLUGINS "Build built-in plugins" ON)
option(MQ_BUILD_CUSTOM_PLUGINS "Build custom plugins from plugins directory" OFF)
option(MQ_BUILD_LAUNCHER "Build MacroQuest loader" OFF)
option(MQ_STATIC_BUILD "Change build type for core libraries to static" OFF)
option(MQ_BUILD_TESTS "Build tests" OFF)
option(MQ_ADD_MQ2MAIN_DEPENDENCY "Add MQ2Main as dependency to custom plugins if not present" OFF)
option(MQ_FORCE_VCXPROJ_CONVERSION "Force reconversion of vcxproj files even if CMakeLists.txt exists" OFF)
option(MQ_FORCE_OVERLAY_REBUILD "Force rebuild of vcpkg.json files in projects that have legacy vcpkg manifests" OFF)
# Custom plugin configuration options
set(MQ_CUSTOM_PLUGINS_FILE "" CACHE FILEPATH "Path to a CMake file that adds custom plugins (overrides auto-detection)")
set(MQ_WRITE_PLUGINS_FILE "" CACHE FILEPATH "Write auto-detected plugins as a CMake file (generated from scan)")
# Set the output directories
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
# Suppress developer warnings (occurs in some vcpkg configs)
if(NOT DEFINED CMAKE_SUPPRESS_DEVELOPER_WARNINGS)
set(CMAKE_SUPPRESS_DEVELOPER_WARNINGS 1 CACHE INTERNAL "No dev warnings")
endif()
# Solution-wide shared config
include(cmake/common.cmake)
include(cmake/plugins.cmake)
# ============================================================================
# Define all subdirectories to include in the build
# This list is used for both vcpkg overlay generation and add_subdirectory calls
# ============================================================================
set(MQ_CORE_SUBDIRS
"src/eqlib"
"src/imgui"
"src/routing"
"src/login"
"src/main"
"contrib/zep"
)
set(MQ_LAUNCHER_SUBDIRS
"src/loader"
)
set(MQ_PLUGIN_SUBDIRS
"src/plugins/pluginapi"
"src/plugins/autobank"
"src/plugins/autologin"
"src/plugins/bzsrch"
"src/plugins/chat"
"src/plugins/chatwnd"
"src/plugins/custombinds"
"src/plugins/eqbugfix"
"src/plugins/hud"
"src/plugins/itemdisplay"
"src/plugins/labels"
"src/plugins/lua"
"src/plugins/map"
"src/plugins/targetinfo"
"src/plugins/xtarinfo"
)
set(MQ_TEST_SUBDIRS
"src/tests/Actors"
"src/tests/NamedPipeClient"
)
set(MQ_ALL_SUBDIRS ${MQ_CORE_SUBDIRS})
if (MQ_BUILD_LAUNCHER)
list(APPEND MQ_ALL_SUBDIRS ${MQ_LAUNCHER_SUBDIRS})
endif()
if (MQ_BUILD_PLUGINS)
list(APPEND MQ_ALL_SUBDIRS ${MQ_PLUGIN_SUBDIRS})
endif()
if (MQ_BUILD_TESTS)
list(APPEND MQ_ALL_SUBDIRS ${MQ_TEST_SUBDIRS})
endif()
if (MQ_BUILD_CUSTOM_PLUGINS)
if(MQ_CUSTOM_PLUGINS_FILE)
get_filename_component(MQ_CUSTOM_PLUGINS_FILE ${MQ_CUSTOM_PLUGINS_FILE} ABSOLUTE)
endif()
detect_custom_plugins(MQ_CUSTOM_PLUGIN_SUBDIRS ${MQ_CUSTOM_PLUGINS_FILE})
# Add custom plugin subdirs to the main list, after converting if needed
if(MQ_CUSTOM_PLUGIN_SUBDIRS)
build_custom_plugin_directories(MQ_CUSTOM_PLUGIN_SUBDIRS "${MQ_CUSTOM_PLUGIN_SUBDIRS}" ${MQ_FORCE_VCXPROJ_CONVERSION})
list(APPEND MQ_ALL_SUBDIRS ${MQ_CUSTOM_PLUGIN_SUBDIRS})
# Write the list if configured to do so
if(MQ_WRITE_PLUGINS_FILE)
write_custom_plugins_file("${CMAKE_SOURCE_DIR}/${MQ_WRITE_PLUGINS_FILE}" "add_subdirectory" "${MQ_CUSTOM_PLUGIN_SUBDIRS}")
endif()
endif()
endif()
# ============================================================================
# vcpkg Integration (MUST be set before project() call)
# ============================================================================
if(NOT DEFINED CMAKE_TOOLCHAIN_FILE)
set(CMAKE_TOOLCHAIN_FILE "$ENV{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake" CACHE STRING "")
endif()
# Extract port names from subdirectories
# For plugins, extract the direct descendant of plugins/ (e.g., "src/plugins/lua" -> "lua")
# For others, extract the leaf directory (e.g., "src/eqlib" -> "eqlib")
set(MQ_VCPKG_PORTS "")
foreach(SUBDIR ${MQ_ALL_SUBDIRS})
if(SUBDIR MATCHES "^plugins/([^/]+)")
# For plugins, use the direct descendant of plugins/
list(APPEND MQ_VCPKG_PORTS "${CMAKE_MATCH_1}")
else()
# For others, use the leaf directory
get_filename_component(PORT_NAME "${SUBDIR}" NAME)
list(APPEND MQ_VCPKG_PORTS "${PORT_NAME}")
endif()
endforeach()
# Remove any duplicates
list(REMOVE_DUPLICATES MQ_VCPKG_PORTS)
if(NOT MQ_REGENERATE_SOLUTION)
# if we are just regenerating the solution, don't build the manifests
message(STATUS "Generating VCPKG manifest (FORCE OVERLAY REBUILD: ${MQ_FORCE_OVERLAY_REBUILD})")
include(cmake/vcpkg_manifest.cmake)
if(MQ_FORCE_OVERLAY_REBUILD)
set(FORCE_REBUILD FORCE_REBUILD)
else()
set(FORCE_REBUILD "")
endif()
create_vcpkg_overlays(
PORTS ${MQ_VCPKG_PORTS}
OUTPUT_DIR ${CMAKE_BINARY_DIR}
${FORCE_REBUILD}
)
endif()
# ============================================================================
# Global settings
# ============================================================================
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CONFIGURATION_TYPES "Debug;Release" CACHE STRING "Available build configurations" FORCE)
# Toolset selection
if(NOT CMAKE_GENERATOR_TOOLSET)
set(CMAKE_GENERATOR_TOOLSET "v143" CACHE STRING "Choose MSVC toolset." FORCE)
endif()
# Disable CMake's automatic MSVC runtime library handling
# Runtime library flags (/MT, /MTd) are set manually in Common.cmake
set(CMAKE_MSVC_RUNTIME_LIBRARY "" CACHE STRING "" FORCE)
# ============================================================================
# Begin project definition
# ============================================================================
# TODO: move semver here? They are technically already handled in the resource files, maybe they can be tied together
project(MacroQuest
VERSION 3.0.0
LANGUAGES CXX
)
# Universal packages and compile flags
find_package(detours REQUIRED)
find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)
string(REPLACE "/D_WINDOWS" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
string(REPLACE "/DNDEBUG" "" CMAKE_CXX_FLAGS_RELEASE ${CMAKE_CXX_FLAGS_RELEASE})
string(REPLACE "/DWIN32" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
if(MQ_REGENERATE_SOLUTION)
# just generate the solution, do nothing else
message(STATUS "Regenerating macroquest solution file")
include(cmake/vcxproj_sln.cmake)
else()
list(REMOVE_DUPLICATES MQ_ALL_SUBDIRS)
foreach(SUBDIR ${MQ_ALL_SUBDIRS})
add_subdirectory(${SUBDIR})
endforeach()
endif()
# Print configuration summary
message(STATUS "")
message(STATUS "MacroQuest Configuration Summary:")
message(STATUS " Build Types: ${CMAKE_CONFIGURATION_TYPES}")
message(STATUS " MSVC Toolchain: ${CMAKE_GENERATOR_TOOLSET}")
message(STATUS " C++ Standard: ${CMAKE_CXX_STANDARD}")
message(STATUS " Only Regenerate Solution: ${MQ_REGENERATE_SOLUTION}")
message(STATUS " Build Plugins: ${MQ_BUILD_PLUGINS}")
message(STATUS " Build Custom Plugins: ${MQ_BUILD_CUSTOM_PLUGINS}")
message(STATUS " Build Loader: ${MQ_BUILD_LAUNCHER}")
message(STATUS " Build Tests: ${MQ_BUILD_TESTS}")
message(STATUS " Force VCXProj Conversion: ${MQ_FORCE_VCXPROJ_CONVERSION}")
message(STATUS "")