Skip to content

Commit e716971

Browse files
committed
CMake: Support using build_profile.json
Add python_callouts.py to hold functions which call python utilities - generate trimmed API - generate file list - generate bindings if GODOT_BUILD_PROFILE is specified, a trimmed API file is created in the CMAKE_CURRENT_BINARY_DIR and used as the source for binding generation Simplify Code Generation Variables - use generator expressions - use math for bits - simplify if statements
1 parent 012b8ff commit e716971

File tree

2 files changed

+132
-27
lines changed

2 files changed

+132
-27
lines changed

cmake/godotcpp.cmake

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux.cmake)
3030
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos.cmake)
3131
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/web.cmake)
3232
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows.cmake)
33+
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/python_callouts.cmake)
3334

3435
# Detect number of processors
3536
include(ProcessorCount)
@@ -109,7 +110,9 @@ function( godotcpp_options )
109110
#TODO threads
110111
#TODO compiledb
111112
#TODO compiledb_file
112-
#TODO build_profile
113+
114+
set( GODOT_BUILD_PROFILE "" CACHE PATH
115+
"Path to a file containing a feature build profile" )
113116

114117
set(GODOT_USE_HOT_RELOAD "" CACHE BOOL
115118
"Enable the extra accounting required to support hot reload. (ON|OFF)")
@@ -193,40 +196,44 @@ function( godotcpp_generate )
193196
set(GODOT_SYSTEM_HEADERS_ATTRIBUTE SYSTEM)
194197
endif ()
195198

196-
#[[ Generate Bindings ]]
197-
if(NOT DEFINED BITS)
198-
set(BITS 32)
199-
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
200-
set(BITS 64)
201-
endif(CMAKE_SIZEOF_VOID_P EQUAL 8)
202-
endif()
199+
#[[ Configure Binding Variables ]]
200+
# Generate Binding Parameters (True|False)
201+
set( GENERATE_BINDING_PARAMETERS "$<IF:$<BOOL:${GODOT_GENERATE_TEMPLATE_GET_NODE}>,True,False>" )
203202

203+
# Bits (32|64)
204+
math( EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8" ) # CMAKE_SIZEOF_VOID_P refers to target architecture.
205+
206+
# API json File
204207
set(GODOT_GDEXTENSION_API_FILE "${GODOT_GDEXTENSION_DIR}/extension_api.json")
205-
if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override.
208+
if( GODOT_CUSTOM_API_FILE ) # User-defined override.
206209
set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}")
207210
endif()
208211

209-
# Code Generation option
210-
if(GODOT_GENERATE_TEMPLATE_GET_NODE)
211-
set(GENERATE_BINDING_PARAMETERS "True")
212-
else()
213-
set(GENERATE_BINDING_PARAMETERS "False")
212+
# Build Profile
213+
if( GODOT_BUILD_PROFILE )
214+
message( STATUS "Using build profile to trim api file")
215+
message( "\tBUILD_PROFILE = '${GODOT_BUILD_PROFILE}'")
216+
message( "\tAPI_SOURCE = '${GODOT_GDEXTENSION_API_FILE}'")
217+
build_profile_generate_trimmed_api(
218+
"${GODOT_BUILD_PROFILE}"
219+
"${GODOT_GDEXTENSION_API_FILE}"
220+
"${CMAKE_CURRENT_BINARY_DIR}/extension_api.json" )
221+
set( GODOT_GDEXTENSION_API_FILE "${CMAKE_CURRENT_BINARY_DIR}/extension_api.json" )
214222
endif()
215223

216-
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)"
217-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
218-
OUTPUT_VARIABLE GENERATED_FILES_LIST
219-
OUTPUT_STRIP_TRAILING_WHITESPACE
220-
)
224+
message( STATUS "GODOT_GDEXTENSION_API_FILE = '${GODOT_GDEXTENSION_API_FILE}'")
221225

222-
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
223-
COMMAND "${Python3_EXECUTABLE}" "-c" "import binding_generator; binding_generator.generate_bindings('${GODOT_GDEXTENSION_API_FILE}', '${GENERATE_BINDING_PARAMETERS}', '${BITS}', '${GODOT_PRECISION}', '${CMAKE_CURRENT_BINARY_DIR}')"
224-
VERBATIM
225-
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
226-
MAIN_DEPENDENCY ${GODOT_GDEXTENSION_API_FILE}
227-
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/binding_generator.py
228-
COMMENT "Generating bindings"
229-
)
226+
# generate the file list to use
227+
binding_generator_get_file_list( GENERATED_FILES_LIST
228+
"${GODOT_GDEXTENSION_API_FILE}"
229+
"${CMAKE_CURRENT_BINARY_DIR}" )
230+
231+
binding_generator_generate_bindings(
232+
"${GODOT_GDEXTENSION_API_FILE}"
233+
"${GENERATE_BINDING_PARAMETERS}"
234+
"${BITS}"
235+
"${GODOT_PRECISION}"
236+
"${CMAKE_CURRENT_BINARY_DIR}" )
230237

