-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathCMakeLists.txt
More file actions
156 lines (122 loc) · 5.6 KB
/
CMakeLists.txt
File metadata and controls
156 lines (122 loc) · 5.6 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
cmake_minimum_required(VERSION 3.21)
project(
ExampleMod
VERSION 0.0.1
DESCRIPTION "An SKSE plugin for Skyrim SE/AE"
LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
option(PLUGIN_TESTS_ONLY "Build unit tests instead of the plugin" OFF)
if(PLUGIN_TESTS_ONLY)
find_package(Catch2 3 CONFIG REQUIRED)
include(CTest)
include(Catch)
add_executable(${PROJECT_NAME}Tests test/ExampleTests.cpp)
target_include_directories(${PROJECT_NAME}Tests PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src")
target_link_libraries(${PROJECT_NAME}Tests PRIVATE Catch2::Catch2WithMain)
catch_discover_tests(${PROJECT_NAME}Tests)
else()
# Auto-init submodules if inside a git repo (self-heals if user skipped init.sh)
find_package(Git QUIET)
if(GIT_FOUND AND EXISTS "${PROJECT_SOURCE_DIR}/.git")
execute_process(
COMMAND ${GIT_EXECUTABLE} submodule update --init --recursive
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
RESULT_VARIABLE _submod_result)
if(NOT _submod_result EQUAL 0)
message(FATAL_ERROR "git submodule update failed (exit code ${_submod_result})")
endif()
endif()
# Dependencies
find_package(spdlog CONFIG REQUIRED)
# directxtk must be found before add_commonlibsse_plugin (CommonLibSSE-NG links
# Microsoft::DirectXTK transitively).
find_package(directxtk CONFIG REQUIRED)
# rapidcsv must be in vcpkg.json (CommonLibSSE-NG unconditionally adds it as an include dir)
# CommonLibSSE-NG
set(ENABLE_SKYRIM_SE
ON
CACHE BOOL "" FORCE)
set(ENABLE_SKYRIM_AE
ON
CACHE BOOL "" FORCE)
set(ENABLE_SKYRIM_VR
OFF
CACHE BOOL "" FORCE)
set(BUILD_TESTS
OFF
CACHE BOOL "" FORCE)
set(SKSE_SUPPORT_XBYAK
OFF
CACHE BOOL "" FORCE)
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/lib/commonlibsse-ng" "${CMAKE_CURRENT_BINARY_DIR}/commonlibsse-ng"
EXCLUDE_FROM_ALL)
include("${CMAKE_CURRENT_SOURCE_DIR}/lib/commonlibsse-ng/cmake/CommonLibSSE.cmake")
file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/src")
configure_file("${CMAKE_CURRENT_SOURCE_DIR}/cmake/version.rc.in" "${CMAKE_CURRENT_BINARY_DIR}/src/version.rc" @ONLY)
# Plugin — auto-generates SKSEPlugin_Version; Plugin.cpp only needs SKSEPlugin_Load
add_commonlibsse_plugin(
${PROJECT_NAME}
NAME
"ExampleMod"
AUTHOR
"Author"
SOURCES
src/Plugin.cpp
"${CMAKE_CURRENT_BINARY_DIR}/src/version.rc"
USE_ADDRESS_LIBRARY)
source_group("Resources" FILES "${CMAKE_CURRENT_BINARY_DIR}/src/version.rc")
# cmake_llvm_rc preprocesses RC files using the target's INCLUDE_DIRECTORIES, not CMAKE_C_FLAGS.
# The xwin SDK paths are in CMAKE_C_FLAGS_INIT as /imsvc flags and are invisible to cmake_llvm_rc,
# so we add them explicitly here for the RC compiler to find winres.h.
if(DEFINED XWIN_DIR)
target_include_directories(
${PROJECT_NAME} SYSTEM PRIVATE "$<$<COMPILE_LANGUAGE:RC>:${XWIN_DIR}/sdk/include/um>"
"$<$<COMPILE_LANGUAGE:RC>:${XWIN_DIR}/sdk/include/shared>")
endif()
target_precompile_headers(${PROJECT_NAME} PRIVATE src/PCH.h)
target_include_directories(${PROJECT_NAME} PRIVATE "${CMAKE_CURRENT_SOURCE_DIR}/src"
"${CMAKE_CURRENT_BINARY_DIR}/src")
set_target_properties(
${PROJECT_NAME}
PROPERTIES OUTPUT_NAME ExampleMod
PREFIX ""
SUFFIX ".dll")
# Compiler/linker flags: /Zi emits PDB in all configs; Release gets full optimization + /DEBUG:FULL
if(MSVC)
target_compile_options(${PROJECT_NAME} PRIVATE /Zi "$<$<CONFIG:Release>:/Zc:inline;/JMC->")
target_link_options(${PROJECT_NAME} PRIVATE "$<$<CONFIG:Debug>:/INCREMENTAL;/OPT:NOREF;/OPT:NOICF>"
"$<$<CONFIG:Release>:/INCREMENTAL:NO;/OPT:REF;/OPT:ICF;/DEBUG:FULL>")
endif()
# LTO/IPO — guarded: unconditionally setting IPO causes a fatal error on toolchains that don't support it
include(CheckIPOSupported)
check_ipo_supported(RESULT _ipo_supported OUTPUT _ipo_output)
if(_ipo_supported)
set_target_properties(${PROJECT_NAME} PROPERTIES INTERPROCEDURAL_OPTIMIZATION_RELEASE TRUE)
else()
message(VERBOSE "IPO not supported: ${_ipo_output}")
endif()
# Deploy: copies DLL + PDB to SKYRIM_MODS_FOLDER, SKYRIM_FOLDER/Data, or build/deploy/ as fallback
if(DEFINED ENV{SKYRIM_MODS_FOLDER} AND IS_DIRECTORY "$ENV{SKYRIM_MODS_FOLDER}")
set(_default_deploy "$ENV{SKYRIM_MODS_FOLDER}/${PROJECT_NAME}")
elseif(DEFINED ENV{SKYRIM_FOLDER} AND IS_DIRECTORY "$ENV{SKYRIM_FOLDER}/Data")
set(_default_deploy "$ENV{SKYRIM_FOLDER}/Data")
else()
set(_default_deploy "${CMAKE_BINARY_DIR}/deploy/${PROJECT_NAME}")
endif()
set(DEPLOY_DIR
"${_default_deploy}"
CACHE PATH "Deploy destination (set SKYRIM_MODS_FOLDER or SKYRIM_FOLDER in .env)")
install(TARGETS ${PROJECT_NAME} RUNTIME DESTINATION "${DEPLOY_DIR}/SKSE/Plugins")
install(
FILES "$<TARGET_PDB_FILE:${PROJECT_NAME}>"
DESTINATION "${DEPLOY_DIR}/SKSE/Plugins"
OPTIONAL)
# `cmake --build --preset deploy` (or cmake --workflow --preset deploy)
add_custom_target(
deploy
COMMAND "${CMAKE_COMMAND}" --install "${CMAKE_BINARY_DIR}"
DEPENDS ${PROJECT_NAME}
COMMENT "Deploying to ${DEPLOY_DIR}/SKSE/Plugins")
endif() # PLUGIN_TESTS_ONLY