From ff55aee5350d669811953db8fea3d08799d7ed73 Mon Sep 17 00:00:00 2001 From: Samuel Nicholas Date: Sat, 28 Dec 2024 21:32:45 +1030 Subject: [PATCH] CMake: Support using build_profile.json CMake: - add GODOT_BUILD_PROFILE cache option - Split file list generation into its own function - add status and debug messages Python Snippets in CMake: - use the get_file_list function directly - re-format for better readability Build Profile: - Add missing VisualInstance3D class to build_profile.json --- cmake/godotcpp.cmake | 81 +++++++++++++++++++++++++++++++++++++---- test/build_profile.json | 3 +- 2 files changed, 76 insertions(+), 8 deletions(-) diff --git a/cmake/godotcpp.cmake b/cmake/godotcpp.cmake index 89fafc45f..5f019a245 100644 --- a/cmake/godotcpp.cmake +++ b/cmake/godotcpp.cmake @@ -81,6 +81,50 @@ function( godot_arch_map ALIAS PROC ) endif () endfunction() + +#[[ Generate File List +Use the binding_generator.py Python script to determine the list of files that +will be passed to the code generator using extension_api.json and build_profile.json. + +This happens for every configure.]] +function( binding_generator_get_file_list OUT_VAR_NAME API_FILEPATH PROFILE_FILEPATH OUTPUT_DIR ) + # This code snippet will be squashed into a single line + + set( PYTHON_SCRIPT "from binding_generator import get_file_list" + "file_list = get_file_list( api_filepath='${API_FILEPATH}', + output_dir='${OUTPUT_DIR}', + headers=True, + sources=True, + profile_filepath='${PROFILE_FILEPATH}')" + "print(*file_list, sep=';', end=None)") + message( DEBUG "Python:\n${PYTHON_SCRIPT}" ) + + # Strip newlines and whitespace to make it a one-liner. + string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" ) + + execute_process( COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + OUTPUT_VARIABLE GENERATED_FILES_LIST + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + # Debug output + message( DEBUG "FileList-Begin" ) + foreach( PATH ${GENERATED_FILES_LIST} ) + message( DEBUG ${PATH} ) + endforeach() + + # Error out if the file list generator returned no files. + list( LENGTH GENERATED_FILES_LIST LIST_LENGTH ) + if( NOT LIST_LENGTH GREATER 0 ) + message( FATAL_ERROR "File List Generation Failed") + endif() + message( STATUS "There are ${LIST_LENGTH} Files to generate" ) + + set( ${OUT_VAR_NAME} ${GENERATED_FILES_LIST} PARENT_SCOPE ) +endfunction( ) + + # Function to define all the options. function( godotcpp_options ) #NOTE: platform is managed using toolchain files. @@ -109,7 +153,9 @@ function( godotcpp_options ) #TODO threads #TODO compiledb #TODO compiledb_file - #TODO build_profile + + set( GODOT_BUILD_PROFILE "" CACHE PATH + "Path to a file containing a feature build profile" ) set(GODOT_USE_HOT_RELOAD "" CACHE BOOL "Enable the extra accounting required to support hot reload. (ON|OFF)") @@ -205,6 +251,10 @@ function( godotcpp_generate ) if (NOT "${GODOT_CUSTOM_API_FILE}" STREQUAL "") # User-defined override. set(GODOT_GDEXTENSION_API_FILE "${GODOT_CUSTOM_API_FILE}") endif() + message( STATUS "GODOT_GDEXTENSION_API_FILE = '${GODOT_GDEXTENSION_API_FILE}'") + if( GODOT_BUILD_PROFILE ) + message( STATUS "GODOT_BUILD_PROFILE = '${GODOT_BUILD_PROFILE}'") + endif( ) # Code Generation option if(GODOT_GENERATE_TEMPLATE_GET_NODE) @@ -213,14 +263,31 @@ function( godotcpp_generate ) set(GENERATE_BINDING_PARAMETERS "False") endif() - 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)" - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} - OUTPUT_VARIABLE GENERATED_FILES_LIST - OUTPUT_STRIP_TRAILING_WHITESPACE - ) + # generate the file list to use + binding_generator_get_file_list( GENERATED_FILES_LIST + "${GODOT_GDEXTENSION_API_FILE}" + "${GODOT_BUILD_PROFILE}" + "${CMAKE_CURRENT_BINARY_DIR}" ) + + #[[ Generate Bindings + Using the generated file list, use the binding_generator.py to generate the + godot-cpp bindings. This will run at build time only if there are files + missing. ]] + set( PYTHON_SCRIPT "from binding_generator import generate_bindings" + "generate_bindings( + api_filepath='${GODOT_GDEXTENSION_API_FILE}', + use_template_get_node='${GENERATE_BINDING_PARAMETERS}', + bits='${BITS}', + precision='${GODOT_PRECISION}', + output_dir='${CMAKE_CURRENT_BINARY_DIR}', + profile_filepath='${GODOT_BUILD_PROFILE}") + message( DEBUG "Python:\n${PYTHON_SCRIPT}" ) + + # Strip newlines and whitespace to make it a one-liner. + string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" ) add_custom_command(OUTPUT ${GENERATED_FILES_LIST} - 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}')" + COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}" VERBATIM WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} MAIN_DEPENDENCY ${GODOT_GDEXTENSION_API_FILE} diff --git a/test/build_profile.json b/test/build_profile.json index 3587651c1..f1377b5ca 100644 --- a/test/build_profile.json +++ b/test/build_profile.json @@ -4,6 +4,7 @@ "Label", "OS", "TileMap", - "InputEventKey" + "InputEventKey", + "VisualInstance3D" ] }