231238
### Platform is derived from the toolchain target
232239
# See GeneratorExpressions PLATFORM_ID and CMAKE_SYSTEM_NAME

cmake/python_callouts.cmake

Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
#[=======================================================================[.rst:
2+
python_callouts.cmake
3+
--------------
4+
5+
This file contains functions which which rely on calling Python
6+
7+
* Generate Trimmed API
8+
* Generate File List
9+
* Generate Bindings
10+
]=======================================================================]
11+
12+
#[[ Generate Trimmed API
13+
The build_profile.py has a __main__ and is used as a tool
14+
Its usage is listed as
15+
16+
$ python build_profile.py BUILD_PROFILE INPUT_JSON [OUTPUT_JSON]
17+
18+
]]
19+
function( build_profile_generate_trimmed_api BUILD_PROFILE INPUT_JSON OUTPUT_JSON )
20+
execute_process(
21+
COMMAND "${Python3_EXECUTABLE}" "build_profile.py" "${BUILD_PROFILE}" "${INPUT_JSON}" "${OUTPUT_JSON}"
22+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
23+
)
24+
endfunction( )
25+
26+
#[[ Generate File List
27+
28+
Use the binding_generator.py Python script to determine the list of files that
29+
will be passed to the code generator using extension_api.json and build_profile.json.
30+
31+
This happens for every configure.]]
32+
function( binding_generator_get_file_list OUT_VAR_NAME API_FILEPATH OUTPUT_DIR )
33+
34+
# This code snippet will be squashed into a single line
35+
# The two strings make this a list, in CMake lists are semicolon delimited strings.
36+
set( PYTHON_SCRIPT
37+
"from binding_generator import print_file_list"
38+
"print_file_list( api_filepath='${API_FILEPATH}',
39+
output_dir='${OUTPUT_DIR}',
40+
headers=True,
41+
sources=True)")
42+
message( DEBUG "Python:\n${PYTHON_SCRIPT}" )
43+
44+
# Strip newlines and whitespace to make it a one-liner.
45+
string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" )
46+
47+
execute_process( COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
48+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
49+
OUTPUT_VARIABLE GENERATED_FILES_LIST
50+
OUTPUT_STRIP_TRAILING_WHITESPACE
51+
)
52+
53+
# Debug output
54+
message( DEBUG "FileList-Begin" )
55+
foreach( PATH ${GENERATED_FILES_LIST} )
56+
message( DEBUG ${PATH} )
57+
endforeach()
58+
59+
# Error out if the file list generator returned no files.
60+
list( LENGTH GENERATED_FILES_LIST LIST_LENGTH )
61+
if( NOT LIST_LENGTH GREATER 0 )
62+
message( FATAL_ERROR "File List Generation Failed")
63+
endif()
64+
message( STATUS "There are ${LIST_LENGTH} Files to generate" )
65+
66+
set( ${OUT_VAR_NAME} ${GENERATED_FILES_LIST} PARENT_SCOPE )
67+
endfunction( )
68+
69+
70+
#[[ Generate Bindings
71+
72+
Using the generated file list, use the binding_generator.py to generate the
73+
godot-cpp bindings. This will run at build time only if there are files
74+
missing. ]]
75+
function( binding_generator_generate_bindings API_FILE GEN_PARAMS, BITS, PRECISION, OUTPUT_DIR )
76+
# This code snippet will be squashed into a single line
77+
set( PYTHON_SCRIPT "from binding_generator import generate_bindings"
78+
"generate_bindings(
79+
api_filepath='${API_FILE}',
80+
use_template_get_node='${GEN_PARAMS}',
81+
bits='${BITS}',
82+
precision='${PRECISION}',
83+
output_dir='${OUTPUT_DIR}')")
84+
85+
message( DEBUG "Python:\n${PYTHON_SCRIPT}" )
86+
87+
# Strip newlines and whitespace to make it a one-liner.
88+
string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" )
89+
90+
add_custom_command(OUTPUT ${GENERATED_FILES_LIST}
91+
COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
92+
VERBATIM
93+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
94+
MAIN_DEPENDENCY ${GODOT_GDEXTENSION_API_FILE}
95+
DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/binding_generator.py
96+
COMMENT "Generating bindings"
97+
)
98+
endfunction( )

0 commit comments

Comments
 (0)