Skip to content

Commit 450994a

Browse files
author
Vano
committed
CMake rewrite, reflecting default SCons variables
1 parent 3f44e9b commit 450994a

File tree

9 files changed

+652
-180
lines changed

9 files changed

+652
-180
lines changed

CMakeLists.txt

Lines changed: 60 additions & 153 deletions
Original file line numberDiff line numberDiff line change
@@ -1,140 +1,79 @@
11
# cmake arguments
2-
# CMAKE_BUILD_TYPE: Compilation target (Debug or Release defaults to Debug)
3-
#
4-
# godot-cpp cmake arguments
5-
# GODOT_GDEXTENSION_DIR: Path to the directory containing GDExtension interface header and API JSON file
6-
# GODOT_CPP_SYSTEM_HEADERS Mark the header files as SYSTEM. This may be useful to supress warnings in projects including this one.
7-
# GODOT_CPP_WARNING_AS_ERROR Treat any warnings as errors
8-
# GODOT_CUSTOM_API_FILE: Path to a custom GDExtension API JSON file (takes precedence over `gdextension_dir`)
9-
# FLOAT_PRECISION: Floating-point precision level ("single", "double")
10-
#
11-
# Android cmake arguments
12-
# CMAKE_TOOLCHAIN_FILE: The path to the android cmake toolchain ($ANDROID_NDK/build/cmake/android.toolchain.cmake)
13-
# ANDROID_NDK: The path to the android ndk root folder
14-
# ANDROID_TOOLCHAIN_NAME: The android toolchain (arm-linux-androideabi-4.9 or aarch64-linux-android-4.9 or x86-4.9 or x86_64-4.9)
15-
# ANDROID_PLATFORM: The android platform version (android-23)
16-
# More info here: https://godot.readthedocs.io/en/latest/development/compiling/compiling_for_android.html
2+
# CMAKE_BUILD_TYPE: Compilation target (editor, template_debug, template_release)
3+
#
4+
# PLATFORM: Platform type (LINUX, MACOS, WINDOWS, ANDROID, IOS, WEB)
5+
# Auto-detected by default depending on current OS or chosen toolchain
6+
#
7+
# other global and chosen platform-specific options:
8+
#
9+
# cmake -LH
10+
#
11+
# Note: use -Bbuild_dir option to build in separate directories
12+
# for different configurations
13+
#
14+
# cmake -Bbuild && cmake --build build
1715
#
1816
# Examples
1917
#
20-
# Builds a debug version:
18+
# Builds default configuration:
2119
# cmake .
2220
# cmake --build .
2321
#
24-
# Builds a release version with clang
25-
# CC=/usr/bin/clang CXX=/usr/bin/clang++ cmake -DCMAKE_BUILD_TYPE=Release -G "Unix Makefiles" .
22+
# Builds template_release version
23+
#
24+
# cmake -DCMAKE_BUILD_TYPE=template_release .
2625
# cmake --build .
2726
#
27+
# Creates multi-config setup and builds 2 library versions (example for Linux)
28+
#
29+
# cmake -G "Ninja Multi-Config" .
30+
# cmake --build . --config editor
31+
# cmake --build . --config template_release
32+
#
33+
# Builds web version, using Emscripten toolchain
34+
#
35+
# cmake --toolchain /usr/lib/emscripten/cmake/Modules/Platform/Emscripten.cmake .
36+
# cmake --build .
37+
#
38+
#
2839
# Builds an android armeabi-v7a debug version:
29-
# cmake -DCMAKE_TOOLCHAIN_FILE=$ANDROID_NDK/build/cmake/android.toolchain.cmake -DANDROID_NDK=$ANDROID_NDK \
30-
# -DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 -DANDROID_PLATFORM=android-23 -DCMAKE_BUILD_TYPE=Debug .
40+
# cmake --toolchain $ANDROID_NDK/build/cmake/android.toolchain.cmake \
41+
# -DANDROID_TOOLCHAIN_NAME=arm-linux-androideabi-4.9 -DANDROID_TOOLCHAIN=clang -DANDROID_PLATFORM=21 .
3142
# cmake --build .
3243
#
33-
# Protip
34-
# Generate the buildfiles in a sub directory to not clutter the root directory with build files:
35-
# mkdir build && cd build && cmake -G "Unix Makefiles" .. && cmake --build .
3644
#
3745
# Todo
3846
# Test build for Windows, Mac and mingw.
3947

