Skip to content

Commit 6388e26

Browse files
authored
Merge pull request #1745 from dsnopek/4.4-cherrypicks-1
Cherry-picks for the godot-cpp 4.4 branch - 1st batch
2 parents 714c9e2 + e9a6dbd commit 6388e26

18 files changed

+785
-713
lines changed

.github/workflows/ci.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,8 +202,8 @@ jobs:
202202
run: |
203203
mkdir cmake-build
204204
cd cmake-build
205-
cmake ../ -DGODOTCPP_ENABLE_TESTING=YES
206-
cmake --build . --verbose -j $(nproc) -t godot-cpp.test.template_release --config Release
205+
cmake ../ -DGODOTCPP_ENABLE_TESTING=YES -DGODOTCPP_TARGET=template_release
206+
cmake --build . --verbose -j $(nproc) --target godot-cpp-test --config Release
207207
208208
windows-msvc-cmake:
209209
name: 🏁 Build (Windows, MSVC, CMake)
@@ -218,5 +218,5 @@ jobs:
218218
run: |
219219
mkdir cmake-build
220220
cd cmake-build
221-
cmake ../ -DGODOTCPP_ENABLE_TESTING=YES
222-
cmake --build . --verbose -t godot-cpp.test.template_release --config Release
221+
cmake ../ -DGODOTCPP_ENABLE_TESTING=YES -DGODOTCPP_TARGET=template_release
222+
cmake --build . --verbose --target godot-cpp-test --config Release

.pre-commit-config.yaml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ repos:
3333
- id: codespell
3434
additional_dependencies: [tomli]
3535

36+
- repo: https://github.com/BlankSpruce/gersemi
37+
rev: 0.18.2
38+
hooks:
39+
- id: gersemi
40+
args: ["-i", "--no-warn-about-unknown-commands", "-l", "120"]
41+
3642
- repo: local
3743
hooks:
3844
- id: copyright-headers

CMakeLists.txt

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ To enable use of the emscripten emsdk hack for pseudo shared library support
99
without polluting options for consumers we need to use the
1010
CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE which was introduced in version 3.17
1111
12-
Scons Compatibility
12+
For more information check cmake/emsdkHack.cmake
13+
14+
SCons Compatibility
1315
-------------------
1416
1517
There is an understandable conflict between build systems as they define
@@ -18,6 +20,9 @@ compromises need to be made to resolve those differences.
1820
1921
As we are attempting to maintain feature parity, and ease of maintenance, these
2022
CMake scripts are built to resemble the SCons build system wherever possible.
23+
Where they are not, we will attempt to document common difference in
24+
doc/cmake.rst and platform specific differences in their respective
25+
cmake/<platform>.cmake file.
2126
2227
The file structure and file content are made to match, if not in content then
2328
in spirit. The closer the two build systems look the easier they will be to
@@ -26,8 +31,7 @@ maintain.
2631
Where the SCons additional scripts in the tools directory, The CMake scripts
2732
are in the cmake directory.
2833
29-
For example, the tools/godotcpp.py is sourced into SCons, and the 'options'
30-
function is run.
34+
For example; the tools/godotcpp.py is matched by the cmake/godotcpp.cmake file
3135
3236
.. highlight:: python
3337
@@ -36,27 +40,35 @@ function is run.
3640
3741
The CMake equivalent is below.
3842
]=======================================================================]
39-
40-
include( cmake/godotcpp.cmake )
43+
include(cmake/godotcpp.cmake)
4144

4245
godotcpp_options()
4346

47+
#[[ People are compiling godot by itself and expecting template_debug
48+
Replace this with PROJECT_IS_TOP_LEVEL, <PROJECT-NAME>_IS_TOP_LEVEL when minimum reaches 3.21
49+
]]
50+
if(NOT PROJECT_NAME)
51+
set(GODOTCPP_IS_TOP_LEVEL ON)
52+
endif()
53+
4454
# Define our project.
45-
project( godot-cpp
46-
VERSION 4.4
47-
DESCRIPTION "C++ bindings for the Godot Engine's GDExtensions API."
48-
HOMEPAGE_URL "https://github.com/godotengine/godot-cpp"
49-
LANGUAGES CXX)
55+
project(
56+
godot-cpp
57+
VERSION 4.4
58+
DESCRIPTION "C++ bindings for the Godot Engine's GDExtensions API."
59+
HOMEPAGE_URL "https://github.com/godotengine/godot-cpp"
60+
LANGUAGES CXX
61+
)
5062

5163
compiler_detection()
5264
godotcpp_generate()
5365

