浏览代码

Merge pull request #1745 from dsnopek/4.4-cherrypicks-1

Cherry-picks for the godot-cpp 4.4 branch - 1st batch
David Snopek 4 月之前
父节点
当前提交
6388e26dd8

+ 4 - 4
.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

+ 6 - 0
.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

+ 27 - 15
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_<PROJECT-NAME>_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/<platform>.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, <PROJECT-NAME>_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.<target> 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)

+ 8 - 3
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)

+ 80 - 73
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}" )
-
-    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"
+    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"
     )
-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}] )" )
-
-    add_custom_command( OUTPUT "${OUTPUT_PATH}"
-            COMMAND "${Python3_EXECUTABLE}" "-c" "${PYTHON_SCRIPT}"
-            VERBATIM
-            WORKING_DIRECTORY "${godot-cpp_SOURCE_DIR}"
-            DEPENDS
+    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 #
             "${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()

+ 17 - 8
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()

+ 122 - 107
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/<platform>.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_<PROJECT-NAME>_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 "$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>" )
+set(DEBUG_SYMBOLS "$<OR:$<CONFIG:Debug>,$<CONFIG:RelWithDebInfo>>")
 
 #[[ Compiler Identification ]]
-set( IS_CLANG "$<CXX_COMPILER_ID:Clang>" )
-set( IS_APPLECLANG "$<CXX_COMPILER_ID:AppleClang>" )
-set( IS_GNU "$<CXX_COMPILER_ID:GNU>" )
-set( IS_MSVC "$<CXX_COMPILER_ID:MSVC>" )
-set( NOT_MSVC "$<NOT:$<CXX_COMPILER_ID:MSVC>>" )
-
-set( GNU_LT_V8 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>" )
-set( GNU_GE_V9 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9>" )
-set( GNU_GT_V11 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,11>" )
-set( GNU_LT_V11 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,11>" )
-set( GNU_GE_V12 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,12>" )
-
+set(IS_CLANG "$<CXX_COMPILER_ID:Clang>")
+set(IS_APPLECLANG "$<CXX_COMPILER_ID:AppleClang>")
+set(IS_GNU "$<CXX_COMPILER_ID:GNU>")
+set(IS_MSVC "$<CXX_COMPILER_ID:MSVC>")
+set(NOT_MSVC "$<NOT:$<CXX_COMPILER_ID:MSVC>>")
+
+set(LT_V8 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,8>")
+set(GE_V9 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,9>")
+set(GT_V11 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,11>")
+set(LT_V11 "$<VERSION_LESS:$<CXX_COMPILER_VERSION>,11>")
+set(GE_V12 "$<VERSION_GREATER_EQUAL:$<CXX_COMPILER_VERSION>,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
+                $<$<CXX_COMPILER_ID:MSVC>:/MP${PROC_N}>
+
+                # Interpret source files as utf-8
+                /utf-8
+            >
+
+        # 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)
+            >
+
+            # Clang and GNU common options
+            $<$<OR:${IS_CLANG},${IS_GNU}>:
+                -Wall
+                -Wctor-dtor-privacy
+                -Wextra
+                -Wno-unused-parameter
+                -Wnon-virtual-dtor
+                -Wwrite-strings
             >
 
-            $<${HOT_RELOAD}:
-                $<${IS_GNU}:-fno-gnu-unique>
+            # Clang only
+            $<${IS_CLANG}:
+                -Wimplicit-fallthrough
+                -Wno-ordered-compare-function-pointers
             >
 
-        # MSVC only
-        $<${IS_MSVC}:
-            # /MP isn't valid for clang-cl with msvc frontend
-            $<$<CXX_COMPILER_ID:MSVC>:/MP${PROC_N}>
-            /W4
-
-            # 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)
-
-            /utf-8
-        >
-
-        # Clang and GNU common options
-        $<$<OR:${IS_CLANG},${IS_GNU}>:
-            -Wall
-            -Wctor-dtor-privacy
-            -Wextra
-            -Wno-unused-parameter
-            -Wnon-virtual-dtor
-            -Wwrite-strings
-        >
-
-        # Clang only
-        $<${IS_CLANG}:
-            -Wimplicit-fallthrough
-            -Wno-ordered-compare-function-pointers
-        >
-
-        # GNU only
-        $<${IS_GNU}:
-            -Walloc-zero
-            -Wduplicated-branches
-            -Wduplicated-cond
-            -Wno-misleading-indentation
-            -Wplacement-new=1
-            -Wshadow-local
-            -Wstringop-overflow=4
-
-            # Bogus warning fixed in 8+.
-            $<${GNU_LT_V8}:-Wno-strict-overflow>
-
-            $<${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>
-        >
+            # GNU only
+            $<${IS_GNU}:
+                -Walloc-zero
+                -Wduplicated-branches
+                -Wduplicated-cond
+                -Wno-misleading-indentation
+                -Wplacement-new=1
+                -Wshadow-local
+                -Wstringop-overflow=4
+
+                # Bogus warning fixed in 8+.
+                $<${LT_V8}:-Wno-strict-overflow>
+
+                $<${GE_V9}:-Wattribute-alias=2>
+
+                # Broke on MethodBind templates before GCC 11.
+                $<${GT_V11}:-Wlogical-op>
+
+                # Regression in GCC 9/10, spams so much in our variadic templates that we need to outright disable it.
+                $<${LT_V11}:-Wno-type-limits>
+
+                # 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>>
+
             $<$<NOT:${DEBUG_SYMBOLS}>:
                 $<${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()

+ 5 - 5
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()

+ 230 - 213
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" )
-
-    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")
+    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")
         # 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.<target> integration testing targets" OFF )
+    option(GODOTCPP_ENABLE_TESTING "Enable the godot-cpp.test.<target> 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 <n> 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 <n> or --parallel <n> 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 <n> or --parallel <n> 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
-            "$<$<PLATFORM_ID:Android>:android.${ANDROID_ABI}>"
-            "$<$<PLATFORM_ID:iOS>:ios>"
-            "$<$<PLATFORM_ID:Linux>:linux>"
-            "$<$<PLATFORM_ID:Darwin>:macos>"
-            "$<$<PLATFORM_ID:Emscripten>:web>"
-            "$<$<PLATFORM_ID:Windows>:windows>"
-            "$<$<PLATFORM_ID:Msys>:windows>"
+    string(
+        CONCAT
+        SYSTEM_NAME
+        "$<$<PLATFORM_ID:Android>:android.${ANDROID_ABI}>"
+        "$<$<PLATFORM_ID:iOS>:ios>"
+        "$<$<PLATFORM_ID:Linux>:linux>"
+        "$<$<PLATFORM_ID:Darwin>:macos>"
+        "$<$<PLATFORM_ID:Emscripten>:web>"
+        "$<$<PLATFORM_ID:Windows>:windows>"
+        "$<$<PLATFORM_ID:Msys>:windows>"
     )
 
     # Process CPU architecture argument.
     godot_arch_name( ARCH_NAME )
 
     # Transform options into generator expressions
-    set( HOT_RELOAD-UNSET "$<STREQUAL:${GODOTCPP_USE_HOT_RELOAD},>")
+    set(HOT_RELOAD-UNSET "$<STREQUAL:${GODOTCPP_USE_HOT_RELOAD},>")
 
-    set( DISABLE_EXCEPTIONS "$<BOOL:${GODOTCPP_DISABLE_EXCEPTIONS}>")
+    set(DISABLE_EXCEPTIONS "$<BOOL:${GODOTCPP_DISABLE_EXCEPTIONS}>")
 
-    set( THREADS_ENABLED "$<BOOL:${GODOTCPP_THREADS}>" )
+    set(THREADS_ENABLED "$<BOOL:${GODOTCPP_THREADS}>")
 
     # 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 <type> 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 "$<BOOL:${GODOTCPP_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 "$<NOT:$<STREQUAL:${TARGET_ALIAS},template_release>>" )
-        set( HOT_RELOAD "$<IF:${HOT_RELOAD-UNSET},${DEBUG_FEATURES},$<BOOL:${GODOTCPP_USE_HOT_RELOAD}>>" )
-
-        # Suffix
-        string( CONCAT GODOTCPP_SUFFIX
-                "$<1:.${SYSTEM_NAME}>"
-                "$<1:.${TARGET_ALIAS}>"
-                "$<${IS_DEV_BUILD}:.dev>"
-                "$<$<STREQUAL:${GODOTCPP_PRECISION},double>:.double>"
-                "$<1:.${ARCH_NAME}>"
-                # TODO IOS_SIMULATOR
-                "$<$<NOT:${THREADS_ENABLED}>:.nothreads>"
+    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 <type> 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 "$<BOOL:${GODOTCPP_DEV_BUILD}>")
 
-        # the godot-cpp.* library targets
-        add_library( ${TARGET_NAME} STATIC EXCLUDE_FROM_ALL )
-        add_library( godot-cpp::${TARGET_ALIAS} ALIAS ${TARGET_NAME} )
+    ### Define our godot-cpp library targets
+    # Generator Expressions that rely on the target
+    set(DEBUG_FEATURES "$<NOT:$<STREQUAL:${GODOTCPP_TARGET},template_release>>")
+    set(HOT_RELOAD "$<IF:${HOT_RELOAD-UNSET},${DEBUG_FEATURES},$<BOOL:${GODOTCPP_USE_HOT_RELOAD}>>")
+
+    # Suffix
+    string(
+        CONCAT
+        GODOTCPP_SUFFIX
+        "$<1:.${SYSTEM_NAME}>"
+        "$<1:.${GODOTCPP_TARGET}>"
+        "$<${IS_DEV_BUILD}:.dev>"
+        "$<$<STREQUAL:${GODOTCPP_PRECISION},double>:.double>"
+        "$<1:.${ARCH_NAME}>"
+        # TODO IOS_SIMULATOR
+        "$<$<NOT:${THREADS_ENABLED}>:.nothreads>"
+    )
 
-        file( GLOB_RECURSE GODOTCPP_SOURCES LIST_DIRECTORIES NO CONFIGURE_DEPENDS src/*.cpp )
+    # the godot-cpp.* library targets
+    add_library(godot-cpp STATIC)
 
-        target_sources( ${TARGET_NAME}
-                PRIVATE
-                ${GODOTCPP_SOURCES}
-                ${GENERATED_FILES_LIST}
-        )
+    # Without adding this dependency to the binding generator, XCode will complain.
+    add_dependencies(godot-cpp generate_bindings)
 
-        target_include_directories( ${TARGET_NAME} ${GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE} PUBLIC
-                include
-                ${CMAKE_CURRENT_BINARY_DIR}/gen/include
-                ${GODOTCPP_GDEXTENSION_DIR}
-        )
+    # 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)
 
-        set_target_properties( ${TARGET_NAME}
-                PROPERTIES
-                CXX_STANDARD 17
-                CXX_EXTENSIONS OFF
-                CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY}
+    file(GLOB_RECURSE GODOTCPP_SOURCES LIST_DIRECTORIES NO CONFIGURE_DEPENDS src/*.cpp)
 
-                COMPILE_WARNING_AS_ERROR ${GODOTCPP_WARNING_AS_ERROR}
-                POSITION_INDEPENDENT_CODE ON
-                BUILD_RPATH_USE_ORIGIN ON
+    target_sources(godot-cpp PRIVATE ${GODOTCPP_SOURCES} ${GENERATED_FILES_LIST})
 
-                PREFIX      "lib"
-                OUTPUT_NAME "${PROJECT_NAME}${GODOTCPP_SUFFIX}"
+    target_include_directories(
+        godot-cpp
+        ${GODOTCPP_SYSTEM_HEADERS_ATTRIBUTE}
+        PUBLIC include ${CMAKE_CURRENT_BINARY_DIR}/gen/include ${GODOTCPP_GDEXTENSION_DIR}
+    )
 
-                ARCHIVE_OUTPUT_DIRECTORY "$<1:${CMAKE_BINARY_DIR}/bin>"
+    # gersemi: off
+    set_target_properties(
+        godot-cpp
+        PROPERTIES
+            CXX_STANDARD 17
+            CXX_EXTENSIONS OFF
+            CXX_VISIBILITY_PRESET ${GODOTCPP_SYMBOL_VISIBILITY}
 
-                # 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}"
+            COMPILE_WARNING_AS_ERROR ${GODOTCPP_WARNING_AS_ERROR}
+            POSITION_INDEPENDENT_CODE ON
+            BUILD_RPATH_USE_ORIGIN ON
 
-                # Some IDE's respect this property to logically group targets
-                FOLDER "godot-cpp"
-        )
+            PREFIX      "lib"
+            OUTPUT_NAME "${PROJECT_NAME}${GODOTCPP_SUFFIX}"
 
-        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 ()
+            ARCHIVE_OUTPUT_DIRECTORY "$<1:${CMAKE_BINARY_DIR}/bin>"
 
-    # 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 )
+            # 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()

+ 23 - 8
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()

+ 11 - 8
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()

+ 31 - 24
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 )
-endfunction()
+#[=============================[ MacOS Options ]=============================]
+function(macos_options)
+    #[[ Options from SCons
+    TODO macos_deployment_target: macOS deployment target
+        Default: 'default'
 
-function( macos_generate )
+    TODO macos_sdk_path: macOS SDK path
+        Default: ''
 
-    target_compile_definitions(${TARGET_NAME}
-            PUBLIC
-            MACOS_ENABLED
-            UNIX_ENABLED
-    )
+    TODO osxcross_sdk: OSXCross SDK version
+        Default: if has_osxcross(): "darwin16" else None
+    ]]
+endfunction()
 
-    target_link_options( ${TARGET_NAME}
-            PUBLIC
-            -Wl,-undefined,dynamic_lookup
-    )
+#[===========================[ Target Generation ]===========================]
+function(macos_generate)
+    target_compile_definitions(godot-cpp PUBLIC MACOS_ENABLED UNIX_ENABLED)
 
-    target_link_libraries( ${TARGET_NAME}
-            INTERFACE
-            ${COCOA_LIBRARY}
-    )
+    target_link_options(godot-cpp PUBLIC -Wl,-undefined,dynamic_lookup)
+
+    target_link_libraries(godot-cpp INTERFACE ${COCOA_LIBRARY})
 
     common_compiler_flags()
 endfunction()

+ 12 - 15
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

+ 37 - 24
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$<IF:$<BOOL:${GODOTCPP_DEBUG_CRT}>,DebugDLL,$<$<NOT:$<BOOL:${GODOTCPP_USE_STATIC_CPP}>>:DLL>>"
-            CACHE STRING "Select the MSVC runtime library for use by compilers targeting the MSVC ABI.")
-endfunction()
+    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
+    ]]
 
-#[===========================[ Target Generation ]===========================]
-function( windows_generate )
-    set( STATIC_CPP "$<BOOL:${GODOTCPP_USE_STATIC_CPP}>")
+    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)
 
-    set_target_properties( ${TARGET_NAME}
-            PROPERTIES
-            PDB_OUTPUT_DIRECTORY "$<1:${CMAKE_SOURCE_DIR}/bin>"
+    message(
+        STATUS
+        "If not already cached, setting CMAKE_MSVC_RUNTIME_LIBRARY.\n"
+        "\tFor more information please read godot-cpp/cmake/windows.cmake"
     )
 
-    target_compile_definitions( ${TARGET_NAME}
-        PUBLIC
-            WINDOWS_ENABLED
-            $<${IS_MSVC}:
-                TYPED_METHOD_BIND
-                NOMINMAX
-            >
+    set(CMAKE_MSVC_RUNTIME_LIBRARY
+        "MultiThreaded$<IF:$<BOOL:${GODOTCPP_DEBUG_CRT}>,DebugDLL,$<$<NOT:$<BOOL:${GODOTCPP_USE_STATIC_CPP}>>:DLL>>"
+        CACHE STRING
+        "Select the MSVC runtime library for use by compilers targeting the MSVC ABI."
     )
+endfunction()
 
-    target_link_options( ${TARGET_NAME}
-            PUBLIC
+#[===========================[ Target Generation ]===========================]
+function(windows_generate)
+    set(STATIC_CPP "$<BOOL:${GODOTCPP_USE_STATIC_CPP}>")
+
+    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 >
+    )
+
+    # gersemi: off
+    target_link_options(
+        godot-cpp
+        PUBLIC
             $<${NOT_MSVC}:
                 -Wl,--no-undefined
                 $<${STATIC_CPP}:
@@ -98,6 +110,7 @@ function( windows_generate )
 
             $<${IS_CLANG}:-lstdc++>
     )
+    # gersemi: on
 
     common_compiler_flags()
 endfunction()

+ 109 - 133
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=<target choice>``
+
+- 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=<type>``
+
+    For multi-config generators add to the build command:
+
+	``--config <type>``
+
+    where ``<type>`` 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.<target>``
-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:: Configure the build
+
+    .. code-block::
+
+        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
 
-   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.
+    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 . -t template_debug --config Debug
+        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=<platform> \
             -DCMAKE_ANDROID_ARCH_ABI=<arch> \
             -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/<version>/build/cmake/android.toolchain.cmake
-        cmake --build . -t template_release
+        cmake -S . -B cmake-build --toolchain $ANDROID_HOME/ndk/<version>/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/<version>/build/cmake/android.toolchain.cmake \
+        cmake -S . -B cmake-build --toolchain $ANDROID_HOME/ndk/<version>/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 ``<arch>[sub][-vendor][-OS][-env]``
-
-* `osdev.org <https://wiki.osdev.org/Target_Triplet>`_
-* `stack overflow <https://stackoverflow.com/questions/13819857/does-a-list-of-all-known-target-triplets-in-use-exist>`_
-* `LLVM <https://llvm.org/doxygen/classllvm_1_1Triple.html>`_
-* `clang target triple <https://clang.llvm.org/docs/CrossCompilation.html#target-triple>`_
-* `vcpkg <https://learn.microsoft.com/en-us/vcpkg/concepts/triplets>`_
-* `wasm32-unknown-emscripten <https://blog.therocode.net/2020/10/a-guide-to-rust-sdl2-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 <https://visualstudio.microsoft.com/vs/>`_
-    :Target: x86_64-w64
-
-`LLVM <https://llvm.org/>`_
-    :Target: x86_64-pc-windows-msvc
-
-`AndroidSDK <https://developer.android.com/studio/#command-tools>`_
-    armv7-none-linux-androideabi16
-
-`Emscripten <https://emscripten.org/>`_
-    :Compiler: Emscripten
-    :Target: wasm32-unknown-emscripten
-
-`MinGW-w64 <https://www.mingw-w64.org/>`_ based toolchains
 
-    `MSYS2 <https://www.msys2.org/>`_
-        Necessary reading about MSYS2 `environments <https://www.msys2.org/docs/environments/>`_
+* `Microsoft Visual Studio 17 2022 <https://visualstudio.microsoft.com/vs/>`_
+* `LLVM <https://llvm.org/>`_
+* `LLVM-MinGW <https://github.com/mstorsjo/llvm-mingw/releases>`_
 
-        ucrt64
-            :Compiler: gcc version 14.2.0 (Rev1, Built by MSYS2 project)
-            :Target:   x86_64-w64-mingw32
+    * aarch64-w64-mingw32
+    * armv7-w64-mingw32
+    * i686-w64-mingw32
+    * x86_64-w64-mingw32
 
-        clang64
-            :Compiler: clang version 18.1.8
-            :Target:   x86_64-w64-windows-gnu
+* `AndroidSDK <https://developer.android.com/studio/#command-tools>`_
+* `Emscripten <https://emscripten.org/>`_
+* `MinGW-W64-builds <https://github.com/niXman/mingw-builds-binaries/releases>`_
+* `Jetbrains-CLion <https://www.jetbrains.com/clion/>`_
 
-    `LLVM-MinGW <https://github.com/mstorsjo/llvm-mingw/releases>`_
+    Jetbrains builtin compiler is just the MingW64 above.
 
-    `MinGW-W64-builds <https://github.com/niXman/mingw-builds-binaries/releases>`_
-        :Compiler: gcc
-        :Target: x86_64-w64-mingw32-ucrt
+* `MSYS2 <https://www.msys2.org/>`_
+    Necessary reading about MSYS2 `environments <https://www.msys2.org/docs/environments/>`_
 
-    `Jetbrains-CLion <https://www.jetbrains.com/clion/>`_
-        :Target: x86_64-w64-mingw32-msvcrt
+    * ucrt64
+    * clang64
+    * mingw32
+    * mingw64
+    * clangarm64

+ 1 - 0
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,

+ 61 - 73
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.")
-
-# Generate Doc Data
-file( GLOB_RECURSE DOC_XML
-    LIST_DIRECTORIES NO
-    CONFIGURE_DEPENDS
-    "${CMAKE_CURRENT_SOURCE_DIR}/doc_classes/*.xml" )
-
-foreach( TARGET_ALIAS template_debug template_release editor )
-    set( TARGET_NAME "godot-cpp.test.${TARGET_ALIAS}" )
-
-    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
+message(STATUS "Testing Integration targets are enabled.")
+
+set(TARGET_NAME "godot-cpp-test")
+
+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
+)
+
+# 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()

+ 1 - 0
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"],