40-
cmake_minimum_required(VERSION 3.12)
48+
cmake_minimum_required(VERSION 3.24)
4149
project(godot-cpp LANGUAGES CXX)
4250

43-
option(GENERATE_TEMPLATE_GET_NODE "Generate a template version of the Node class's get_node." ON)
44-
option(GODOT_CPP_SYSTEM_HEADERS "Expose headers as SYSTEM." ON)
45-
option(GODOT_CPP_WARNING_AS_ERROR "Treat warnings as errors" OFF)
46-
47-
# Add path to modules
48-
list( APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/" )
51+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/")
4952

50-
# Set some helper variables for readability
51-
set( compiler_is_clang "$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>" )
52-
set( compiler_is_gnu "$<CXX_COMPILER_ID:GNU>" )
53-
set( compiler_is_msvc "$<CXX_COMPILER_ID:MSVC>" )
54-
55-
# Default build type is Debug in the SConstruct
56-
if("${CMAKE_BUILD_TYPE}" STREQUAL "")
57-
set(CMAKE_BUILD_TYPE Debug)
58-
endif()
59-
60-
if(NOT DEFINED BITS)
61-
set(BITS 32)
62-
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
63-
set(BITS 64)
64-
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
65-
endif()
66-
67-
# Input from user for GDExtension interface header and the API JSON file
68-
set(GODOT_GDEXTENSION_DIR "gdextension" CACHE STRING "")
69-
set(GODOT_CUSTOM_API_FILE "" CACHE STRING "")
70-
71-
set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json")
72-
if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override.
73-
set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}")
74-
endif()
75-
76-
set(FLOAT_PRECISION "single" CACHE STRING "")
77-
if ("${FLOAT_PRECISION}" STREQUAL "double")
78-
add_definitions(-DREAL_T_IS_DOUBLE)
79-
endif()
80-
81-
set(GODOT_COMPILE_FLAGS )
82-
83-
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
84-
# using Visual Studio C++
85-
set(GODOT_COMPILE_FLAGS "/utf-8") # /GF /MP
86-
87-
if(CMAKE_BUILD_TYPE MATCHES Debug)
88-
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MDd") # /Od /RTC1 /Zi
89-
else()
90-
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /MD /O2") # /Oy /GL /Gy
91-
STRING(REGEX REPLACE "/RTC(su|[1su])" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
92-
string(REPLACE "/RTC1" "" CMAKE_CXX_FLAGS_DEBUG ${CMAKE_CXX_FLAGS_DEBUG})
93-
endif(CMAKE_BUILD_TYPE MATCHES Debug)
94-
95-
add_definitions(-DNOMINMAX)
96-
else() # GCC/Clang
97-
if(CMAKE_BUILD_TYPE MATCHES Debug)
98-
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-omit-frame-pointer -O0 -g")
99-
else()
100-
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -O3")
101-
endif(CMAKE_BUILD_TYPE MATCHES Debug)
102-
endif()
103-
104-
# Disable exception handling. Godot doesn't use exceptions anywhere, and this
105-
# saves around 20% of binary size and very significant build time (GH-80513).
106-
option(GODOT_DISABLE_EXCEPTIONS ON "Force disabling exception handling code")
107-
if (GODOT_DISABLE_EXCEPTIONS)
108-
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
109-
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -D_HAS_EXCEPTIONS=0")
110-
else()
111-
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} -fno-exceptions")
112-
endif()
113-
else()
114-
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
115-
set(GODOT_COMPILE_FLAGS "${GODOT_COMPILE_FLAGS} /EHsc")
116-
endif()
117-
endif()
53+
# Handles all global and platform-specific variables
54+
include(godotcpp)
11855