5466
# Conditionally enable the godot-cpp.test.<target> integration testing targets
55-
if( GODOTCPP_ENABLE_TESTING )
56-
add_subdirectory( test )
67+
if(GODOTCPP_ENABLE_TESTING)
68+
add_subdirectory(test)
5769
endif()
5870

59-
# If this is the top level CMakeLists.txt, Generators which honor the
60-
# USE_FOLDERS flag will organize godot-cpp targets under the subfolder
61-
# 'godot-cpp'. This is enable by default from CMake version 3.26
71+
#[[ If this is the top level CMakeLists.txt, Generators which honor the
72+
USE_FOLDERS flag will organize godot-cpp targets under a subfolder named
73+
'godot-cpp'. This is enable by default from CMake version 3.26 ]]
6274
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

binding_generator.py

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,14 +290,19 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision=
290290
api = {}
291291
with open(api_filepath, encoding="utf-8") as api_file:
292292
api = json.load(api_file)
293-
_generate_bindings(api, use_template_get_node, bits, precision, output_dir)
293+
_generate_bindings(api, api_filepath, use_template_get_node, bits, precision, output_dir)
294294

295295

296-
def _generate_bindings(api, use_template_get_node, bits="64", precision="single", output_dir="."):
296+
def _generate_bindings(api, api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."):
297+
if "precision" in api["header"] and precision != api["header"]["precision"]:
298+
raise Exception(
299+
f"Cannot do a precision={precision} build using '{api_filepath}' which was generated by Godot built with precision={api['header']['precision']}"
300+
)
301+
297302
target_dir = Path(output_dir) / "gen"
298303

299304
shutil.rmtree(target_dir, ignore_errors=True)
300-
target_dir.mkdir(parents=True)
305+
target_dir.mkdir(parents=True, exist_ok=True)
301306

302307
real_t = "double" if precision == "double" else "float"
303308
print("Built-in type config: " + real_t + "_" + bits)

cmake/GodotCPPModule.cmake

Lines changed: 80 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -26,144 +26,151 @@ The build_profile.py has a __main__ and is used as a tool
2626
Its usage is listed as:
2727
$ python build_profile.py BUILD_PROFILE INPUT_JSON [OUTPUT_JSON]
2828
]]
29-
function( build_profile_generate_trimmed_api BUILD_PROFILE INPUT_JSON OUTPUT_JSON )
29+
function(build_profile_generate_trimmed_api BUILD_PROFILE INPUT_JSON OUTPUT_JSON)
3030
execute_process(
31-
COMMAND "${Python3_EXECUTABLE}"
32-
"${godot-cpp_SOURCE_DIR}/build_profile.py"
33-
"${BUILD_PROFILE}"
34-
"${INPUT_JSON}"
35-
"${OUTPUT_JSON}"
36-
WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR}
31+
COMMAND
32+
"${Python3_EXECUTABLE}" "${godot-cpp_SOURCE_DIR}/build_profile.py" "${BUILD_PROFILE}" "${INPUT_JSON}"
33+
"${OUTPUT_JSON}"
34+
WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR}
3735
)
38-
endfunction( )
39-
36+
endfunction()
4037

4138
#[[ Generate File List
4239
4340
Use the binding_generator.py Python script to determine the list of files that
4441
will be passed to the code generator using extension_api.json.
4542
NOTE: This happens for every configure.]]
46-
function( binding_generator_get_file_list OUT_VAR_NAME API_FILEPATH OUTPUT_DIR )
47-
43+
function(binding_generator_get_file_list OUT_VAR_NAME API_FILEPATH OUTPUT_DIR)
4844
# This code snippet will be squashed into a single line
4945
# The two strings make this a list, in CMake lists are semicolon delimited strings.
50-
set( PYTHON_SCRIPT
51-
"from binding_generator import print_file_list"
52-
"print_file_list( api_filepath='${API_FILEPATH}',
46+
set(PYTHON_SCRIPT
47+
"from binding_generator import print_file_list"
48+
"print_file_list( api_filepath='${API_FILEPATH}',
5349
output_dir='${OUTPUT_DIR}',
5450
headers=True,
55-
sources=True)")
56-
message( DEBUG "Python:\n${PYTHON_SCRIPT}" )
51+
sources=True)"
52+
)
53+
message(DEBUG "Python:\n${PYTHON_SCRIPT}")
5754

5855
# Strip newlines and whitespace to make it a one-liner.
59-
string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" )
56+
string(REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}")
6057

61-
execute_process( COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
62-
WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}"
63-
OUTPUT_VARIABLE GENERATED_FILES_LIST
64-
OUTPUT_STRIP_TRAILING_WHITESPACE
58+
execute_process(
59+
COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
60+
WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}"
61+
OUTPUT_VARIABLE GENERATED_FILES_LIST
62+
OUTPUT_STRIP_TRAILING_WHITESPACE
6563
)
6664

