diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c1e4aecb..5782b310 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -202,8 +202,8 @@ jobs: run: | mkdir cmake-build cd cmake-build - cmake ../ -DGODOTCPP_ENABLE_TESTING=YES - cmake --build . --verbose -j $(nproc) -t godot-cpp.test.template_release --config Release + cmake ../ -DGODOTCPP_ENABLE_TESTING=YES -DGODOTCPP_TARGET=template_release + cmake --build . --verbose -j $(nproc) --target godot-cpp-test --config Release windows-msvc-cmake: name: 🏁 Build (Windows, MSVC, CMake) @@ -218,5 +218,5 @@ jobs: run: | mkdir cmake-build cd cmake-build - cmake ../ -DGODOTCPP_ENABLE_TESTING=YES - cmake --build . --verbose -t godot-cpp.test.template_release --config Release + cmake ../ -DGODOTCPP_ENABLE_TESTING=YES -DGODOTCPP_TARGET=template_release + cmake --build . --verbose --target godot-cpp-test --config Release diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index e63f1d40..7354ba41 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,6 +33,12 @@ repos: - id: codespell additional_dependencies: [tomli] + - repo: https://github.com/BlankSpruce/gersemi + rev: 0.18.2 + hooks: + - id: gersemi + args: ["-i", "--no-warn-about-unknown-commands", "-l", "120"] + - repo: local hooks: - id: copyright-headers diff --git a/CMakeLists.txt b/CMakeLists.txt index 9e4b1f50..32dce3ec 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,7 +9,9 @@ To enable use of the emscripten emsdk hack for pseudo shared library support without polluting options for consumers we need to use the CMAKE_PROJECT__INCLUDE which was introduced in version 3.17 -Scons Compatibility +For more information check cmake/emsdkHack.cmake + +SCons Compatibility ------------------- There is an understandable conflict between build systems as they define @@ -18,6 +20,9 @@ compromises need to be made to resolve those differences. As we are attempting to maintain feature parity, and ease of maintenance, these CMake scripts are built to resemble the SCons build system wherever possible. +Where they are not, we will attempt to document common difference in +doc/cmake.rst and platform specific differences in their respective +cmake/.cmake file. The file structure and file content are made to match, if not in content then in spirit. The closer the two build systems look the easier they will be to @@ -26,8 +31,7 @@ maintain. Where the SCons additional scripts in the tools directory, The CMake scripts are in the cmake directory. -For example, the tools/godotcpp.py is sourced into SCons, and the 'options' -function is run. +For example; the tools/godotcpp.py is matched by the cmake/godotcpp.cmake file .. highlight:: python @@ -36,27 +40,35 @@ function is run. The CMake equivalent is below. ]=======================================================================] - -include( cmake/godotcpp.cmake ) +include(cmake/godotcpp.cmake) godotcpp_options() +#[[ People are compiling godot by itself and expecting template_debug +Replace this with PROJECT_IS_TOP_LEVEL, _IS_TOP_LEVEL when minimum reaches 3.21 +]] +if(NOT PROJECT_NAME) + set(GODOTCPP_IS_TOP_LEVEL ON) +endif() + # Define our project. -project( godot-cpp - VERSION 4.4 - DESCRIPTION "C++ bindings for the Godot Engine's GDExtensions API." - HOMEPAGE_URL "https://github.com/godotengine/godot-cpp" - LANGUAGES CXX) +project( + godot-cpp + VERSION 4.4 + DESCRIPTION "C++ bindings for the Godot Engine's GDExtensions API." + HOMEPAGE_URL "https://github.com/godotengine/godot-cpp" + LANGUAGES CXX +) compiler_detection() godotcpp_generate() # Conditionally enable the godot-cpp.test. integration testing targets -if( GODOTCPP_ENABLE_TESTING ) - add_subdirectory( test ) +if(GODOTCPP_ENABLE_TESTING) + add_subdirectory(test) endif() -# If this is the top level CMakeLists.txt, Generators which honor the -# USE_FOLDERS flag will organize godot-cpp targets under the subfolder -# 'godot-cpp'. This is enable by default from CMake version 3.26 +#[[ If this is the top level CMakeLists.txt, Generators which honor the +USE_FOLDERS flag will organize godot-cpp targets under a subfolder named +'godot-cpp'. This is enable by default from CMake version 3.26 ]] set_property(GLOBAL PROPERTY USE_FOLDERS ON) diff --git a/binding_generator.py b/binding_generator.py index 103214e2..1efc5b4e 100644 --- a/binding_generator.py +++ b/binding_generator.py @@ -290,14 +290,19 @@ def generate_bindings(api_filepath, use_template_get_node, bits="64", precision= api = {} with open(api_filepath, encoding="utf-8") as api_file: api = json.load(api_file) - _generate_bindings(api, use_template_get_node, bits, precision, output_dir) + _generate_bindings(api, api_filepath, use_template_get_node, bits, precision, output_dir) -def _generate_bindings(api, use_template_get_node, bits="64", precision="single", output_dir="."): +def _generate_bindings(api, api_filepath, use_template_get_node, bits="64", precision="single", output_dir="."): + if "precision" in api["header"] and precision != api["header"]["precision"]: + raise Exception( + f"Cannot do a precision={precision} build using '{api_filepath}' which was generated by Godot built with precision={api['header']['precision']}" + ) + target_dir = Path(output_dir) / "gen" shutil.rmtree(target_dir, ignore_errors=True) - target_dir.mkdir(parents=True) + target_dir.mkdir(parents=True, exist_ok=True) real_t = "double" if precision == "double" else "float" print("Built-in type config: " + real_t + "_" + bits) diff --git a/cmake/GodotCPPModule.cmake b/cmake/GodotCPPModule.cmake index ce087468..00e00fe5 100644 --- a/cmake/GodotCPPModule.cmake +++ b/cmake/GodotCPPModule.cmake @@ -26,144 +26,151 @@ The build_profile.py has a __main__ and is used as a tool Its usage is listed as: $ python build_profile.py BUILD_PROFILE INPUT_JSON [OUTPUT_JSON] ]] -function( build_profile_generate_trimmed_api BUILD_PROFILE INPUT_JSON OUTPUT_JSON ) +function(build_profile_generate_trimmed_api BUILD_PROFILE INPUT_JSON OUTPUT_JSON) execute_process( - COMMAND "${Python3_EXECUTABLE}" - "${godot-cpp_SOURCE_DIR}/build_profile.py" - "${BUILD_PROFILE}" - "${INPUT_JSON}" - "${OUTPUT_JSON}" - WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR} + COMMAND + "${Python3_EXECUTABLE}" "${godot-cpp_SOURCE_DIR}/build_profile.py" "${BUILD_PROFILE}" "${INPUT_JSON}" + "${OUTPUT_JSON}" + WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR} ) -endfunction( ) - +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. NOTE: This happens for every configure.]] -function( binding_generator_get_file_list OUT_VAR_NAME API_FILEPATH OUTPUT_DIR ) - +function(binding_generator_get_file_list OUT_VAR_NAME API_FILEPATH OUTPUT_DIR) # This code snippet will be squashed into a single line # The two strings make this a list, in CMake lists are semicolon delimited strings. - set( PYTHON_SCRIPT -"from binding_generator import print_file_list" -"print_file_list( api_filepath='${API_FILEPATH}', + set(PYTHON_SCRIPT + "from binding_generator import print_file_list" + "print_file_list( api_filepath='${API_FILEPATH}', output_dir='${OUTPUT_DIR}', headers=True, - sources=True)") - message( DEBUG "Python:\n${PYTHON_SCRIPT}" ) + sources=True)" + ) + message(DEBUG "Python:\n${PYTHON_SCRIPT}") # Strip newlines and whitespace to make it a one-liner. - string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" ) + string(REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}") - execute_process( COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}" - WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}" - OUTPUT_VARIABLE GENERATED_FILES_LIST - OUTPUT_STRIP_TRAILING_WHITESPACE + execute_process( + COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}" + WORKING_DIRECTORY "${godot-cpp_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} ) + 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") + 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( ) + message(STATUS "There are ${LIST_LENGTH} Files to generate") + set(${OUT_VAR_NAME} ${GENERATED_FILES_LIST} PARENT_SCOPE) +endfunction() #[[ 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. ]] -function( binding_generator_generate_bindings API_FILE USE_TEMPLATE_GET_NODE, BITS, PRECISION, OUTPUT_DIR ) +function( + binding_generator_generate_bindings + API_FILE + USE_TEMPLATE_GET_NODE, + BITS, + PRECISION, + OUTPUT_DIR +) # This code snippet will be squashed into a single line - set( PYTHON_SCRIPT -"from binding_generator import generate_bindings" -"generate_bindings( + set(PYTHON_SCRIPT + "from binding_generator import generate_bindings" + "generate_bindings( api_filepath='${API_FILE}', use_template_get_node='${USE_TEMPLATE_GET_NODE}', bits='${BITS}', precision='${PRECISION}', - output_dir='${OUTPUT_DIR}')") + output_dir='${OUTPUT_DIR}')" + ) - message( DEBUG "Python:\n${PYTHON_SCRIPT}" ) + message(DEBUG "Python:\n${PYTHON_SCRIPT}") # Strip newlines and whitespace to make it a one-liner. - string( REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}" ) + string(REGEX REPLACE "\n *" " " PYTHON_SCRIPT "${PYTHON_SCRIPT}") - add_custom_command(OUTPUT ${GENERATED_FILES_LIST} - COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}" - VERBATIM - WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR} - MAIN_DEPENDENCY ${GODOTCPP_GDEXTENSION_API_FILE} - DEPENDS ${godot-cpp_SOURCE_DIR}/binding_generator.py - COMMENT "Generating bindings" + add_custom_command( + OUTPUT ${GENERATED_FILES_LIST} + COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}" + VERBATIM + WORKING_DIRECTORY ${godot-cpp_SOURCE_DIR} + MAIN_DEPENDENCY ${GODOTCPP_GDEXTENSION_API_FILE} + DEPENDS ${godot-cpp_SOURCE_DIR}/binding_generator.py + COMMENT "Generating bindings" ) -endfunction( ) + add_custom_target(generate_bindings DEPENDS ${GENERATED_FILES_LIST}) + set_target_properties(generate_bindings PROPERTIES FOLDER "godot-cpp") +endfunction() #[[ Generate doc_data.cpp The documentation displayed in the Godot editor is compiled into the extension. It takes a list of XML source files, and transforms them into a cpp file that is added to the sources list.]] -function( generate_doc_source OUTPUT_PATH SOURCES ) +function(generate_doc_source OUTPUT_PATH SOURCES) # Transform SOURCES CMake LIST # quote each path with '' # join with , to transform into a python list minus the surrounding [] - set( PYTHON_LIST "${SOURCES}") - list( TRANSFORM PYTHON_LIST REPLACE "(.*\.xml)" "'\\1'" ) - list( JOIN PYTHON_LIST "," PYTHON_LIST ) + set(PYTHON_LIST "${SOURCES}") + list(TRANSFORM PYTHON_LIST REPLACE "(.*\.xml)" "'\\1'") + list(JOIN PYTHON_LIST "," PYTHON_LIST) get_filename_component(OUTPUT_DIR "${OUTPUT_PATH}" DIRECTORY) - file(MAKE_DIRECTORY ${OUTPUT_DIR} ) + file(MAKE_DIRECTORY ${OUTPUT_DIR}) # Python one-liner to run our command # lists in CMake are just strings delimited by ';', so this works. - set( PYTHON_SCRIPT "from doc_source_generator import generate_doc_source" - "generate_doc_source( '${OUTPUT_PATH}', [${PYTHON_LIST}] )" ) + set(PYTHON_SCRIPT + "from doc_source_generator import generate_doc_source" + "generate_doc_source( '${OUTPUT_PATH}', [${PYTHON_LIST}] )" + ) - add_custom_command( OUTPUT "${OUTPUT_PATH}" - COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}" - VERBATIM - WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}" - DEPENDS + add_custom_command( + OUTPUT "${OUTPUT_PATH}" + COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}" + VERBATIM + WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}" + DEPENDS # "${godot-cpp_SOURCE_DIR}/doc_source_generator.py" "${SOURCES}" - COMMENT "Generating: ${OUTPUT_PATH}" + COMMENT "Generating: ${OUTPUT_PATH}" ) + add_custom_target(generate_doc_source DEPENDS "${OUTPUT_PATH}") + set_target_properties(generate_doc_source PROPERTIES FOLDER "godot-cpp") endfunction() #[[ target_doc_sources A simpler interface to add xml files as doc source to a output target. TARGET: The gdexension library target -SOURCES: a list of xml files to use for source generation and inclusion. -This function also adds a doc_gen target to test source generation.]] -function( target_doc_sources TARGET SOURCES ) +SOURCES: a list of xml files to use for source generation and inclusion.]] +function(target_doc_sources TARGET SOURCES) # set the generated file name - set( DOC_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/gen/doc_source.cpp" ) + set(DOC_SOURCE_FILE "${CMAKE_CURRENT_BINARY_DIR}/gen/doc_source.cpp") # Create the file generation target, this won't be triggered unless a target # that depends on DOC_SOURCE_FILE is built generate_doc_source( "${DOC_SOURCE_FILE}" ${SOURCES} ) # Add DOC_SOURCE_FILE as a dependency to TARGET - target_sources( ${TARGET} PRIVATE "${DOC_SOURCE_FILE}" ) + target_sources(${TARGET} PRIVATE "${DOC_SOURCE_FILE}") - # Create a dummy target that depends on the source so that users can - # test the file generation task. - if( TARGET doc_gen ) - else() - add_custom_target( doc_gen ) - endif() - target_sources( doc_gen PRIVATE "${DOC_SOURCE_FILE}" ) + # Without adding this dependency to the doc_source_generator, XCode will complain. + add_dependencies(${TARGET} generate_doc_source) endfunction() diff --git a/cmake/android.cmake b/cmake/android.cmake index d3d95ee5..1d3a93b6 100644 --- a/cmake/android.cmake +++ b/cmake/android.cmake @@ -25,16 +25,25 @@ Android platforms. There is further information and examples in the doc/cmake.rst file. ]=======================================================================] -function( android_options ) - # Android Options + +#[============================[ Android Options ]============================] +function(android_options) + #[[ Options from SCons + + The options below are managed by CMake toolchain files, doc.cmake.rst has + more information + + android_api_level : Target Android API level. + Default = 21 + + ANDROID_HOME : Path to your Android SDK installation. + Default = os.environ.get("ANDROID_HOME", os.environ.get("ANDROID_SDK_ROOT") + ]] endfunction() -function( android_generate ) - target_compile_definitions(${TARGET_NAME} - PUBLIC - ANDROID_ENABLED - UNIX_ENABLED - ) +#[===========================[ Target Generation ]===========================] +function(android_generate) + target_compile_definitions(godot-cpp PUBLIC ANDROID_ENABLED UNIX_ENABLED) common_compiler_flags() endfunction() diff --git a/cmake/common_compiler_flags.cmake b/cmake/common_compiler_flags.cmake index 5a23c012..8a4d836f 100644 --- a/cmake/common_compiler_flags.cmake +++ b/cmake/common_compiler_flags.cmake @@ -7,24 +7,35 @@ configuration. It includes flags like optimization levels, warnings, and features. For target platform specific flags look to each of the ``cmake/.cmake`` files. +The default compile and link options CMake adds can be found in the +platform modules_. When a project is created it initializes its variables from +the ``CMAKE_*`` values. The cleanest way I have found to alter these defaults +is the use of the ``CMAKE_PROJECT__INCLUDE`` as demonstrated by +the emsdkHack.cmake to overcome the limitation on shared library creation. + +So far the emsdkHack is the only modification to the defaults we have made. + +.. _modules: https://github.com/Kitware/CMake/blob/master/Modules/Platform/ + ]=======================================================================] #[[ Compiler Configuration, not to be confused with build targets ]] -set( DEBUG_SYMBOLS "$,$>" ) +set(DEBUG_SYMBOLS "$,$>") #[[ Compiler Identification ]] -set( IS_CLANG "$" ) -set( IS_APPLECLANG "$" ) -set( IS_GNU "$" ) -set( IS_MSVC "$" ) -set( NOT_MSVC "$>" ) +set(IS_CLANG "$") +set(IS_APPLECLANG "$") +set(IS_GNU "$") +set(IS_MSVC "$") +set(NOT_MSVC "$>") -set( GNU_LT_V8 "$,8>" ) -set( GNU_GE_V9 "$,9>" ) -set( GNU_GT_V11 "$,11>" ) -set( GNU_LT_V11 "$,11>" ) -set( GNU_GE_V12 "$,12>" ) +set(LT_V8 "$,8>") +set(GE_V9 "$,9>") +set(GT_V11 "$,11>") +set(LT_V11 "$,11>") +set(GE_V12 "$,12>") +#[===========================[ compiler_detection ]===========================] #[[ Check for clang-cl with MSVC frontend The compiler is tested and set when the project command is called. The variable CXX_COMPILER_FRONTEND_VARIANT was introduced in 3.14 @@ -33,32 +44,31 @@ until CMake 3.30 so we can't use it yet. So to support clang downloaded from llvm.org which uses the MSVC frontend by default, we need to test for it. ]] -function( compiler_detection ) - if( ${CMAKE_CXX_COMPILER_ID} STREQUAL Clang ) - if( ${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} STREQUAL MSVC ) - message( "Using clang-cl" ) - set( IS_CLANG "0" PARENT_SCOPE ) - set( IS_MSVC "1" PARENT_SCOPE ) - set( NOT_MSVC "0" PARENT_SCOPE ) - endif () - endif () -endfunction( ) - -function( common_compiler_flags ) - - target_compile_features(${TARGET_NAME} - PUBLIC - cxx_std_17 - ) +function(compiler_detection) + if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang) + if(${CMAKE_CXX_COMPILER_FRONTEND_VARIANT} STREQUAL MSVC) + message("Using clang-cl") + set(IS_CLANG "0" PARENT_SCOPE) + set(IS_MSVC "1" PARENT_SCOPE) + set(NOT_MSVC "0" PARENT_SCOPE) + endif() + endif() +endfunction() +#[=========================[ common_compiler_flags ]=========================] +#[[ This function assumes it is being called from within one of the platform +generate functions, with all the variables from lower scopes defined. ]] +function(common_compiler_flags) + # gersemi: off # These compiler options reflect what is in godot/SConstruct. - target_compile_options( ${TARGET_NAME} + target_compile_options( + godot-cpp + # The public flag tells CMake that the following options are transient, + # and will propagate to consumers. PUBLIC # Disable exception handling. Godot doesn't use exceptions anywhere, and this # saves around 20% of binary size and very significant build time. - $<${DISABLE_EXCEPTIONS}: - $<${NOT_MSVC}:-fno-exceptions> - > + $<${DISABLE_EXCEPTIONS}:$<${NOT_MSVC}:-fno-exceptions>> # Enabling Debug Symbols $<${DEBUG_SYMBOLS}: @@ -70,78 +80,81 @@ function( common_compiler_flags ) > > - $<${IS_DEV_BUILD}: - $<${NOT_MSVC}:-fno-omit-frame-pointer -O0> + $<${IS_DEV_BUILD}:$<${NOT_MSVC}:-fno-omit-frame-pointer -O0>> + + $<${HOT_RELOAD}:$<${IS_GNU}:-fno-gnu-unique>> + + # MSVC only + $<${IS_MSVC}: + # /MP isn't valid for clang-cl with msvc frontend + $<$:/MP${PROC_N}> + + # Interpret source files as utf-8 + /utf-8 > - $<${HOT_RELOAD}: - $<${IS_GNU}:-fno-gnu-unique> + # Warnings below, these do not need to propagate to consumers. + PRIVATE + $<${IS_MSVC}: + /W4 # Warning level 4 (informational) warnings that aren't off by default. + + # Disable warnings which we don't plan to fix. + /wd4100 # C4100 (unreferenced formal parameter): Doesn't play nice with polymorphism. + /wd4127 # C4127 (conditional expression is constant) + /wd4201 # C4201 (non-standard nameless struct/union): Only relevant for C89. + /wd4244 # C4244 C4245 C4267 (narrowing conversions): Unavoidable at this scale. + /wd4245 + /wd4267 + /wd4305 # C4305 (truncation): double to float or real_t, too hard to avoid. + /wd4514 # C4514 (unreferenced inline function has been removed) + /wd4714 # C4714 (function marked as __forceinline not inlined) + /wd4820 # C4820 (padding added after construct) > - # MSVC only - $<${IS_MSVC}: - # /MP isn't valid for clang-cl with msvc frontend - $<$:/MP${PROC_N}> - /W4 + # Clang and GNU common options + $<$: + -Wall + -Wctor-dtor-privacy + -Wextra + -Wno-unused-parameter + -Wnon-virtual-dtor + -Wwrite-strings + > - # Disable warnings which we don't plan to fix. - /wd4100 # C4100 (unreferenced formal parameter): Doesn't play nice with polymorphism. - /wd4127 # C4127 (conditional expression is constant) - /wd4201 # C4201 (non-standard nameless struct/union): Only relevant for C89. - /wd4244 # C4244 C4245 C4267 (narrowing conversions): Unavoidable at this scale. - /wd4245 - /wd4267 - /wd4305 # C4305 (truncation): double to float or real_t, too hard to avoid. - /wd4514 # C4514 (unreferenced inline function has been removed) - /wd4714 # C4714 (function marked as __forceinline not inlined) - /wd4820 # C4820 (padding added after construct) + # Clang only + $<${IS_CLANG}: + -Wimplicit-fallthrough + -Wno-ordered-compare-function-pointers + > - /utf-8 - > + # GNU only + $<${IS_GNU}: + -Walloc-zero + -Wduplicated-branches + -Wduplicated-cond + -Wno-misleading-indentation + -Wplacement-new=1 + -Wshadow-local + -Wstringop-overflow=4 - # Clang and GNU common options - $<$: - -Wall - -Wctor-dtor-privacy - -Wextra - -Wno-unused-parameter - -Wnon-virtual-dtor - -Wwrite-strings - > + # Bogus warning fixed in 8+. + $<${LT_V8}:-Wno-strict-overflow> - # Clang only - $<${IS_CLANG}: - -Wimplicit-fallthrough - -Wno-ordered-compare-function-pointers - > + $<${GE_V9}:-Wattribute-alias=2> - # GNU only - $<${IS_GNU}: - -Walloc-zero - -Wduplicated-branches - -Wduplicated-cond - -Wno-misleading-indentation - -Wplacement-new=1 - -Wshadow-local - -Wstringop-overflow=4 + # Broke on MethodBind templates before GCC 11. + $<${GT_V11}:-Wlogical-op> - # Bogus warning fixed in 8+. - $<${GNU_LT_V8}:-Wno-strict-overflow> + # Regression in GCC 9/10, spams so much in our variadic templates that we need to outright disable it. + $<${LT_V11}:-Wno-type-limits> - $<${GNU_GE_V9}:-Wattribute-alias=2> - - # Broke on MethodBind templates before GCC 11. - $<${GNU_GT_V11}:-Wlogical-op> - - # Regression in GCC 9/10, spams so much in our variadic templates that we need to outright disable it. - $<${GNU_LT_V11}:-Wno-type-limits> - - # False positives in our error macros, see GH-58747. - $<${GNU_GE_V12}:-Wno-return-type> - > + # False positives in our error macros, see GH-58747. + $<${GE_V12}:-Wno-return-type> + > ) - target_compile_definitions(${TARGET_NAME} + target_compile_definitions( + godot-cpp PUBLIC GDEXTENSION @@ -159,19 +172,21 @@ function( common_compiler_flags ) $<${THREADS_ENABLED}:THREADS_ENABLED> ) - target_link_options( ${TARGET_NAME} + target_link_options( + godot-cpp PUBLIC - $<${IS_MSVC}: - /WX # treat link warnings as errors. - /MANIFEST:NO # We dont need a manifest - > - $<${DEBUG_SYMBOLS}:$<${IS_MSVC}:/DEBUG:FULL>> + $<$: $<${IS_GNU}:-s> $<${IS_CLANG}:-s> $<${IS_APPLECLANG}:-Wl,-S -Wl,-x -Wl,-dead_strip> > + PRIVATE + $<${IS_MSVC}: + /WX # treat link warnings as errors. + /MANIFEST:NO # We dont need a manifest + > ) - + # gersemi: on endfunction() diff --git a/cmake/emsdkHack.cmake b/cmake/emsdkHack.cmake index 6981a379..c5ccc6fc 100644 --- a/cmake/emsdkHack.cmake +++ b/cmake/emsdkHack.cmake @@ -23,18 +23,18 @@ More information on cmake's `code injection`_ Overwrite Shared Library Properties to allow shared libs to be generated. ]=======================================================================] -if( EMSCRIPTEN ) +if(EMSCRIPTEN) set_property(GLOBAL PROPERTY TARGET_SUPPORTS_SHARED_LIBS TRUE) set(CMAKE_SHARED_LIBRARY_CREATE_C_FLAGS "-sSIDE_MODULE=1") set(CMAKE_SHARED_LIBRARY_CREATE_CXX_FLAGS "-sSIDE_MODULE=1") set(CMAKE_SHARED_LIBRARY_SUFFIX) # remove the suffix from the shared lib - set(CMAKE_STRIP FALSE) # used by default in pybind11 on .so modules + set(CMAKE_STRIP FALSE) # used by default in pybind11 on .so modules # The Emscripten toolchain sets the default value for EMSCRIPTEN_SYSTEM_PROCESSOR to x86 - # and CMAKE_SYSTEM_PROCESSOR to this value. I don't want that. - set(CMAKE_SYSTEM_PROCESSOR "wasm32" ) + # and copies that to CMAKE_SYSTEM_PROCESSOR. We don't want that. + set(CMAKE_SYSTEM_PROCESSOR "wasm32") # the above prevents the need for logic like: #if( ${CMAKE_SYSTEM_NAME} STREQUAL Emscripten ) # set( SYSTEM_ARCH wasm32 ) #endif () -endif () +endif() diff --git a/cmake/godotcpp.cmake b/cmake/godotcpp.cmake index c10d835d..8ae938bf 100644 --- a/cmake/godotcpp.cmake +++ b/cmake/godotcpp.cmake @@ -8,140 +8,154 @@ C compiler is specified, like in a toolchain, or from an IDE, then it will print a warning stating that the CMAKE_C_COMPILER compiler is unused. This if statement simply silences that warning. ]=======================================================================] -if( CMAKE_C_COMPILER ) -endif () +if(CMAKE_C_COMPILER) +endif() -#[=======================================================================[.rst: -Include Platform Files ----------------------- - -Because these files are included into the top level CMakelists.txt before the +#[[ Include Platform Files +Because these files are included into the top level CMakeLists.txt before the project directive, it means that -* ``CMAKE_CURRENT_SOURCE_DIR`` is the location of godot-cpp's CMakeLists.txt -* ``CMAKE_SOURCE_DIR`` is the location where any prior ``project(...)`` - directive was - -]=======================================================================] -include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/GodotCPPModule.cmake) -include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/common_compiler_flags.cmake) -include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/android.cmake) -include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ios.cmake) -include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux.cmake) -include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos.cmake) -include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/web.cmake) -include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows.cmake) - +CMAKE_CURRENT_SOURCE_DIR is the location of godot-cpp's CMakeLists.txt +CMAKE_SOURCE_DIR is the location where any prior project() directive was ]] +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/GodotCPPModule.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/common_compiler_flags.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/android.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/ios.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/linux.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/macos.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/web.cmake) +include(${CMAKE_CURRENT_SOURCE_DIR}/cmake/windows.cmake) # Detect number of processors include(ProcessorCount) ProcessorCount(PROC_MAX) -message( "Auto-detected ${PROC_MAX} CPU cores available for build parallelism." ) +message("Auto-detected ${PROC_MAX} CPU cores available for build parallelism.") # List of known platforms -set( PLATFORM_LIST linux macos windows android ios web ) +set(PLATFORM_LIST + linux + macos + windows + android + ios + web +) # List of known architectures -set( ARCH_LIST x86_32 x86_64 arm32 arm64 rv64 ppc32 ppc64 wasm32 ) - -# Function to map processors to known architectures -function( godot_arch_name OUTVAR ) +set(ARCH_LIST + x86_32 + x86_64 + arm32 + arm64 + rv64 + ppc32 + ppc64 + wasm32 +) +#[=============================[ godot_arch_name ]=============================] +#[[ Function to map CMAKE_SYSTEM_PROCESSOR names to godot arch equivalents ]] +function(godot_arch_name OUTVAR) # Special case for macos universal builds that target both x86_64 and arm64 - if( DEFINED CMAKE_OSX_ARCHITECTURES) - if( "x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES AND "arm64" IN_LIST CMAKE_OSX_ARCHITECTURES) - set(${OUTVAR} "universal" PARENT_SCOPE ) + if(DEFINED CMAKE_OSX_ARCHITECTURES) + if("x86_64" IN_LIST CMAKE_OSX_ARCHITECTURES AND "arm64" IN_LIST CMAKE_OSX_ARCHITECTURES) + set(${OUTVAR} "universal" PARENT_SCOPE) return() endif() endif() # Direct match early out. - string( TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCH ) - if( ARCH IN_LIST ARCH_LIST ) - set( ${OUTVAR} "${ARCH}" PARENT_SCOPE) + string(TOLOWER "${CMAKE_SYSTEM_PROCESSOR}" ARCH) + if(ARCH IN_LIST ARCH_LIST) + set(${OUTVAR} "${ARCH}" PARENT_SCOPE) return() endif() # Known aliases - set( x86_64 "w64;amd64;x86-64" ) - set( arm32 "armv7;armv7-a" ) - set( arm64 "armv8;arm64v8;aarch64;armv8-a" ) - set( rv64 "rv;riscv;riscv64" ) - set( ppc32 "ppcle;ppc" ) - set( ppc64 "ppc64le" ) + set(x86_64 "w64;amd64;x86-64") + set(arm32 "armv7;armv7-a") + set(arm64 "armv8;arm64v8;aarch64;armv8-a") + set(rv64 "rv;riscv;riscv64") + set(ppc32 "ppcle;ppc") + set(ppc64 "ppc64le") - if( ARCH IN_LIST x86_64 ) - set(${OUTVAR} "x86_64" PARENT_SCOPE ) - - elseif( ARCH IN_LIST arm32 ) - set(${OUTVAR} "arm32" PARENT_SCOPE ) - - elseif( ARCH IN_LIST arm64 ) - set(${OUTVAR} "arm64" PARENT_SCOPE ) - - elseif( ARCH IN_LIST rv64 ) - set(${OUTVAR} "rv64" PARENT_SCOPE ) - - elseif( ARCH IN_LIST ppc32 ) - set(${OUTVAR} "ppc32" PARENT_SCOPE ) - - elseif( ARCH IN_LIST ppc64 ) - set(${OUTVAR} "ppc64" PARENT_SCOPE ) - - elseif( ARCH MATCHES "86") + if(ARCH IN_LIST x86_64) + set(${OUTVAR} "x86_64" PARENT_SCOPE) + elseif(ARCH IN_LIST arm32) + set(${OUTVAR} "arm32" PARENT_SCOPE) + elseif(ARCH IN_LIST arm64) + set(${OUTVAR} "arm64" PARENT_SCOPE) + elseif(ARCH IN_LIST rv64) + set(${OUTVAR} "rv64" PARENT_SCOPE) + elseif(ARCH IN_LIST ppc32) + set(${OUTVAR} "ppc32" PARENT_SCOPE) + elseif(ARCH IN_LIST ppc64) + set(${OUTVAR} "ppc64" PARENT_SCOPE) + elseif(ARCH MATCHES "86") # Catches x86, i386, i486, i586, i686, etc. - set(${OUTVAR} "x86_32" PARENT_SCOPE ) - + set(${OUTVAR} "x86_32" PARENT_SCOPE) else() # Default value is whatever the processor is. - set(${OUTVAR} ${CMAKE_SYSTEM_PROCESSOR} PARENT_SCOPE ) - endif () + set(${OUTVAR} ${CMAKE_SYSTEM_PROCESSOR} PARENT_SCOPE) + endif() endfunction() # Function to define all the options. -function( godotcpp_options ) +function(godotcpp_options) #NOTE: platform is managed using toolchain files. #NOTE: arch is managed by using toolchain files. - # Except for macos universal, which can be set by GODOTCPP_MACOS_UNIVERSAL=YES + # To create a universal build for macos, set CMAKE_OSX_ARCHITECTURES + + set(GODOTCPP_TARGET + "template_debug" + CACHE STRING + "Which target to generate. valid values are: template_debug, template_release, and editor" + ) + set_property(CACHE GODOTCPP_TARGET PROPERTY STRINGS "template_debug;template_release;editor") # Input from user for GDExtension interface header and the API JSON file - set( GODOTCPP_GDEXTENSION_DIR "gdextension" CACHE PATH - "Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )" ) - set( GODOTCPP_CUSTOM_API_FILE "" CACHE FILEPATH - "Path to a custom GDExtension API JSON file (takes precedence over `GODOTCPP_GDEXTENSION_DIR`) ( /path/to/custom_api_file )") + set(GODOTCPP_GDEXTENSION_DIR + "gdextension" + CACHE PATH + "Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir )" + ) + set(GODOTCPP_CUSTOM_API_FILE + "" + CACHE FILEPATH + "Path to a custom GDExtension API JSON file (takes precedence over `GODOTCPP_GDEXTENSION_DIR`) ( /path/to/custom_api_file )" + ) #TODO generate_bindings - option( GODOTCPP_GENERATE_TEMPLATE_GET_NODE - "Generate a template version of the Node class's get_node. (ON|OFF)" ON) + option(GODOTCPP_GENERATE_TEMPLATE_GET_NODE "Generate a template version of the Node class's get_node. (ON|OFF)" ON) #TODO build_library - set( GODOTCPP_PRECISION "single" CACHE STRING - "Set the floating-point precision level (single|double)") + set(GODOTCPP_PRECISION "single" CACHE STRING "Set the floating-point precision level (single|double)") - set( GODOTCPP_THREADS ON CACHE BOOL "Enable threading support" ) + set(GODOTCPP_THREADS ON CACHE BOOL "Enable threading support") #TODO compiledb #TODO compiledb_file - set( GODOTCPP_BUILD_PROFILE "" CACHE PATH - "Path to a file containing a feature build profile" ) + set(GODOTCPP_BUILD_PROFILE "" CACHE PATH "Path to a file containing a feature build profile") - set( GODOTCPP_USE_HOT_RELOAD "" CACHE BOOL - "Enable the extra accounting required to support hot reload. (ON|OFF)") + set(GODOTCPP_USE_HOT_RELOAD "" CACHE BOOL "Enable the extra accounting required to support hot reload. (ON|OFF)") # Disable exception handling. Godot doesn't use exceptions anywhere, and this # saves around 20% of binary size and very significant build time (GH-80513). - option( GODOTCPP_DISABLE_EXCEPTIONS "Force disabling exception handling code (ON|OFF)" ON ) + option(GODOTCPP_DISABLE_EXCEPTIONS "Force disabling exception handling code (ON|OFF)" ON) - set( GODOTCPP_SYMBOL_VISIBILITY "hidden" CACHE STRING - "Symbols visibility on GNU platforms. Use 'auto' to apply the default value. (auto|visible|hidden)") - set_property( CACHE GODOTCPP_SYMBOL_VISIBILITY PROPERTY STRINGS "auto;visible;hidden" ) + set(GODOTCPP_SYMBOL_VISIBILITY + "hidden" + CACHE STRING + "Symbols visibility on GNU platforms. Use 'auto' to apply the default value. (auto|visible|hidden)" + ) + set_property(CACHE GODOTCPP_SYMBOL_VISIBILITY PROPERTY STRINGS "auto;visible;hidden") #TODO optimize - option( GODOTCPP_DEV_BUILD "Developer build with dev-only debugging code (DEV_ENABLED)" OFF ) + option(GODOTCPP_DEV_BUILD "Developer build with dev-only debugging code (DEV_ENABLED)" OFF) #[[ debug_symbols Debug symbols are enabled by using the Debug or RelWithDebInfo build configurations. @@ -156,11 +170,11 @@ function( godotcpp_options ) ]] # FIXME These options are not present in SCons, and perhaps should be added there. - option( GODOTCPP_SYSTEM_HEADERS "Expose headers as SYSTEM." OFF ) - option( GODOTCPP_WARNING_AS_ERROR "Treat warnings as errors" OFF ) + option(GODOTCPP_SYSTEM_HEADERS "Expose headers as SYSTEM." OFF) + option(GODOTCPP_WARNING_AS_ERROR "Treat warnings as errors" OFF) # Enable Testing - option( GODOTCPP_ENABLE_TESTING "Enable the godot-cpp.test. integration testing targets" OFF ) + option(GODOTCPP_ENABLE_TESTING "Enable the godot-cpp.test. integration testing targets" OFF) #[[ Target Platform Options ]] android_options() @@ -171,8 +185,8 @@ function( godotcpp_options ) windows_options() endfunction() -# Function to configure and generate the targets -function( godotcpp_generate ) +#[===========================[ Target Generation ]===========================] +function(godotcpp_generate) #[[ Multi-Threaded MSVC Compilation When using the MSVC compiler the build command -j only specifies parallel jobs or targets, and not multi-threaded compilation To speed up @@ -181,16 +195,18 @@ function( godotcpp_generate ) MSVC is true when the compiler is some version of Microsoft Visual C++ or another compiler simulating the Visual C++ cl command-line syntax. ]] - if( MSVC ) - math( EXPR PROC_N "(${PROC_MAX}-1) | (${X}-2)>>31 & 1" ) - message( "Using ${PROC_N} cores for multi-threaded compilation.") + if(MSVC) + math(EXPR PROC_N "(${PROC_MAX}-1) | (${X}-2)>>31 & 1") + message("Using ${PROC_N} cores for multi-threaded compilation.") # TODO You can override it at configure time with ...." ) - else () - message( "Using ${CMAKE_BUILD_PARALLEL_LEVEL} cores, You can override" - " it at configure time by using -j or --parallel on the build" - " command.") - message( " eg. cmake --build . -j 7 ...") - endif () + else() + message( + "Using ${CMAKE_BUILD_PARALLEL_LEVEL} cores, You can override" + " it at configure time by using -j or --parallel on the build" + " command." + ) + message(" eg. cmake --build . -j 7 ...") + endif() #[[ GODOTCPP_SYMBOL_VISIBLITY To match the SCons options, the allowed values are "auto", "visible", and "hidden" @@ -200,174 +216,175 @@ function( godotcpp_generate ) TODO: It is probably worth a pull request which changes both to use the compiler values .. _flag:https://gcc.gnu.org/onlinedocs/gcc/Code-Gen-Options.html#index-fvisibility ]] - if( ${GODOTCPP_SYMBOL_VISIBILITY} STREQUAL "auto" OR ${GODOTCPP_SYMBOL_VISIBILITY} STREQUAL "visible" ) - set( GODOTCPP_SYMBOL_VISIBILITY "default" ) - endif () + if(${GODOTCPP_SYMBOL_VISIBILITY} STREQUAL "auto" OR ${GODOTCPP_SYMBOL_VISIBILITY} STREQUAL "visible") + set(GODOTCPP_SYMBOL_VISIBILITY "default") + endif() # Setup variable to optionally mark headers as SYSTEM - set( GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE "") - if( GODOTCPP_SYSTEM_HEADERS) - set( GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE SYSTEM) - endif () + set(GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE "") + if(GODOTCPP_SYSTEM_HEADERS) + set(GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE SYSTEM) + endif() #[[ Configure Binding Variables ]] # Generate Binding Parameters (True|False) - set( USE_TEMPLATE_GET_NODE "False" ) - if( GODOTCPP_GENERATE_TEMPLATE_GET_NODE ) - set( USE_TEMPLATE_GET_NODE "True" ) + set(USE_TEMPLATE_GET_NODE "False") + if(GODOTCPP_GENERATE_TEMPLATE_GET_NODE) + set(USE_TEMPLATE_GET_NODE "True") endif() # Bits (32|64) - math( EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8" ) # CMAKE_SIZEOF_VOID_P refers to target architecture. + math(EXPR BITS "${CMAKE_SIZEOF_VOID_P} * 8") # CMAKE_SIZEOF_VOID_P refers to target architecture. # API json File - set( GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_GDEXTENSION_DIR}/extension_api.json") - if( GODOTCPP_CUSTOM_API_FILE ) # User-defined override. - set( GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_CUSTOM_API_FILE}") + set(GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_GDEXTENSION_DIR}/extension_api.json") + if(GODOTCPP_CUSTOM_API_FILE) # User-defined override. + set(GODOTCPP_GDEXTENSION_API_FILE "${GODOTCPP_CUSTOM_API_FILE}") endif() # Build Profile - if( GODOTCPP_BUILD_PROFILE ) - message( STATUS "Using build profile to trim api file") - message( "\tBUILD_PROFILE = '${GODOTCPP_BUILD_PROFILE}'") - message( "\tAPI_SOURCE = '${GODOTCPP_GDEXTENSION_API_FILE}'") + if(GODOTCPP_BUILD_PROFILE) + message(STATUS "Using build profile to trim api file") + message("\tBUILD_PROFILE = '${GODOTCPP_BUILD_PROFILE}'") + message("\tAPI_SOURCE = '${GODOTCPP_GDEXTENSION_API_FILE}'") build_profile_generate_trimmed_api( "${GODOTCPP_BUILD_PROFILE}" "${GODOTCPP_GDEXTENSION_API_FILE}" - "${CMAKE_CURRENT_BINARY_DIR}/extension_api.json" ) - set( GODOTCPP_GDEXTENSION_API_FILE "${CMAKE_CURRENT_BINARY_DIR}/extension_api.json" ) + "${CMAKE_CURRENT_BINARY_DIR}/extension_api.json" + ) + set(GODOTCPP_GDEXTENSION_API_FILE "${CMAKE_CURRENT_BINARY_DIR}/extension_api.json") endif() - message( STATUS "GODOTCPP_GDEXTENSION_API_FILE = '${GODOTCPP_GDEXTENSION_API_FILE}'") + message(STATUS "GODOTCPP_GDEXTENSION_API_FILE = '${GODOTCPP_GDEXTENSION_API_FILE}'") # generate the file list to use binding_generator_get_file_list( GENERATED_FILES_LIST "${GODOTCPP_GDEXTENSION_API_FILE}" - "${CMAKE_CURRENT_BINARY_DIR}" ) + "${CMAKE_CURRENT_BINARY_DIR}" + ) binding_generator_generate_bindings( "${GODOTCPP_GDEXTENSION_API_FILE}" "${USE_TEMPLATE_GET_NODE}" "${BITS}" "${GODOTCPP_PRECISION}" - "${CMAKE_CURRENT_BINARY_DIR}" ) - - add_custom_target( godot-cpp.generate_bindings DEPENDS ${GENERATED_FILES_LIST} ) - set_target_properties( godot-cpp.generate_bindings PROPERTIES FOLDER "godot-cpp" ) + "${CMAKE_CURRENT_BINARY_DIR}" + ) ### Platform is derived from the toolchain target # See GeneratorExpressions PLATFORM_ID and CMAKE_SYSTEM_NAME - string( CONCAT SYSTEM_NAME - "$<$:android.${ANDROID_ABI}>" - "$<$:ios>" - "$<$:linux>" - "$<$:macos>" - "$<$:web>" - "$<$:windows>" - "$<$:windows>" + string( + CONCAT + SYSTEM_NAME + "$<$:android.${ANDROID_ABI}>" + "$<$:ios>" + "$<$:linux>" + "$<$:macos>" + "$<$:web>" + "$<$:windows>" + "$<$:windows>" ) # Process CPU architecture argument. godot_arch_name( ARCH_NAME ) # Transform options into generator expressions - set( HOT_RELOAD-UNSET "$") + set(HOT_RELOAD-UNSET "$") - set( DISABLE_EXCEPTIONS "$") + set(DISABLE_EXCEPTIONS "$") - set( THREADS_ENABLED "$" ) + set(THREADS_ENABLED "$") # GODOTCPP_DEV_BUILD - set( RELEASE_TYPES "Release;MinSizeRel") - get_property( IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG ) - if( IS_MULTI_CONFIG ) - message( NOTICE "=> Default build type is Debug. For other build types add --config to build command") - elseif( GODOTCPP_DEV_BUILD AND CMAKE_BUILD_TYPE IN_LIST RELEASE_TYPES ) - message( WARNING "=> GODOTCPP_DEV_BUILD implies a Debug-like build but CMAKE_BUILD_TYPE is '${CMAKE_BUILD_TYPE}'") - endif () - set( IS_DEV_BUILD "$") + set(RELEASE_TYPES "Release;MinSizeRel") + get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) + if(IS_MULTI_CONFIG) + message(NOTICE "=> Default build type is Debug. For other build types add --config to build command") + elseif(GODOTCPP_DEV_BUILD AND CMAKE_BUILD_TYPE IN_LIST RELEASE_TYPES) + message( + WARNING + "=> GODOTCPP_DEV_BUILD implies a Debug-like build but CMAKE_BUILD_TYPE is '${CMAKE_BUILD_TYPE}'" + ) + endif() + set(IS_DEV_BUILD "$") ### Define our godot-cpp library targets - foreach ( TARGET_ALIAS template_debug template_release editor ) - set( TARGET_NAME "godot-cpp.${TARGET_ALIAS}" ) + # Generator Expressions that rely on the target + set(DEBUG_FEATURES "$>") + set(HOT_RELOAD "$>") - # Generator Expressions that rely on the target - set( DEBUG_FEATURES "$>" ) - set( HOT_RELOAD "$>" ) + # Suffix + string( + CONCAT + GODOTCPP_SUFFIX + "$<1:.${SYSTEM_NAME}>" + "$<1:.${GODOTCPP_TARGET}>" + "$<${IS_DEV_BUILD}:.dev>" + "$<$:.double>" + "$<1:.${ARCH_NAME}>" + # TODO IOS_SIMULATOR + "$<$:.nothreads>" + ) - # Suffix - string( CONCAT GODOTCPP_SUFFIX - "$<1:.${SYSTEM_NAME}>" - "$<1:.${TARGET_ALIAS}>" - "$<${IS_DEV_BUILD}:.dev>" - "$<$:.double>" - "$<1:.${ARCH_NAME}>" - # TODO IOS_SIMULATOR - "$<$:.nothreads>" - ) + # the godot-cpp.* library targets + add_library(godot-cpp STATIC) - # the godot-cpp.* library targets - add_library( ${TARGET_NAME} STATIC EXCLUDE_FROM_ALL ) - add_library( godot-cpp::${TARGET_ALIAS} ALIAS ${TARGET_NAME} ) - - file( GLOB_RECURSE GODOTCPP_SOURCES LIST_DIRECTORIES NO CONFIGURE_DEPENDS src/*.cpp ) - - target_sources( ${TARGET_NAME} - PRIVATE - ${GODOTCPP_SOURCES} - ${GENERATED_FILES_LIST} - ) - - target_include_directories( ${TARGET_NAME} ${GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC - include - ${CMAKE_CURRENT_BINARY_DIR}/gen/include - ${GODOTCPP_GDEXTENSION_DIR} - ) - - set_target_properties( ${TARGET_NAME} - PROPERTIES - CXX_STANDARD 17 - CXX_EXTENSIONS OFF - CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY} - - COMPILE_WARNING_AS_ERROR ${GODOTCPP_WARNING_AS_ERROR} - POSITION_INDEPENDENT_CODE ON - BUILD_RPATH_USE_ORIGIN ON - - PREFIX "lib" - OUTPUT_NAME "${PROJECT_NAME}${GODOTCPP_SUFFIX}" - - ARCHIVE_OUTPUT_DIRECTORY "$<1:${CMAKE_BINARY_DIR}/bin>" - - # Things that are handy to know for dependent targets - GODOTCPP_PLATFORM "${SYSTEM_NAME}" - GODOTCPP_TARGET "${TARGET_ALIAS}" - GODOTCPP_ARCH "${ARCH_NAME}" - GODOTCPP_PRECISION "${GODOTCPP_PRECISION}" - GODOTCPP_SUFFIX "${GODOTCPP_SUFFIX}" - - # Some IDE's respect this property to logically group targets - FOLDER "godot-cpp" - ) - - if( CMAKE_SYSTEM_NAME STREQUAL Android ) - android_generate() - elseif ( CMAKE_SYSTEM_NAME STREQUAL iOS ) - ios_generate() - elseif ( CMAKE_SYSTEM_NAME STREQUAL Linux ) - linux_generate() - elseif ( CMAKE_SYSTEM_NAME STREQUAL Darwin ) - macos_generate() - elseif ( CMAKE_SYSTEM_NAME STREQUAL Emscripten ) - web_generate() - elseif ( CMAKE_SYSTEM_NAME STREQUAL Windows ) - windows_generate() - endif () - - endforeach () + # Without adding this dependency to the binding generator, XCode will complain. + add_dependencies(godot-cpp generate_bindings) # Added for backwards compatibility with prior cmake solution so that builds dont immediately break # from a missing target. - add_library( godot::cpp ALIAS godot-cpp.template_debug ) + add_library(godot::cpp ALIAS godot-cpp) + file(GLOB_RECURSE GODOTCPP_SOURCES LIST_DIRECTORIES NO CONFIGURE_DEPENDS src/*.cpp) + + target_sources(godot-cpp PRIVATE ${GODOTCPP_SOURCES} ${GENERATED_FILES_LIST}) + + target_include_directories( + godot-cpp + ${GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE} + PUBLIC include ${CMAKE_CURRENT_BINARY_DIR}/gen/include ${GODOTCPP_GDEXTENSION_DIR} + ) + + # gersemi: off + set_target_properties( + godot-cpp + PROPERTIES + CXX_STANDARD 17 + CXX_EXTENSIONS OFF + CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY} + + COMPILE_WARNING_AS_ERROR ${GODOTCPP_WARNING_AS_ERROR} + POSITION_INDEPENDENT_CODE ON + BUILD_RPATH_USE_ORIGIN ON + + PREFIX "lib" + OUTPUT_NAME "${PROJECT_NAME}${GODOTCPP_SUFFIX}" + + ARCHIVE_OUTPUT_DIRECTORY "$<1:${CMAKE_BINARY_DIR}/bin>" + + # Things that are handy to know for dependent targets + GODOTCPP_PLATFORM "${SYSTEM_NAME}" + GODOTCPP_TARGET "${GODOTCPP_TARGET}" + GODOTCPP_ARCH "${ARCH_NAME}" + GODOTCPP_PRECISION "${GODOTCPP_PRECISION}" + GODOTCPP_SUFFIX "${GODOTCPP_SUFFIX}" + + # Some IDE's respect this property to logically group targets + FOLDER "godot-cpp" + ) + # gersemi: on + if(CMAKE_SYSTEM_NAME STREQUAL Android) + android_generate() + elseif(CMAKE_SYSTEM_NAME STREQUAL iOS) + ios_generate() + elseif(CMAKE_SYSTEM_NAME STREQUAL Linux) + linux_generate() + elseif(CMAKE_SYSTEM_NAME STREQUAL Darwin) + macos_generate() + elseif(CMAKE_SYSTEM_NAME STREQUAL Emscripten) + web_generate() + elseif(CMAKE_SYSTEM_NAME STREQUAL Windows) + windows_generate() + endif() endfunction() diff --git a/cmake/ios.cmake b/cmake/ios.cmake index a4c57057..52b2c012 100644 --- a/cmake/ios.cmake +++ b/cmake/ios.cmake @@ -1,21 +1,36 @@ #[=======================================================================[.rst: -Ios +iOS --- This file contains functions for options and configuration for targeting the -Ios platform +iOS platform ]=======================================================================] + +#[==============================[ iOS Options ]==============================] function(ios_options) - # iOS options + #[[ Options from SCons + + TODO ios_simulator: Target iOS Simulator + Default: False + + TODO ios_min_version: Target minimum iphoneos/iphonesimulator version + Default: 12.0 + + TODO IOS_TOOLCHAIN_PATH: Path to iOS toolchain + Default: "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain", + + TODO IOS_SDK_PATH: Path to the iOS SDK + Default: '' + + TODO ios_triple: Triple for ios toolchain + Default: if has_ios_osxcross(): 'ios_triple' else '' + ]] endfunction() +#[===========================[ Target Generation ]===========================] function(ios_generate) - target_compile_definitions(${TARGET_NAME} - PUBLIC - IOS_ENABLED - UNIX_ENABLED - ) + target_compile_definitions(godot-cpp PUBLIC IOS_ENABLED UNIX_ENABLED) common_compiler_flags() endfunction() diff --git a/cmake/linux.cmake b/cmake/linux.cmake index 15855099..89289d75 100644 --- a/cmake/linux.cmake +++ b/cmake/linux.cmake @@ -6,16 +6,19 @@ This file contains functions for options and configuration for targeting the Linux platform ]=======================================================================] -function( linux_options ) - # Linux Options + +#[=============================[ Linux Options ]=============================] +function(linux_options) + #[[ Options from SCons + use_llvm : Use the LLVM compiler + Not implemented as compiler selection is managed by CMake. Look to + doc/cmake.rst for examples. + ]] endfunction() -function( linux_generate ) - target_compile_definitions( ${TARGET_NAME} - PUBLIC - LINUX_ENABLED - UNIX_ENABLED - ) +#[===========================[ Target Generation ]===========================] +function(linux_generate) + target_compile_definitions(godot-cpp PUBLIC LINUX_ENABLED UNIX_ENABLED) common_compiler_flags() endfunction() diff --git a/cmake/macos.cmake b/cmake/macos.cmake index d3271ad1..7f803821 100644 --- a/cmake/macos.cmake +++ b/cmake/macos.cmake @@ -5,42 +5,49 @@ MacOS This file contains functions for options and configuration for targeting the MacOS platform -# To build universal binaries, ie targeting both x86_64 and arm64, use -# the CMAKE_OSX_ARCHITECTURES variable prior to any project calls. -# https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html +Universal Builds +---------------- + +To build universal binaries, ie targeting both x86_64 and arm64, use +the CMAKE_OSX_ARCHITECTURES variable prior to any project calls. +https://cmake.org/cmake/help/latest/variable/CMAKE_OSX_ARCHITECTURES.html ]=======================================================================] # Find Requirements -IF(APPLE) - set( CMAKE_OSX_SYSROOT $ENV{SDKROOT} ) - find_library( COCOA_LIBRARY REQUIRED +if(APPLE) + set(CMAKE_OSX_SYSROOT $ENV{SDKROOT}) + find_library( + COCOA_LIBRARY + REQUIRED NAMES Cocoa PATHS ${CMAKE_OSX_SYSROOT}/System/Library PATH_SUFFIXES Frameworks - NO_DEFAULT_PATH) -ENDIF (APPLE) + NO_DEFAULT_PATH + ) +endif(APPLE) -function( macos_options ) +#[=============================[ MacOS Options ]=============================] +function(macos_options) + #[[ Options from SCons + TODO macos_deployment_target: macOS deployment target + Default: 'default' + + TODO macos_sdk_path: macOS SDK path + Default: '' + + TODO osxcross_sdk: OSXCross SDK version + Default: if has_osxcross(): "darwin16" else None + ]] endfunction() -function( macos_generate ) +#[===========================[ Target Generation ]===========================] +function(macos_generate) + target_compile_definitions(godot-cpp PUBLIC MACOS_ENABLED UNIX_ENABLED) - target_compile_definitions(${TARGET_NAME} - PUBLIC - MACOS_ENABLED - UNIX_ENABLED - ) + target_link_options(godot-cpp PUBLIC -Wl,-undefined,dynamic_lookup) - target_link_options( ${TARGET_NAME} - PUBLIC - -Wl,-undefined,dynamic_lookup - ) - - target_link_libraries( ${TARGET_NAME} - INTERFACE - ${COCOA_LIBRARY} - ) + target_link_libraries(godot-cpp INTERFACE ${COCOA_LIBRARY}) common_compiler_flags() endfunction() diff --git a/cmake/web.cmake b/cmake/web.cmake index 996a1e52..819aa89a 100644 --- a/cmake/web.cmake +++ b/cmake/web.cmake @@ -8,30 +8,27 @@ Web platform ]=======================================================================] # Emscripten requires this hack for use of the SHARED option -set( CMAKE_PROJECT_godot-cpp_INCLUDE cmake/emsdkHack.cmake ) +set(CMAKE_PROJECT_godot-cpp_INCLUDE cmake/emsdkHack.cmake) -function( web_options ) - # web options +#[==============================[ Web Options ]==============================] +function(web_options) endfunction() +#[===========================[ Target Generation ]===========================] +function(web_generate) + target_compile_definitions(godot-cpp PUBLIC WEB_ENABLED UNIX_ENABLED) -function( web_generate ) - target_compile_definitions(${TARGET_NAME} - PUBLIC - WEB_ENABLED - UNIX_ENABLED - ) - - target_compile_options( ${TARGET_NAME} - PUBLIC + target_compile_options( + godot-cpp + PUBLIC # -sSIDE_MODULE -sSUPPORT_LONGJMP=wasm - -fno-exceptions $<${THREADS_ENABLED}:-sUSE_PTHREADS=1> ) - target_link_options( ${TARGET_NAME} - INTERFACE + target_link_options( + godot-cpp + INTERFACE # -sWASM_BIGINT -sSUPPORT_LONGJMP=wasm -fvisibility=hidden diff --git a/cmake/windows.cmake b/cmake/windows.cmake index 8e37e7e4..75ae4707 100644 --- a/cmake/windows.cmake +++ b/cmake/windows.cmake @@ -53,40 +53,52 @@ documentation. .. _issues: https://github.com/godotengine/godot-cpp/issues/1699 ]=======================================================================] -function( windows_options ) - option( GODOTCPP_USE_STATIC_CPP "Link MinGW/MSVC C++ runtime libraries statically" ON ) - option( GODOTCPP_DEBUG_CRT "Compile with MSVC's debug CRT (/MDd)" OFF ) - message( STATUS "If not already cached, setting CMAKE_MSVC_RUNTIME_LIBRARY.\n" - "\tFor more information please read godot-cpp/cmake/windows.cmake") +#[============================[ Windows Options ]============================] +function(windows_options) + #[[ Options from SCons - set( CMAKE_MSVC_RUNTIME_LIBRARY - "MultiThreaded$,DebugDLL,$<$>:DLL>>" - CACHE STRING "Select the MSVC runtime library for use by compilers targeting the MSVC ABI.") + TODO silence_msvc: Silence MSVC's cl/link stdout bloat, redirecting errors to stderr + Default: True + + These three options will not implemented as compiler selection is managed + by CMake toolchain files. Look to doc/cmake.rst for examples. + use_mingw: Use the MinGW compiler instead of MSVC - only effective on Windows + use_llvm: Use the LLVM compiler (MVSC or MinGW depending on the use_mingw flag + mingw_prefix: MinGW prefix + ]] + + option(GODOTCPP_USE_STATIC_CPP "Link MinGW/MSVC C++ runtime libraries statically" ON) + option(GODOTCPP_DEBUG_CRT "Compile with MSVC's debug CRT (/MDd)" OFF) + + message( + STATUS + "If not already cached, setting CMAKE_MSVC_RUNTIME_LIBRARY.\n" + "\tFor more information please read godot-cpp/cmake/windows.cmake" + ) + + set(CMAKE_MSVC_RUNTIME_LIBRARY + "MultiThreaded$,DebugDLL,$<$>:DLL>>" + CACHE STRING + "Select the MSVC runtime library for use by compilers targeting the MSVC ABI." + ) endfunction() - #[===========================[ Target Generation ]===========================] -function( windows_generate ) - set( STATIC_CPP "$") +function(windows_generate) + set(STATIC_CPP "$") - set_target_properties( ${TARGET_NAME} - PROPERTIES - PDB_OUTPUT_DIRECTORY "$<1:${CMAKE_SOURCE_DIR}/bin>" + set_target_properties(godot-cpp PROPERTIES PDB_OUTPUT_DIRECTORY "$<1:${CMAKE_SOURCE_DIR}/bin>") + + target_compile_definitions( + godot-cpp + PUBLIC WINDOWS_ENABLED $<${IS_MSVC}: TYPED_METHOD_BIND NOMINMAX > ) - target_compile_definitions( ${TARGET_NAME} + # gersemi: off + target_link_options( + godot-cpp PUBLIC - WINDOWS_ENABLED - $<${IS_MSVC}: - TYPED_METHOD_BIND - NOMINMAX - > - ) - - target_link_options( ${TARGET_NAME} - PUBLIC - $<${NOT_MSVC}: -Wl,--no-undefined $<${STATIC_CPP}: @@ -98,6 +110,7 @@ function( windows_generate ) $<${IS_CLANG}:-lstdc++> ) + # gersemi: on common_compiler_flags() endfunction() diff --git a/doc/cmake.rst b/doc/cmake.rst index 8045aa64..760d4561 100644 --- a/doc/cmake.rst +++ b/doc/cmake.rst @@ -24,6 +24,38 @@ Configuration examples are listed at the bottom of the page. .. _godot-cpp-template: https://github.com/godotengine/godot-cpp-template +Debug vs template_debug +----------------------- + +Something I've seen come up many times is the conflation of a compilation of c++ +source code with debug symbols enabled, and compiling a Godot extension with +debug features enabled. The two concepts are not mutually inclusive. + +- debug_features + Enables a pre-processor definition to selectively compile code to help + users of a Godot extension with their own project. + + debug features are enabled in editor and template_debug builds, which can be specified during the configure phase like so + + ``cmake -S . -B cmake-build -DGODOTCPP_TARGET=`` + +- Debug + Sets compiler flags so that debug symbols are generated to help godot + extension developers debug their extension. + + ``Debug`` is the default build type for CMake projects, to select another it depends on the generator used + + For single configuration generators, add to the configure command: + + ``-DCMAKE_BUILD_TYPE=`` + + For multi-config generators add to the build command: + + ``--config `` + + where ```` is one of ``Debug``, ``Release``, ``RelWithDebInfo``, ``MinSizeRel`` + + SCons Deviations ---------------- @@ -32,21 +64,23 @@ the notable differences. - debug_symbols No longer has an explicit option, and is enabled via Debug-like CMake - build configurations; Debug, RelWithDebInfo. + build configurations; ``Debug``, ``RelWithDebInfo``. - dev_build - Does not define NDEBUG when disabled, NDEBUG is set via Release-like - CMake build configurations; Release, MinSizeRel. + Does not define ``NDEBUG`` when disabled, ``NDEBUG`` is set via Release-like + CMake build configurations; ``Release``, ``MinSizeRel``. + +- arch + CMake sets the architecture via the toolchain files, macos universal is controlled vua the ``CMAKE_OSX_ARCHITECTURES`` + property which is copied to targets when they are defined. + +- debug_crt + CMake controls linking to windows runtime libraries by copying the value of ``CMAKE_MSVC_RUNTIME_LIBRARIES`` to targets as they are defined. + godot-cpp will set this variable if it isn't already set. so include it before other dependencies to have the value propagate across the projects. Testing Integration ------------------- -When consuming a third party CMake project into yours, an unfortunate side -effect is that the targets of the consumed project appear in the list of -available targets, and are by default included in the ALL meta target -created by most build systems. For this reason, all the targets specified -in godot-cpp are marked with the ``EXCLUDE_FROM_ALL`` tag to prevent -unnecessary compilation. The testing targets ``godot-cpp.test.`` -are also guarded by ``GODOTCPP_ENABLE_TESTING`` which is off by default. +The testing target ``godot-cpp-test`` is guarded by ``GODOTCPP_ENABLE_TESTING`` which is off by default. To configure and build the godot-cpp project to enable the integration testing targets the command will look something like: @@ -54,10 +88,8 @@ testing targets the command will look something like: .. code-block:: # Assuming our current directory is the godot-cpp source root - mkdir cmake-build - cd cmake-build - cmake .. -DGODOTCPP_ENABLE_TESTING=YES - cmake --build . --target godot-cpp.test.template_debug + cmake -S . -B cmake-build -DGODOTCPP_ENABLE_TESTING=YES + cmake --build cmake-build --target godot-cpp-test Basic walkthrough ----------------- @@ -71,30 +103,7 @@ Basic walkthrough ... cd godot-cpp - -.. topic:: Out-of-tree build directory - - Create a build directory for CMake to put caches and build artifacts in and - change directory to it. This is typically as a sub-directory of the project - root but can be outside the source tree. This is so that generated files do - not clutter up the source tree. - - .. code-block:: - - mkdir cmake-build - cd cmake-build - -.. topic:: Configure the build - - CMake doesn't build the code, it generates the files that another tool uses - to build the code. To see the list of generators run ``cmake --help``. The - first phase of which is running through the configuration scripts. - - Configure and generate Ninja build files. - - .. code-block:: - - cmake .. -G "Ninja" +.. topic:: Options To list the available options CMake use the ``-L[AH]`` option. ``A`` is for advanced, and ``H`` is for help strings. @@ -103,7 +112,7 @@ Basic walkthrough cmake .. -LH - Options are specified on the command line when configuring + Options are specified on the command line when configuring eg. .. code-block:: @@ -129,36 +138,38 @@ Basic walkthrough // Path to a custom directory containing GDExtension interface header and API JSON file ( /path/to/gdextension_dir ) GODOTCPP_GDEXTENSION_DIR:PATH=gdextension - // Generate a template version of the Node class's get_node. (ON|OFF) - GODOTCPP_GENERATE_TEMPLATE_GET_NODE:BOOL=ON - // Set the floating-point precision level (single|double) GODOTCPP_PRECISION:STRING=single - // Symbols visibility on GNU platforms. Use 'auto' to apply the default value. (auto|visible|hidden) - GODOTCPP_SYMBOL_VISIBILITY:STRING=hidden - - // Expose headers as SYSTEM. - GODOTCPP_SYSTEM_HEADERS:BOOL=ON - // Enable the extra accounting required to support hot reload. (ON|OFF) GODOTCPP_USE_HOT_RELOAD:BOOL= - // Treat warnings as errors - GODOTCPP_WARNING_AS_ERROR:BOOL=OFF - - -.. topic:: Compiling - - A target and a configuration is required, as the default ``all`` target does - not include anything and when using multi-config generators like ``Ninja - Multi-Config``, ``Visual Studio *`` or ``Xcode`` the build configuration - needs to be specified at build time. Build in Release mode unless you need - debug symbols. +.. topic:: Configure the build .. code-block:: - cmake --build . -t template_debug --config Debug + cmake -S . -B cmake-build -G Ninja + + ``-S .`` Specifies the source directory + + ``-B cmake-build`` Specifies the build directory + + ``-G Ninja`` Specifies the Generator + + The source directory in this example is the source code for godot-cpp. + The build directory is so that generated files do not clutter up the source tree. + CMake doesn't build the code, it generates the files that another tool uses + to build the code, in this case Ninja. + To see the list of generators run ``cmake --help``. + +.. topic:: Compiling + + Tell cmake to invoke the build system it generated in the specified directory. + The default target is template_debug and the default build configuration is Debug. + + .. code-block:: + + cmake --build cmake-build Examples -------- @@ -169,25 +180,23 @@ So long as CMake is installed from the `CMake Downloads`_ page and in the PATH, and Microsoft Visual Studio is installed with c++ support, CMake will detect the MSVC compiler. -Remembering that Visual Studio is a Multi-Config Generator so the build type -needs to be specified at build time. +Note that Visual Studio is a Multi-Config Generator so the build configuration +needs to be specified at build time ie ``--config Release`` .. _CMake downloads: https://cmake.org/download/ .. code-block:: # Assuming our current directory is the godot-cpp source root - mkdir build-msvc - cd build-msvc - cmake .. -DGODOTCPP_ENABLE_TESTING=YES - cmake --build . -t godot-cpp.test.template_debug --config Debug + cmake -S . -B cmake-build -DGODOTCPP_ENABLE_TESTING=YES + cmake --build cmake-build -t godot-cpp-test --config Release MSys2/clang64, "Ninja" - Debug ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Assumes the ming-w64-clang-x86_64-toolchain is installed -Remembering that Ninja is a Single-Config Generator so the build type +Note that Ninja is a Single-Config Generator so the build type needs to be specified at Configure time. Using the msys2/clang64 shell @@ -195,10 +204,8 @@ Using the msys2/clang64 shell .. code-block:: # Assuming our current directory is the godot-cpp source root - mkdir build-clang - cd build-clang - cmake .. -G"Ninja" -DGODOTCPP_ENABLE_TESTING=YES -DCMAKE_BUILD_TYPE=Debug - cmake --build . -t godot-cpp.test.template_debug + cmake -S . -B cmake-build -G"Ninja" -DGODOTCPP_ENABLE_TESTING=YES -DCMAKE_BUILD_TYPE=Release + cmake --build cmake-build -t godot-cpp-test MSys2/clang64, "Ninja Multi-Config" - dev_build, Debug Symbols ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -212,10 +219,8 @@ Using the msys2/clang64 shell .. code-block:: # Assuming our current directory is the godot-cpp source root - mkdir build-clang - cd build-clang - cmake .. -G"Ninja Multi-Config" -DGODOTCPP_ENABLE_TESTING=YES -DGODOTCPP_DEV_BUILD:BOOL=ON - cmake --build . -t godot-cpp.test.template_debug --config Debug + cmake -S . -B cmake-build -G"Ninja Multi-Config" -DGODOTCPP_ENABLE_TESTING=YES -DGODOTCPP_DEV_BUILD:BOOL=ON + cmake --build cmake-build -t godot-cpp-test --config Debug Emscripten for web platform ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -228,15 +233,14 @@ I've been using ``C:\emsdk\emsdk.ps1 activate latest`` to enable the environment from powershell in the current shell. The ``emcmake.bat`` utility adds the emscripten toolchain to the CMake command +It can also be added manually, the location is listed inside the emcmake.bat file .. code-block:: # Assuming our current directory is the godot-cpp source root C:\emsdk\emsdk.ps1 activate latest - mkdir build-wasm32 - cd build-wasm32 - emcmake.bat cmake ../ - cmake --build . --target template_release + emcmake.bat cmake -S . -B cmake-build-web -DCMAKE_BUILD_TYPE=Release + cmake --build cmake-build-web Android Cross Compile from Windows ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -263,24 +267,20 @@ is for android sdk platform, (tested with ``android-29``) .. code-block:: # Assuming our current directory is the godot-cpp source root - mkdir build-android - cd build-android - cmake .. --toolchain my_toolchain.cmake - cmake --build . -t template_release + cmake -S . -B cmake-build --toolchain my_toolchain.cmake + cmake --build cmake-build -t template_release Doing the equivalent on just using the command line .. code-block:: # Assuming our current directory is the godot-cpp source root - mkdir build-android - cd build-android - cmake .. \ + cmake -S . -B cmake-build \ -DCMAKE_SYSTEM_NAME=Android \ -DCMAKE_SYSTEM_VERSION= \ -DCMAKE_ANDROID_ARCH_ABI= \ -DCMAKE_ANDROID_NDK=/path/to/android-ndk - cmake --build . -t template_release + cmake --build cmake-build .. topic:: Using the toolchain file from the Android SDK @@ -289,22 +289,18 @@ is for android sdk platform, (tested with ``android-29``) .. code-block:: # Assuming our current directory is the godot-cpp source root - mkdir build-android - cd build-android - cmake .. --toolchain $ANDROID_HOME/ndk//build/cmake/android.toolchain.cmake - cmake --build . -t template_release + cmake -S . -B cmake-build --toolchain $ANDROID_HOME/ndk//build/cmake/android.toolchain.cmake + cmake --build cmake-build Specify Android platform and ABI .. code-block:: # Assuming our current directory is the godot-cpp source root - mkdir build-android - cd build-android - cmake .. --toolchain $ANDROID_HOME/ndk//build/cmake/android.toolchain.cmake \ + cmake -S . -B cmake-build --toolchain $ANDROID_HOME/ndk//build/cmake/android.toolchain.cmake \ -DANDROID_PLATFORM:STRING=android-29 \ -DANDROID_ABI:STRING=armeabi-v7a - cmake --build . -t template_release + cmake --build cmake-build Toolchains @@ -312,22 +308,9 @@ Toolchains This section attempts to list the host and target combinations that have been at tested. -Info on cross compiling triplets indicates that the naming is a little more -freeform that expected, and tailored to its use case. Triplets tend to have the -format ``[sub][-vendor][-OS][-env]`` - -* `osdev.org `_ -* `stack overflow `_ -* `LLVM `_ -* `clang target triple `_ -* `vcpkg `_ -* `wasm32-unknown-emscripten `_ - Linux Host ~~~~~~~~~~ -:Target: x86_64-linux - Macos Host ~~~~~~~~~~ @@ -335,43 +318,36 @@ Macos Host :OS Name: Sequoia 15.0.1 :Processor: Apple M2 +* AppleClang + Windows Host ~~~~~~~~~~~~ -:OS Name: Microsoft Windows 11 Home, 10.0.22631 N/A Build 22631 +:OS Name: Windows 11 :Processor: AMD Ryzen 7 6800HS Creator Edition -`Microsoft Visual Studio 17 2022 `_ - :Target: x86_64-w64 -`LLVM `_ - :Target: x86_64-pc-windows-msvc +* `Microsoft Visual Studio 17 2022 `_ +* `LLVM `_ +* `LLVM-MinGW `_ -`AndroidSDK `_ - armv7-none-linux-androideabi16 + * aarch64-w64-mingw32 + * armv7-w64-mingw32 + * i686-w64-mingw32 + * x86_64-w64-mingw32 -`Emscripten `_ - :Compiler: Emscripten - :Target: wasm32-unknown-emscripten +* `AndroidSDK `_ +* `Emscripten `_ +* `MinGW-W64-builds `_ +* `Jetbrains-CLion `_ -`MinGW-w64 `_ based toolchains + Jetbrains builtin compiler is just the MingW64 above. - `MSYS2 `_ - Necessary reading about MSYS2 `environments `_ +* `MSYS2 `_ + Necessary reading about MSYS2 `environments `_ - ucrt64 - :Compiler: gcc version 14.2.0 (Rev1, Built by MSYS2 project) - :Target: x86_64-w64-mingw32 - - clang64 - :Compiler: clang version 18.1.8 - :Target: x86_64-w64-windows-gnu - - `LLVM-MinGW `_ - - `MinGW-W64-builds `_ - :Compiler: gcc - :Target: x86_64-w64-mingw32-ucrt - - `Jetbrains-CLion `_ - :Target: x86_64-w64-mingw32-msvcrt + * ucrt64 + * clang64 + * mingw32 + * mingw64 + * clangarm64 diff --git a/misc/scripts/check_get_file_list.py b/misc/scripts/check_get_file_list.py index ac90777a..6ea5d6f7 100755 --- a/misc/scripts/check_get_file_list.py +++ b/misc/scripts/check_get_file_list.py @@ -19,6 +19,7 @@ def test(profile_filepath=""): api = generate_trimmed_api(api_filepath, profile_filepath) _generate_bindings( api, + api_filepath, use_template_get_node=False, bits=bits, precision=precision, diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9205aa08..ebbcbb7b 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -5,77 +5,65 @@ Integration Testing The Test target used to validate changes in the GitHub CI. ]=======================================================================] -message( STATUS "Testing Integration targets are enabled.") +message(STATUS "Testing Integration targets are enabled.") -# Generate Doc Data -file( GLOB_RECURSE DOC_XML - LIST_DIRECTORIES NO - CONFIGURE_DEPENDS - "${CMAKE_CURRENT_SOURCE_DIR}/doc_classes/*.xml" ) +set(TARGET_NAME "godot-cpp-test") -foreach( TARGET_ALIAS template_debug template_release editor ) - set( TARGET_NAME "godot-cpp.test.${TARGET_ALIAS}" ) +add_library(${TARGET_NAME} SHARED EXCLUDE_FROM_ALL) - add_library( ${TARGET_NAME} SHARED EXCLUDE_FROM_ALL ) +target_sources( + ${TARGET_NAME} + PRIVATE src/example.cpp src/example.h src/register_types.cpp src/register_types.h src/tests.h +) - target_sources( ${TARGET_NAME} - PRIVATE - src/example.cpp - src/example.h - src/register_types.cpp - src/register_types.h - src/tests.h +# conditionally add doc data to compile output +if(GODOTCPP_TARGET MATCHES "editor|template_debug") + file(GLOB_RECURSE DOC_XML LIST_DIRECTORIES NO CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/doc_classes/*.xml") + target_doc_sources( ${TARGET_NAME} ${DOC_XML} ) +endif() + +set(OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/project/bin/") + +# Link to godot-cpp target +target_link_libraries(${TARGET_NAME} PRIVATE godot-cpp) + +### Get useful properties from godot-cpp target +get_target_property(GODOTCPP_SUFFIX godot-cpp GODOTCPP_SUFFIX) + +# gersemi: off +set_target_properties( + ${TARGET_NAME} + PROPERTIES + CXX_STANDARD 17 + CXX_EXTENSIONS OFF + CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY} + + POSITION_INDEPENDENT_CODE ON + BUILD_RPATH_USE_ORIGIN ON + + # Try to ensure only static libraries are selected to be linked to. + LINK_SEARCH_START_STATIC ON + LINK_SEARCH_END_STATIC ON + + # NOTE: Wrapping the output variables inside a generator expression + # prevents msvc generator from adding addition Config Directories + LIBRARY_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>" + RUNTIME_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>" + PDB_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>" #MSVC Only, ignored on other platforms + + PREFIX "lib" + OUTPUT_NAME "gdexample${GODOTCPP_SUFFIX}" + # TODO rename the file for both CMake and SCons + + # Some IDE's respect this property to logically group targets + FOLDER "godot-cpp" +) +# gersemi: on + +# CMAKE_SYSTEM_NAME refers to the target system +if(CMAKE_SYSTEM_NAME STREQUAL Darwin) + set_target_properties( + ${TARGET_NAME} + PROPERTIES SUFFIX "" OUTPUT_DIR "${OUTPUT_DIR}/libgdexample.macos.${GODOTCPP_TARGET}.framework" ) - - # conditionally add doc data to compile output - if( TARGET_ALIAS MATCHES "editor|template_debug" ) - target_doc_sources( ${TARGET_NAME} ${DOC_XML} ) - endif() - - set( OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/project/bin/" ) - - # Link to godot-cpp target - set( LINK_TARGET "godot-cpp::${TARGET_ALIAS}" ) - target_link_libraries( ${TARGET_NAME} PRIVATE ${LINK_TARGET} ) - - ### Get useful properties from godot-cpp target - get_target_property( GODOTCPP_SUFFIX ${LINK_TARGET} GODOTCPP_SUFFIX ) - get_target_property( OSX_ARCH ${LINK_TARGET} OSX_ARCHITECTURES ) - - set_target_properties( ${TARGET_NAME} - PROPERTIES - CXX_STANDARD 17 - CXX_EXTENSIONS OFF - CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY} - - POSITION_INDEPENDENT_CODE ON - BUILD_RPATH_USE_ORIGIN ON - - # Try to ensure only static libraries are selected to be linked to. - LINK_SEARCH_START_STATIC ON - LINK_SEARCH_END_STATIC ON - - # NOTE: Wrapping the output variables inside a generator expression - # prevents msvc generator from adding addition Config Directories - LIBRARY_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>" - RUNTIME_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>" - PDB_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>" #MSVC Only, ignored on other platforms - - PREFIX "lib" - OUTPUT_NAME "gdexample${GODOTCPP_SUFFIX}" - - # Some IDE's respect this property to logically group targets - FOLDER "godot-cpp" - ) - - # CMAKE_SYSTEM_NAME refers to the target system - if( CMAKE_SYSTEM_NAME STREQUAL Darwin ) - set_target_properties( ${TARGET_NAME} - PROPERTIES - SUFFIX "" - OUTPUT_DIR "${OUTPUT_DIR}/libgdexample.macos.${TARGET_ALIAS}.framework" - OSX_ARCHITECTURES "${OSX_ARCH}" - ) - endif() - -endforeach() +endif() diff --git a/tools/godotcpp.py b/tools/godotcpp.py index 8931e6dc..3646264b 100644 --- a/tools/godotcpp.py +++ b/tools/godotcpp.py @@ -154,6 +154,7 @@ def scons_generate_bindings(target, source, env): _generate_bindings( api, + str(source[0]), env["generate_template_get_node"], "32" if "32" in env["arch"] else "64", env["precision"],