11956
# Generate source from the bindings file
12057
find_package(Python3 3.4 REQUIRED) # pathlib should be present
121-
if(GENERATE_TEMPLATE_GET_NODE)
122-
set(GENERATE_BINDING_PARAMETERS "True")
123-
else()
124-
set(GENERATE_BINDING_PARAMETERS "False")
125-
endif()
12658

127-
execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.print_file_list(\"${GODOT_GDEXTENSION_API_FILE}\", \"${CMAKE_CURRENT_BINARY_DIR}\", headers=True, sources=True)"
59+
execute_process(COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.print_file_list(\"${GDEXTENSION_API_FILE}\", \"${CMAKE_CURRENT_BINARY_DIR}\", headers=True, sources=True)"
12860
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
12961
OUTPUT_VARIABLE GENERATED_FILES_LIST
13062
OUTPUT_STRIP_TRAILING_WHITESPACE
13163
)
13264

65+
string(TOLOWER ${FLOAT_PRECISION} FLOAT_PRECISION_ARG)
66+
if(GENERATE_TEMPLATE_GET_NODE)
67+
set(GENERATE_BINDING_PARAMETERS "True")
68+
else()
69+
set(GENERATE_BINDING_PARAMETERS "False")
70+
endif()
71+
13372
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
134-
COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GODOT_GDEXTENSION_API_FILE}\", \"${GENERATE_BINDING_PARAMETERS}\", \"${BITS}\", \"${FLOAT_PRECISION}\", \"${CMAKE_CURRENT_BINARY_DIR}\")"
73+
COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.generate_bindings(\"${GDEXTENSION_API_FILE}\", \"${GENERATE_BINDING_PARAMETERS}\", \"${BITS}\", \"${FLOAT_PRECISION_ARG}\", \"${CMAKE_CURRENT_BINARY_DIR}\")"
13574
VERBATIM
13675
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
137-
MAIN_DEPENDENCY ${GODOT_GDEXTENSION_API_FILE}
76+
MAIN_DEPENDENCY ${GDEXTENSION_API_FILE}
13877
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/binding_generator.py
13978
COMMENT "Generating bindings"
14079
)
@@ -144,73 +83,41 @@ file(GLOB_RECURSE SOURCES CONFIGURE_DEPENDS src/*.c**)
14483
file(GLOB_RECURSE HEADERS CONFIGURE_DEPENDS include/*.h**)
14584

14685
# Define our godot-cpp library
147-
add_library(${PROJECT_NAME} STATIC
86+
add_library(${PROJECT_NAME} ${GODOT_CPP_LIBRARY_TYPE}
14887
${SOURCES}
14988
${HEADERS}
15089
${GENERATED_FILES_LIST}
15190
)
15291
add_library(godot::cpp ALIAS ${PROJECT_NAME})
15392

154-
include(GodotCompilerWarnings)
155-
156-
target_compile_features(${PROJECT_NAME}
157-
PRIVATE
158-
cxx_std_17
159-
)
160-
161-
target_compile_definitions(${PROJECT_NAME} PUBLIC
162-
$<$<CONFIG:Debug>:
163-
DEBUG_ENABLED
164-
DEBUG_METHODS_ENABLED
165-
>
166-
$<${compiler_is_msvc}:
167-
TYPED_METHOD_BIND
168-
>
169-
)
170-
171-
target_link_options(${PROJECT_NAME} PRIVATE
172-
$<$<NOT:${compiler_is_msvc}>:
173-
-static-libgcc
174-
-static-libstdc++
175-
-Wl,-R,'$$ORIGIN'
176-
>
177-
)
178-
179-
# Optionally mark headers as SYSTEM
180-
set(GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE "")
181-
if (GODOT_CPP_SYSTEM_HEADERS)
182-
set(GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
183-
endif ()
184-
18593
target_include_directories(${PROJECT_NAME} ${GODOT_CPP_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
18694
include
18795
${CMAKE_CURRENT_BINARY_DIR}/gen/include
188-
${GODOT_GDEXTENSION_DIR}
96+
${GDEXTENSION_DIR}
18997
)
19098

191-
# Add the compile flags
192-
set_property(TARGET ${PROJECT_NAME} APPEND_STRING PROPERTY COMPILE_FLAGS ${GODOT_COMPILE_FLAGS})
99+
target_compile_features(${PROJECT_NAME} PUBLIC
100+
cxx_std_17
101+
)
193102

194-
# Create the correct name (godot.os.build_type.system_bits)
195-
string(TOLOWER "${CMAKE_SYSTEM_NAME}" SYSTEM_NAME)
196-
string(TOLOWER "${CMAKE_BUILD_TYPE}" BUILD_TYPE)
103+
target_compile_options(${PROJECT_NAME} PRIVATE
104+
${GODOT_CC_FLAGS}
105+
${GODOT_CXX_FLAGS}
106+
${GODOT_COMPILE_WARNING_FLAGS}
107+
)
197108

198-
if(ANDROID)
199-
# Added the android abi after system name
200-
set(SYSTEM_NAME ${SYSTEM_NAME}.${ANDROID_ABI})
109+
target_link_options(${PROJECT_NAME} PRIVATE ${GODOT_LINK_FLAGS})
201110

202-
# Android does not have the bits at the end if you look at the main godot repo build
203-
set(OUTPUT_NAME "godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}")
204-
else()
205-
set(OUTPUT_NAME "godot-cpp.${SYSTEM_NAME}.${BUILD_TYPE}.${BITS}")
206-
endif()
111+
target_compile_definitions(${PROJECT_NAME} PRIVATE ${GODOT_DEFINITIONS})
207112

208113
set_target_properties(${PROJECT_NAME}
209114
PROPERTIES
210115
CXX_EXTENSIONS OFF
116+
COMPILE_WARNING_AS_ERROR ${GODOT_CPP_WARNING_AS_ERROR}
211117
POSITION_INDEPENDENT_CODE ON
212118
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
213119
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
214120
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/bin"
215-
OUTPUT_NAME "${OUTPUT_NAME}"
121+
OUTPUT_NAME "${PROJECT_NAME}${LIBRARY_SUFFIX}"
216122
)
123+

cmake/GodotCompilerWarnings.cmake

Lines changed: 11 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,18 @@
1+
# Set some helper variables for readability
2+
set(compiler_is_clang "$<OR:$<CXX_COMPILER_ID:AppleClang>,$<CXX_COMPILER_ID:Clang>>")
3+
set(compiler_is_gnu "$<CXX_COMPILER_ID:GNU>")
4+
set(compiler_is_msvc "$<CXX_COMPILER_ID:MSVC>")
5+
16
# Add warnings based on compiler & version
27
# Set some helper variables for readability
3-
set( compiler_less_than_v8 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>" )
4-
set( compiler_greater_than_or_equal_v9 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9>" )
5-
set( compiler_greater_than_or_equal_v11 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,11>" )
6-
set( compiler_less_than_v11 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,11>" )
7-
set( compiler_greater_than_or_equal_v12 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,12>" )
8+
set(compiler_less_than_v8 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>")
9+
set(compiler_greater_than_or_equal_v9 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9>")
10+
set(compiler_greater_than_or_equal_v11 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,11>")
11+
set(compiler_less_than_v11 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,11>")
12+
set(compiler_greater_than_or_equal_v12 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,12>")
813

914
# These compiler options reflect what is in godot/SConstruct.
10-
target_compile_options( ${PROJECT_NAME} PRIVATE
15+
list(APPEND GODOT_COMPILE_WARNING_FLAGS
1116
# MSVC only
1217
$<${compiler_is_msvc}:
1318
/W4
@@ -71,24 +76,3 @@ target_compile_options( ${PROJECT_NAME} PRIVATE
7176
-Wno-return-type
7277
>
7378
)
74-
75-
# Treat warnings as errors
76-
function( set_warning_as_error )
77-
message( STATUS "[${PROJECT_NAME}] Treating warnings as errors")
78-
if ( CMAKE_VERSION VERSION_GREATER_EQUAL "3.24" )
79-
set_target_properties( ${PROJECT_NAME}
80-
PROPERTIES
81-
COMPILE_WARNING_AS_ERROR ON
82-
)
83-
else()
84-
target_compile_options( ${PROJECT_NAME}
85-
PRIVATE
86-
$<${compiler_is_msvc}:/WX>
87-
$<$<OR:${compiler_is_clang},${compiler_is_gnu}>:-Werror>
88-
)
89-
endif()
90-
endfunction()
91-
92-
if ( GODOT_CPP_WARNING_AS_ERROR )
93-
set_warning_as_error()
94-
endif()

cmake/android.cmake

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
# Used with android toolchain at $ANDROID_NDK/build/cmake/android.toolchain.cmake
2+
3+
set(ARCH "arm64" CACHE STRING "Target architecture (arm64, x86_64, arm32, x86_32, CUSTOM")
4+
5+
if(${ANDROID_PLATFORM} VERSION_LESS 21)
6+
message(FATAL_ERROR "Minimum supported API level is 21 (-DANDROID_PLATFORM=21)")
7+
endif()
8+
9+
# This must be kept in sync with the value in https://github.com/godotengine/godot/blob/master/platform/android/detect.py#L58.
10+
set(ANDROID_NDK_VERSION_EXPECTED "23.2.8568313")
11+
if(NOT "${ANDROID_NDK_REVISION}" STREQUAL "${ANDROID_NDK_VERSION_EXPECTED}")
12+
message(FATAL_ERROR "Android NDK version '${ANDROID_NDK_VERSION_EXPECTED}' expected, got '${ANDROID_NDK_REVISION}'")
13+
endif()
14+
15+
string(REGEX MATCH "32$|64$" DEFAULT_BITS "${ARCH}")
16+
set(BITS "${DEFAULT_BITS}" CACHE STRING "Architecture bits. Needs to be set manually for custom architecture")
17+
18+
19+
list(APPEND GODOT_DEFINITIONS
20+
ANDROID_ENABLED
21+
UNIX_ENABLED
22+
)
23+
24+
list(APPEND GODOT_CC_FLAGS
25+
$<$<STREQUAL:${ARCH},arm32>:
26+
--target=armv7a-linux-androideabi${ANDROID_PLATFORM}
27+
-march=armv7-a
28+
29+
-mfpu=neon
30+
>
31+
$<$<STREQUAL:${ARCH},arm64>:
32+
--target=aarch64-linux-android${ANDROID_PLATFORM}
33+
-march=armv8-a
34+
>
35+
$<$<STREQUAL:${ARCH},x86_32>:
36+
--target=i686-linux-android${ANDROID_PLATFORM}
37+
-march=i686
38+
39+
-mstackrealign
40+
>
41+
$<$<STREQUAL:${ARCH},x86_64>:
42+
--target=x86_64-linux-android${ANDROID_PLATFORM}
43+
-march=x86-64
44+
>
45+
)
46+
47+
list(APPEND GODOT_LINK_FLAGS
48+
$<$<STREQUAL:${ARCH},arm32>:
49+
--target=armv7a-linux-androideabi${ANDROID_PLATFORM}
50+
-march=armv7-a
51+
>
52+
$<$<STREQUAL:${ARCH},arm64>:
53+
--target=aarch64-linux-android${ANDROID_PLATFORM}
54+
-march=armv8-a
55+
>
56+
$<$<STREQUAL:${ARCH},x86_32>:
57+
--target=i686-linux-android${ANDROID_PLATFORM}
58+
-march=i686
59+
>
60+
$<$<STREQUAL:${ARCH},x86_64>:
61+
--target=x86_64-linux-android${ANDROID_PLATFORM}
62+
-march=x86-64
63+
>
64+
)
65+
66+
string(APPEND LIBRARY_SUFFIX ".${ARCH}")
67+

0 commit comments

Comments
 (0)