6765
# Debug output
68-
message( DEBUG "FileList-Begin" )
69-
foreach( PATH ${GENERATED_FILES_LIST} )
70-
message( DEBUG ${PATH} )
66+
message(DEBUG "FileList-Begin")
67+
foreach(PATH ${GENERATED_FILES_LIST})
68+
message(DEBUG ${PATH})
7169
endforeach()
7270

7371
# Error out if the file list generator returned no files.
74-
list( LENGTH GENERATED_FILES_LIST LIST_LENGTH )
75-
if( NOT LIST_LENGTH GREATER 0 )
76-
message( FATAL_ERROR "File List Generation Failed")
72+
list(LENGTH GENERATED_FILES_LIST LIST_LENGTH)
73+
if(NOT LIST_LENGTH GREATER 0)
74+
message(FATAL_ERROR "File List Generation Failed")
7775
endif()
78-
message( STATUS "There are ${LIST_LENGTH} Files to generate" )
79-
80-
set( ${OUT_VAR_NAME} ${GENERATED_FILES_LIST} PARENT_SCOPE )
81-
endfunction( )
76+
message(STATUS "There are ${LIST_LENGTH} Files to generate")
8277

78+
set(${OUT_VAR_NAME} ${GENERATED_FILES_LIST} PARENT_SCOPE)
79+
endfunction()
8380

8481
#[[ Generate Bindings
8582
8683
Using the generated file list, use the binding_generator.py to generate the
8784
godot-cpp bindings. This will run at build time only if there are files
8885
missing. ]]
89-
function( binding_generator_generate_bindings API_FILE USE_TEMPLATE_GET_NODE, BITS, PRECISION, OUTPUT_DIR )
86+
function(
87+
binding_generator_generate_bindings
88+
API_FILE
89+
USE_TEMPLATE_GET_NODE,
90+
BITS,
91+
PRECISION,
92+
OUTPUT_DIR
93+
)
9094
# This code snippet will be squashed into a single line
91-
set( PYTHON_SCRIPT
92-
"from binding_generator import generate_bindings"
93-
"generate_bindings(
95+
set(PYTHON_SCRIPT
96+
"from binding_generator import generate_bindings"
97+
"generate_bindings(
9498
api_filepath='${API_FILE}',
9599
use_template_get_node='${USE_TEMPLATE_GET_NODE}',
96100
bits='${BITS}',
97101
precision='${PRECISION}',
98-
output_dir='${OUTPUT_DIR}')")
102+
output_dir='${OUTPUT_DIR}')"
103+
)
99104

100-
message( DEBUG "Python:\n${PYTHON_SCRIPT}" )
105+
message(DEBUG "Python:\n${PYTHON_SCRIPT}")
101106

102107
# Strip newlines and whitespace to make it a one-liner.
103-
string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" )
104-
105-
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
106-
COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
107-
VERBATIM
108-
WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR}
109-
MAIN_DEPENDENCY ${GODOTCPP_GDEXTENSION_API_FILE}
110-
DEPENDS ${godot-cpp_SOURCE_DIR}/binding_generator.py
111-
COMMENT "Generating bindings"
108+
string(REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}")
109+
110+
add_custom_command(
111+
OUTPUT ${GENERATED_FILES_LIST}
112+
COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
113+
VERBATIM
114+
WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR}
115+
MAIN_DEPENDENCY ${GODOTCPP_GDEXTENSION_API_FILE}
116+
DEPENDS ${godot-cpp_SOURCE_DIR}/binding_generator.py
117+
COMMENT "Generating bindings"
112118
)
113-
endfunction( )
119+
add_custom_target(generate_bindings DEPENDS ${GENERATED_FILES_LIST})
120+
set_target_properties(generate_bindings PROPERTIES FOLDER "godot-cpp")
121+
endfunction()
114122

115123
#[[ Generate doc_data.cpp
116124
The documentation displayed in the Godot editor is compiled into the extension.
117125
It takes a list of XML source files, and transforms them into a cpp file that
118126
is added to the sources list.]]
119-
function( generate_doc_source OUTPUT_PATH SOURCES )
127+
function(generate_doc_source OUTPUT_PATH SOURCES)
120128
# Transform SOURCES CMake LIST
121129
# quote each path with ''
122130
# join with , to transform into a python list minus the surrounding []
123-
set( PYTHON_LIST "${SOURCES}")
124-
list( TRANSFORM PYTHON_LIST REPLACE "(.*\.xml)" "'\\1'" )
125-
list( JOIN PYTHON_LIST "," PYTHON_LIST )
131+
set(PYTHON_LIST "${SOURCES}")
132+
list(TRANSFORM PYTHON_LIST REPLACE "(.*\.xml)" "'\\1'")
133+
list(JOIN PYTHON_LIST "," PYTHON_LIST)
126134

