forked from skyrim-multiplayer/skymp
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
291 lines (250 loc) · 10.4 KB
/
Copy pathCMakeLists.txt
File metadata and controls
291 lines (250 loc) · 10.4 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
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
# At the moment of writing this gives ~10% speedup of cmake command on Windows
# https://gitlab.kitware.com/cmake/cmake/-/issues/23154
if(POLICY 0115)
cmake_policy(SET CMP0115 NEW)
endif()
if("${VCPKG_TARGET_TRIPLET}" STREQUAL "")
if(WIN32)
set(VCPKG_TARGET_TRIPLET "x64-windows-sp")
elseif(APPLE)
set(VCPKG_TARGET_TRIPLET "x64-osx")
else()
set(VCPKG_TARGET_TRIPLET "x64-linux")
endif()
endif()
set(VCPKG_OVERLAY_TRIPLETS "${CMAKE_CURRENT_LIST_DIR}/overlay_triplets")
set(VCPKG_OVERLAY_PORTS "${CMAKE_CURRENT_LIST_DIR}/overlay_ports")
option(NO_CLEAN_AFTER_BUILD "Don't clean vcpkg temporary folders after build" OFF)
if("$ENV{CI}" STREQUAL "true" OR NO_CLEAN_AFTER_BUILD)
set(VCPKG_INSTALL_OPTIONS --no-print-usage)
else()
set(VCPKG_INSTALL_OPTIONS --no-print-usage --clean-after-build)
endif()
if("$ENV{CI}" STREQUAL "true" AND WIN32)
# The same submodule but moved to a larger disk in Windows CI. See action files:
# - https://github.com/skyrim-multiplayer/skymp/blob/main/.github/workflows/pr-windows.yml
# - https://github.com/skyrim-multiplayer/skymp/blob/main/.github/workflows/pr-windows-ae.yml
set(CMAKE_TOOLCHAIN_FILE "C:/vcpkg/scripts/buildsystems/vcpkg.cmake")
else()
set(CMAKE_TOOLCHAIN_FILE "${CMAKE_SOURCE_DIR}/vcpkg/scripts/buildsystems/vcpkg.cmake")
endif()
# File from vcpkg submodule. This indicates inability to find this file or checkout submodules.
if(NOT EXISTS "${CMAKE_TOOLCHAIN_FILE}")
set(msg "${CMAKE_TOOLCHAIN_FILE} doesn't exist. It seems that vcpkg submodule is not initialized.")
set(msg "${msg}\nUse commands below to initialize:")
set(msg "${msg}\n git submodule init")
set(msg "${msg}\n git submodule update")
message(FATAL_ERROR "${msg}")
endif()
if(NOT "${CMAKE_BINARY_DIR}" STREQUAL "${CMAKE_SOURCE_DIR}/build")
set(msg "CMake binary directory ${CMAKE_BINARY_DIR} must be <repo_root>/build (${CMAKE_SOURCE_DIR}/build)")
set(msg "${msg}\nUse commands below after cloning the repo (replace path with your actual Skyrim SE folder):")
set(msg "${msg}\n mkdir build")
set(msg "${msg}\n cd build")
set(msg "${msg}\nFor users who have Skyrim SE installed:")
set(msg "${msg}\n cmake .. -DSKYRIM_DIR=\"C:/Program Files (x86)/Steam/steamapps/common/Skyrim Special Edition\"")
set(msg "${msg}\nFor users who don't have Skyrim SE installed:")
set(msg "${msg}\n cmake ..")
message(FATAL_ERROR "${msg}")
endif()
# Bool options (Part 1)
option(SKYRIM_VR "Skyrim VR (1.4) build" OFF)
option(BUILD_NODEJS "Build NodeJS port if ON, use a pre-built otherwise" OFF)
if(SKYRIM_VR)
list(APPEND VCPKG_MANIFEST_FEATURES "skyrim-vr")
else()
list(APPEND VCPKG_MANIFEST_FEATURES "skyrim-flatrim")
endif()
if(BUILD_NODEJS)
list(APPEND VCPKG_MANIFEST_FEATURES "build-nodejs")
else()
list(APPEND VCPKG_MANIFEST_FEATURES "prebuilt-nodejs")
endif()
cmake_minimum_required(VERSION 3.19)
project(skymp)
enable_testing()
# Check the Visual Studio version
if(MSVC)
if(NOT CMAKE_GENERATOR MATCHES "Visual Studio 17 2022")
message(FATAL_ERROR "This project requires \"Visual Studio 17 2022\". But the generator was \"${CMAKE_GENERATOR}\"")
endif()
endif()
# Bool options (Part 2)
option(PREPARE_NEXUS_ARCHIVES "Prepare SP and other archives during build or not" OFF)
option(BUILD_UNIT_TESTS "Build unit tests (excluded from build when off - workaround for #1182)" ON)
option(INSTALL_CLIENT_DIST "Install the client into SKYRIM_DIR after build" OFF)
option(BUILD_GAMEMODE "Build gamemode" OFF)
option(BUILD_CLIENT "Build client" ON)
option(BUILD_FRONT "Build front" OFF)
option(BUILD_SKYRIM_PLATFORM "Build Skyrim Platform" ON)
option(BUILD_SCRIPTS "Build skymp5-scripts and Papyrus scripts in skyrim-platform" ON)
option(OFFLINE_MODE "Enable offline mode in generated server settings and client settings" ON)
message(STATUS PREPARE_NEXUS_ARCHIVES=${PREPARE_NEXUS_ARCHIVES})
message(STATUS SKYRIM_VR=${SKYRIM_VR})
message(STATUS BUILD_UNIT_TESTS=${BUILD_UNIT_TESTS})
message(STATUS INSTALL_CLIENT_DIST=${INSTALL_CLIENT_DIST})
message(STATUS BUILD_GAMEMODE=${BUILD_GAMEMODE})
message(STATUS BUILD_CLIENT=${BUILD_CLIENT})
message(STATUS BUILD_SCRIPTS=${BUILD_SCRIPTS})
message(STATUS BUILD_FRONT=${BUILD_FRONT})
message(STATUS BUILD_SKYRIM_PLATFORM=${BUILD_SKYRIM_PLATFORM})
message(STATUS OFFLINE_MODE=${OFFLINE_MODE})
message(STATUS BUILD_NODEJS=${BUILD_NODEJS})
if(PREPARE_NEXUS_ARCHIVES AND EMSCRIPTEN)
message(FATAL_ERROR "PREPARE_NEXUS_ARCHIVES is not supported on Emscripten")
endif()
# Path options
option(UNIT_DATA_DIR "Path to directory with Skyrim.esm and other data files required for testing. CMAKE_SOURCE_DIR would be used to resolve a relative path if passed." OFF)
option(DOWNLOAD_SKYRIM_DATA "Download Skyrim.esm and other data files required for testing" OFF)
option(SKYRIM_DIR "Path to Skyrim, would be used for tests if UNIT_DATA_DIR is not specified" OFF)
option(CPPCOV_PATH "Path to OpenCppCoverage" OFF)
if(DOWNLOAD_SKYRIM_DATA AND NOT UNIT_DATA_DIR)
set(UNIT_DATA_DIR "skyrim_data_files")
endif()
if(UNIT_DATA_DIR AND NOT IS_ABSOLUTE "${UNIT_DATA_DIR}")
get_filename_component(UNIT_DATA_DIR "${UNIT_DATA_DIR}" ABSOLUTE BASE_DIR ${CMAKE_SOURCE_DIR})
endif()
if(DOWNLOAD_SKYRIM_DATA)
include(${CMAKE_SOURCE_DIR}/cmake/download_skyrim_data.cmake)
download_skyrim_data("${UNIT_DATA_DIR}")
endif()
if(NOT SKYRIM_DIR)
message(STATUS "SKYRIM_DIR is not specified. You will have to fill server config with esm paths manually")
endif()
string(REPLACE "\\" "/" SKYRIM_DIR "${SKYRIM_DIR}")
if(SKYRIM_DIR)
if (NOT EXISTS ${SKYRIM_DIR}/SkyrimSE.exe)
message(FATAL_ERROR "Bad SKYRIM_DIR: ${SKYRIM_DIR}")
endif()
endif()
if(NOT CPPCOV_PATH)
message(STATUS "CPPCOV_PATH is not specified, coverage will not be calculated")
endif()
string(REPLACE "\\" "/" CPPCOV_PATH "${CPPCOV_PATH}")
if(CPPCOV_PATH)
if (NOT EXISTS ${CPPCOV_PATH}/OpenCppCoverage.exe)
message(FATAL_ERROR "Bad CPPCOV_PATH: ${CPPCOV_PATH}")
endif()
endif()
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/modules)
# Initialize the CMAKEPROJ projects and their configurations
list(APPEND CMAKEPROJ_PROJECTS_LIST) # List of all projects
set(CMAKEPROJ_PROJECTS_DEPENDENCIES) # Dependencies for each project
set(CMAKEPROJ_PROJECTS_PRIORITY) # Priority for each project
# Glob directories under source directory root
file(GLOB ROOT_DIRS RELATIVE ${CMAKE_SOURCE_DIR} ${CMAKE_SOURCE_DIR}/*)
foreach(dir ${ROOT_DIRS})
if(IS_DIRECTORY ${CMAKE_SOURCE_DIR}/${dir})
# Check if directory has a cmakeproj.cmake file
if(EXISTS ${CMAKE_SOURCE_DIR}/${dir}/cmakeproj.cmake)
include(${CMAKE_SOURCE_DIR}/${dir}/cmakeproj.cmake)
# Add project to the list if not already added
if(NOT "${CMAKEPROJ_PROJECTS_LIST}" MATCHES "${dir}")
list(APPEND CMAKEPROJ_PROJECTS_LIST ${dir})
endif()
# Set default priority if not set
if (NOT DEFINED CMAKEPROJ_PRIORITY_${dir})
set(CMAKEPROJ_PRIORITY_${dir} 0) # Default priority 0 if not defined
endif()
# Store dependencies and priorities for sorting
set(CMAKEPROJ_PROJECTS_DEPENDENCIES ${CMAKEPROJ_PROJECTS_DEPENDENCIES} "${CMAKEPROJ_DEPS_${dir}}")
set(CMAKEPROJ_PROJECTS_PRIORITY ${CMAKEPROJ_PROJECTS_PRIORITY} ${CMAKEPROJ_PRIORITY_${dir}})
endif()
endif()
endforeach()
foreach(proj ${CMAKEPROJ_PROJECTS_LIST})
list(APPEND priorities_list ${CMAKEPROJ_PRIORITY_${proj}})
endforeach()
list(REMOVE_DUPLICATES priorities_list)
list(SORT priorities_list COMPARE NATURAL)
foreach(priority ${priorities_list})
foreach(proj ${CMAKEPROJ_PROJECTS_LIST})
if(${CMAKEPROJ_PRIORITY_${proj}} STREQUAL ${priority})
list(APPEND sorted_projects ${proj})
endif()
endforeach()
endforeach()
foreach(project ${sorted_projects})
message(STATUS "Adding project: ${project} with priority ${CMAKEPROJ_PRIORITY_${project}}")
add_subdirectory(${project})
endforeach()
if(PREPARE_NEXUS_ARCHIVES)
add_custom_target(
prepare_nexus_archives ALL
COMMAND ${CMAKE_COMMAND} -P ${CMAKE_SOURCE_DIR}/cmake/prepare_nexus_archives.cmake
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
add_dependencies(prepare_nexus_archives skyrim-platform papyrus-vm)
set(TARGETS_ADDITIONAL
skymp5-client
skymp5-front
skymp5-functions-lib
skymp5-scripts
skymp5-server
)
foreach(target ${TARGETS_ADDITIONAL})
if(TARGET ${target})
add_dependencies(prepare_nexus_archives ${target})
endif()
endforeach()
endif()
# One or more of these targets help dev_service not to crash during build (watch mode). Not sure which target exactly.
set(TARGETS_ADDITIONAL
skymp5-client
skymp5-front
skymp5-functions-lib
skymp5-scripts
skymp5-server
)
foreach(target ${TARGETS_ADDITIONAL})
if(TARGET ${target} AND TARGET RestartGame)
add_dependencies(RestartGame ${target})
endif()
endforeach()
if(INSTALL_CLIENT_DIST)
add_custom_target(
install_client_dist ALL
COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_BINARY_DIR}/dist/client ${SKYRIM_DIR}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
add_dependencies(install_client_dist skymp5-client skyrim-platform)
endif()
# Integration tests from misc/tests
file(GLOB INTEGRATION_TESTS "${CMAKE_SOURCE_DIR}/misc/tests/test_*.js")
foreach(TEST_SCRIPT ${INTEGRATION_TESTS})
get_filename_component(TEST_NAME "${TEST_SCRIPT}" NAME_WE)
# Check for satellite DB folder (same name as test file without .js)
set(TEST_DB_DIR "${CMAKE_SOURCE_DIR}/misc/tests/${TEST_NAME}")
if(NOT IS_DIRECTORY "${TEST_DB_DIR}")
unset(TEST_DB_DIR)
endif()
# Check for test-specific server settings patch (same name as test file with .settings.json)
set(TEST_SETTINGS_JSON "${CMAKE_SOURCE_DIR}/misc/tests/${TEST_NAME}.settings.json")
if(NOT EXISTS "${TEST_SETTINGS_JSON}")
unset(TEST_SETTINGS_JSON)
endif()
set(ADD_TEST_ARGS
-DTEST_SCRIPT=${TEST_SCRIPT}
-DSERVER_DIR=${CMAKE_BINARY_DIR}/dist/server
-DSERVER_SETTINGS_BASE_JSON=${CMAKE_BINARY_DIR}/server-settings-base.json
)
if(TEST_DB_DIR)
list(APPEND ADD_TEST_ARGS -DTEST_DB_DIR=${TEST_DB_DIR})
endif()
if(TEST_SETTINGS_JSON)
list(APPEND ADD_TEST_ARGS -DTEST_SETTINGS_JSON=${TEST_SETTINGS_JSON})
endif()
add_test(
NAME integration_${TEST_NAME}
COMMAND ${CMAKE_COMMAND} ${ADD_TEST_ARGS}
-P ${CMAKE_SOURCE_DIR}/cmake/run_integration_test.cmake
)
set_tests_properties(integration_${TEST_NAME} PROPERTIES
TIMEOUT 120
RESOURCE_LOCK server_directory
FIXTURES_REQUIRED unit_passed
)
endforeach()