127135
get_filename_component(OUTPUT_DIR "${OUTPUT_PATH}" DIRECTORY)
128-
file(MAKE_DIRECTORY ${OUTPUT_DIR} )
136+
file(MAKE_DIRECTORY ${OUTPUT_DIR})
129137

130138
# Python one-liner to run our command
131139
# lists in CMake are just strings delimited by ';', so this works.
132-
set( PYTHON_SCRIPT "from doc_source_generator import generate_doc_source"
133-
"generate_doc_source( '${OUTPUT_PATH}', [${PYTHON_LIST}] )" )
134-
135-
add_custom_command( OUTPUT "${OUTPUT_PATH}"
136-
COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
137-
VERBATIM
138-
WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}"
139-
DEPENDS
140+
set(PYTHON_SCRIPT
141+
"from doc_source_generator import generate_doc_source"
142+
"generate_doc_source( '${OUTPUT_PATH}', [${PYTHON_LIST}] )"
143+
)
144+
145+
add_custom_command(
146+
OUTPUT "${OUTPUT_PATH}"
147+
COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
148+
VERBATIM
149+
WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}"
150+
DEPENDS #
140151
"${godot-cpp_SOURCE_DIR}/doc_source_generator.py"
141152
"${SOURCES}"
142-
COMMENT "Generating: ${OUTPUT_PATH}"
153+
COMMENT "Generating: ${OUTPUT_PATH}"
143154
)
155+
add_custom_target(generate_doc_source DEPENDS "${OUTPUT_PATH}")
156+
set_target_properties(generate_doc_source PROPERTIES FOLDER "godot-cpp")
144157
endfunction()
145158

146159
#[[ target_doc_sources
147160
A simpler interface to add xml files as doc source to a output target.
148161
TARGET: The gdexension library target
149-
SOURCES: a list of xml files to use for source generation and inclusion.
150-
This function also adds a doc_gen target to test source generation.]]
151-
function( target_doc_sources TARGET SOURCES )
162+
SOURCES: a list of xml files to use for source generation and inclusion.]]
163+
function(target_doc_sources TARGET SOURCES)
152164
# set the generated file name
153-
set( DOC_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/gen/doc_source.cpp" )
165+
set(DOC_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/gen/doc_source.cpp")
154166

155167
# Create the file generation target, this won't be triggered unless a target
156168
# that depends on DOC_SOURCE_FILE is built
157169
generate_doc_source( "${DOC_SOURCE_FILE}" ${SOURCES} )
158170

159171
# Add DOC_SOURCE_FILE as a dependency to TARGET
160-
target_sources( ${TARGET} PRIVATE "${DOC_SOURCE_FILE}" )
172+
target_sources(${TARGET} PRIVATE "${DOC_SOURCE_FILE}")
161173

162-
# Create a dummy target that depends on the source so that users can
163-
# test the file generation task.
164-
if( TARGET doc_gen )
165-
else()
166-
add_custom_target( doc_gen )
167-
endif()
168-
target_sources( doc_gen PRIVATE "${DOC_SOURCE_FILE}" )
174+
# Without adding this dependency to the doc_source_generator, XCode will complain.
175+
add_dependencies(${TARGET} generate_doc_source)
169176
endfunction()

cmake/android.cmake

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,25 @@ Android platforms.
2525
There is further information and examples in the doc/cmake.rst file.
2626
2727
]=======================================================================]
28-
function( android_options )
29-
# Android Options
28+
29+
#[============================[ Android Options ]============================]
30+
function(android_options)
31+
#[[ Options from SCons
32+
33+
The options below are managed by CMake toolchain files, doc.cmake.rst has
34+
more information
35+
36+
android_api_level : Target Android API level.
37+
Default = 21
38+
39+
ANDROID_HOME : Path to your Android SDK installation.
40+
Default = os.environ.get("ANDROID_HOME", os.environ.get("ANDROID_SDK_ROOT")
41+
]]
3042
endfunction()
3143

32-
function( android_generate )
33-
target_compile_definitions(${TARGET_NAME}
34-
PUBLIC
35-
ANDROID_ENABLED
36-
UNIX_ENABLED
37-
)
44+
#[===========================[ Target Generation ]===========================]
45+
function(android_generate)
46+
target_compile_definitions(godot-cpp PUBLIC ANDROID_ENABLED UNIX_ENABLED)
3847

3948
common_compiler_flags()
4049
endfunction()

0 commit comments

Comments
 (0)