Alleviate CMake target name clashes, visibility, and grouping.

Simplify <platform>_generate cmake function signature, as TARGET_ALIAS and TARGET_NAME are still in scope and do not need to be passed.
Add USE_FOLDERS, and FOLDER properties to group targets in VS and XCode
Guard test target with GODOT_ENABLE_TESTING
Generate all three variants in the form godot-cpp.test.<target> to remove the -DTEST_TARGET option clutter.
Update the docs/cmake.rst with information about the testing target
Update the Github CI
pull/1658/head
Samuel Nicholas 2024-12-11 10:40:21 +10:30
parent 47f11bc5c7
commit 6f7293cef4
12 changed files with 181 additions and 125 deletions

View File

@ -202,8 +202,8 @@ jobs:
run: |
mkdir cmake-build
cd cmake-build
cmake ../ -DTEST_TARGET=template_release
cmake --build . --verbose -j $(nproc) -t godot-cpp-test --config Release
cmake ../ -DGODOT_ENABLE_TESTING=YES
cmake --build . --verbose -j $(nproc) -t godot-cpp.test.template_release --config Release
windows-msvc-cmake:
name: 🏁 Build (Windows, MSVC, CMake)
@ -218,5 +218,5 @@ jobs:
run: |
mkdir cmake-build
cd cmake-build
cmake ../ -DTEST_TARGET=template_release
cmake --build . --verbose -t godot-cpp-test --config Release
cmake ../ -DGODOT_ENABLE_TESTING=YES
cmake --build . --verbose -t godot-cpp.test.template_release --config Release

View File

@ -38,6 +38,7 @@ The CMake equivalent is below.
]=======================================================================]
include( cmake/godotcpp.cmake )
godotcpp_options()
#[[ Python is required for code generation ]]
@ -53,5 +54,12 @@ project( godot-cpp
compiler_detection()
godotcpp_generate()
# Test Example
# Conditionally enable the godot-cpp.test.<target> integration testing targets
if( GODOT_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
set_property(GLOBAL PROPERTY USE_FOLDERS ON)

View File

@ -29,13 +29,12 @@ function( android_options )
# Android Options
endfunction()
function( android_generate TARGET_NAME )
function( android_generate )
target_compile_definitions(${TARGET_NAME}
PUBLIC
ANDROID_ENABLED
UNIX_ENABLED
)
common_compiler_flags( ${TARGET_NAME} )
common_compiler_flags()
endfunction()

View File

@ -44,7 +44,7 @@ function( compiler_detection )
endif ()
endfunction( )
function( common_compiler_flags TARGET_NAME )
function( common_compiler_flags )
target_compile_features(${TARGET_NAME}
PUBLIC

View File

@ -142,6 +142,9 @@ function( godotcpp_options )
option( GODOT_SYSTEM_HEADERS "Expose headers as SYSTEM." OFF )
option( GODOT_WARNING_AS_ERROR "Treat warnings as errors" OFF )
# Enable Testing
option( GODOT_ENABLE_TESTING "Enable the godot-cpp.test.<target> integration testing targets" OFF )
#[[ Target Platform Options ]]
android_options()
ios_options()
@ -228,7 +231,7 @@ function( godotcpp_generate )
### Platform is derived from the toolchain target
# See GeneratorExpressions PLATFORM_ID and CMAKE_SYSTEM_NAME
set( SYSTEM_NAME
$<$<PLATFORM_ID:Android>:android.${ANDROID_ABI}>
$<$<PLATFORM_ID:Android>:android>
$<$<PLATFORM_ID:iOS>:ios>
$<$<PLATFORM_ID:Linux>:linux>
$<$<PLATFORM_ID:Darwin>:macos>
@ -263,7 +266,8 @@ function( godotcpp_generate )
set( DEV_TAG "$<${IS_DEV_BUILD}:.dev>" )
### Define our godot-cpp library targets
foreach ( TARGET_NAME template_debug template_release editor )
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_NAME},template_release>>" )
@ -271,7 +275,7 @@ function( godotcpp_generate )
# the godot-cpp.* library targets
add_library( ${TARGET_NAME} STATIC EXCLUDE_FROM_ALL )
add_library( godot-cpp::${TARGET_NAME} ALIAS ${TARGET_NAME} )
add_library( godot-cpp::${TARGET_ALIAS} ALIAS ${TARGET_NAME} )
file( GLOB_RECURSE GODOTCPP_SOURCES LIST_DIRECTORIES NO CONFIGURE_DEPENDS src/*.cpp )
@ -298,33 +302,36 @@ function( godotcpp_generate )
BUILD_RPATH_USE_ORIGIN ON
PREFIX lib
OUTPUT_NAME "${PROJECT_NAME}.${SYSTEM_NAME}.${TARGET_NAME}${DEV_TAG}.${SYSTEM_ARCH}"
OUTPUT_NAME "${PROJECT_NAME}.${SYSTEM_NAME}.${TARGET_ALIAS}${DEV_TAG}.${SYSTEM_ARCH}"
ARCHIVE_OUTPUT_DIRECTORY "$<1:${CMAKE_BINARY_DIR}/bin>"
# Things that are handy to know for dependent targets
GODOT_PLATFORM "${SYSTEM_NAME}"
GODOT_TARGET "${TARGET_NAME}"
GODOT_TARGET "${TARGET_ALIAS}"
GODOT_ARCH "${SYSTEM_ARCH}"
# Some IDE's respect this property to logically group targets
FOLDER "godot-cpp"
)
if( CMAKE_SYSTEM_NAME STREQUAL Android )
android_generate( ${TARGET_NAME} )
android_generate()
elseif ( CMAKE_SYSTEM_NAME STREQUAL iOS )
ios_generate( ${TARGET_NAME} )
ios_generate()
elseif ( CMAKE_SYSTEM_NAME STREQUAL Linux )
linux_generate( ${TARGET_NAME} )
linux_generate()
elseif ( CMAKE_SYSTEM_NAME STREQUAL Darwin )
macos_generate( ${TARGET_NAME} )
macos_generate()
elseif ( CMAKE_SYSTEM_NAME STREQUAL Emscripten )
web_generate( ${TARGET_NAME} )
web_generate()
elseif ( CMAKE_SYSTEM_NAME STREQUAL Windows )
windows_generate( ${TARGET_NAME} )
windows_generate()
endif ()
endforeach ()
# Added for backwards compatibility with prior cmake solution so that builds dont immediately break
# from a missing target.
add_library( godot::cpp ALIAS template_debug )
add_library( godot::cpp ALIAS godot-cpp.template_debug )
endfunction()

View File

@ -10,13 +10,12 @@ function(ios_options)
# iOS options
endfunction()
function(ios_generate TARGET_NAME)
function(ios_generate)
target_compile_definitions(${TARGET_NAME}
PUBLIC
IOS_ENABLED
UNIX_ENABLED
)
common_compiler_flags(${TARGET_NAME})
common_compiler_flags()
endfunction()

View File

@ -10,13 +10,12 @@ function( linux_options )
# Linux Options
endfunction()
function( linux_generate TARGET_NAME )
function( linux_generate )
target_compile_definitions( ${TARGET_NAME}
PUBLIC
LINUX_ENABLED
UNIX_ENABLED
)
common_compiler_flags( ${TARGET_NAME} )
common_compiler_flags()
endfunction()

View File

@ -23,7 +23,7 @@ function( macos_options )
endfunction()
function( macos_generate TARGET_NAME )
function( macos_generate )
# OSX_ARCHITECTURES does not support generator expressions.
if( NOT GODOT_ARCH OR GODOT_ARCH STREQUAL universal )
@ -55,5 +55,5 @@ function( macos_generate TARGET_NAME )
${COCOA_LIBRARY}
)
common_compiler_flags( ${TARGET_NAME} )
common_compiler_flags()
endfunction()

View File

@ -15,8 +15,7 @@ function( web_options )
endfunction()
function( web_generate TARGET_NAME )
function( web_generate )
target_compile_definitions(${TARGET_NAME}
PUBLIC
WEB_ENABLED
@ -38,5 +37,5 @@ function( web_generate TARGET_NAME )
-shared
)
common_compiler_flags( ${TARGET_NAME} )
common_compiler_flags()
endfunction()

View File

@ -58,7 +58,7 @@ function( windows_options )
endfunction()
#[===========================[ Target Generation ]===========================]
function( windows_generate TARGET_NAME )
function( windows_generate )
set( STATIC_CPP "$<BOOL:${GODOT_USE_STATIC_CPP}>")
set( DEBUG_CRT "$<BOOL:${GODOT_DEBUG_CRT}>" )
@ -96,5 +96,5 @@ function( windows_generate TARGET_NAME )
$<${IS_CLANG}:-lstdc++>
)
common_compiler_flags( ${TARGET_NAME} )
common_compiler_flags()
endfunction()

View File

@ -38,6 +38,27 @@ the notable differences.
Does not define NDEBUG when disabled, NDEBUG is set via Release-like
CMake build configurations; Release, MinSizeRel.
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 ``GODOT_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:
.. code-block::
# Assuming our current directory is the godot-cpp source root
mkdir cmake-build
cd cmake-build
cmake .. -DGODOT_ENABLE_TESTING=YES
cmake --build . --target godot-cpp.test.template_debug
Basic walkthrough
-----------------
@ -73,20 +94,20 @@ Basic walkthrough
.. code-block::
cmake ../ -G "Ninja"
cmake .. -G "Ninja"
To list the available options CMake use the ``-L[AH]`` option. ``A`` is for
advanced, and ``H`` is for help strings.
.. code-block::
cmake ../ -LH
cmake .. -LH
Options are specified on the command line when configuring
.. code-block::
cmake ../ -DGODOT_USE_HOT_RELOAD:BOOL=ON \
cmake .. -DGODOT_USE_HOT_RELOAD:BOOL=ON \
-DGODOT_PRECISION:STRING=double \
-DCMAKE_BUILD_TYPE:STRING=Debug
@ -137,78 +158,85 @@ Basic walkthrough
.. code-block::
cmake --build . -t template_debug --config Release
cmake --build . -t template_debug --config Debug
Examples
--------
Windows and MSVC
~~~~~~~~~~~~~~~~
Windows and MSVC - Release
~~~~~~~~~~~~~~~~~~~~~~~~~~
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.
.. _CMake downloads: https://cmake.org/download/
Assuming the current working directory is the godot-cpp project root:
.. code-block::
# Assuming our current directory is the godot-cpp source root
mkdir build-msvc
cd build-msvc
cmake ../
cmake --build . -t godot-cpp-test --config Release
cmake .. -DGODOT_ENABLE_TESTING=YES
cmake --build . -t godot-cpp.test.template_debug --config Debug
MSys2/clang64, "Ninja", godot-cpp-test target with debug symbols
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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
needs to be specified at Configure time.
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" -DCMAKE_BUILD_TYPE:STRING=Debug
cmake --build . -t godot-cpp-test
cmake .. -G"Ninja" -DGODOT_ENABLE_TESTING=YES -DCMAKE_BUILD_TYPE=Debug
cmake --build . -t godot-cpp.test.template_debug
MSys2/clang64, "Ninja Multi-Config", godot-cpp-test target with GODOT_DEV_BUILD
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
MSys2/clang64, "Ninja Multi-Config" - dev_build, Debug Symbols
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Assumes the ming-w64-clang-x86_64-toolchain is installed
This time we are choosing the 'Ninja Multi-Config' generator, so the build
type is specified at build time.
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" -DGODOT_DEV_BUILD:BOOL=ON
cmake --build . -t godot-cpp-test --config Debug
cmake .. -G"Ninja Multi-Config" -DGODOT_ENABLE_TESTING=YES -DGODOT_DEV_BUILD:BOOL=ON
cmake --build . -t godot-cpp.test.template_debug --config Debug
Emscripten for web, template_release target
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Emscripten for web platform
~~~~~~~~~~~~~~~~~~~~~~~~~~~
I've only tested this on windows so far.
I cloned, installed, and activating the latest Emscripten tools(for me it was
3.1.69) to ``c:\emsdk``
I cloned and installed the latest Emscripten tools to ``c:\emsdk``
At the time of writing that was v3.1.69
From a terminal running the ``c:\emsdk\emcmdprompt.bat`` puts me in a cmdprompt
context which I dislike, so after that I run pwsh to get my powershell 7.4.5
context back.
I've been using ``C:\emsdk\emsdk.ps1 activate latest`` to enable the
environment from powershell in the current shell.
using the ``emcmake.bat`` command adds the emscripten toolchain to the CMake
command
The ``emcmake.bat`` utility adds the emscripten toolchain to the CMake command
.. code-block::
C:\emsdk\emcmdprompt.bat
pwsh
cd <godot-cpp source folder>
# 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 . --verbose -t template_release
cmake --build . --target template_release
Android Cross Compile from Windows
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
@ -234,18 +262,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 .. --toolchain my_toolchain.cmake
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 .. \
-DCMAKE_SYSTEM_NAME=Android \
-DCMAKE_SYSTEM_VERSION=<platform> \
-DCMAKE_ANDROID_ARCH_ABI=<arch> \
@ -258,18 +288,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 $ANDROID_HOME/ndk/<version>/build/cmake/android.toolchain.cmake
cmake .. --toolchain $ANDROID_HOME/ndk/<version>/build/cmake/android.toolchain.cmake
cmake --build . -t template_release
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 .. --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

View File

@ -1,10 +1,20 @@
# Testing Extension
# This is only linked to the template_release config.
# so it requires the template_release version of godot to run.
#[=======================================================================[.rst:
Integration Testing
-------------------
add_library( godot-cpp-test SHARED EXCLUDE_FROM_ALL )
The Test target used to validate changes in the GitHub CI.
target_sources( godot-cpp-test
]=======================================================================]
message( STATUS "Testing Integration targets are enabled.")
foreach( TARGET_ALIAS template_debug template_release editor )
set( TARGET_NAME "godot-cpp.test.${TARGET_ALIAS}" )
set( LINK_TARGET "godot-cpp::${TARGET_ALIAS}" )
add_library( ${TARGET_NAME} SHARED EXCLUDE_FROM_ALL )
target_sources( ${TARGET_NAME}
PRIVATE
src/example.cpp
src/example.h
@ -13,22 +23,17 @@ target_sources( godot-cpp-test
src/tests.h
)
set( TEST_TARGET "template_debug" CACHE STRING "Which godot-cpp::target to link against" )
set_property( CACHE TEST_TARGET PROPERTY STRINGS "template_debug;template_release;editor" )
target_link_libraries( godot-cpp-test
PRIVATE
godot-cpp::${TEST_TARGET} )
target_link_libraries( ${TARGET_NAME} PRIVATE ${LINK_TARGET} )
### Get useful properties of the library
get_target_property( GODOT_PLATFORM godot-cpp::${TEST_TARGET} GODOT_PLATFORM )
get_target_property( GODOT_TARGET godot-cpp::${TEST_TARGET} GODOT_TARGET )
get_target_property( GODOT_ARCH godot-cpp::${TEST_TARGET} GODOT_ARCH )
get_target_property( GODOT_PLATFORM ${LINK_TARGET} GODOT_PLATFORM )
get_target_property( GODOT_TARGET ${LINK_TARGET} GODOT_TARGET )
get_target_property( GODOT_ARCH ${LINK_TARGET} GODOT_ARCH )
set( OUTPUT_DIR "${CMAKE_CURRENT_SOURCE_DIR}/project/bin/" )
set( DEV_TAG "$<$<BOOL:${GODOT_DEV_BUILD}>:.dev>" )
set_target_properties( godot-cpp-test
set_target_properties( ${TARGET_NAME}
PROPERTIES
CXX_STANDARD 17
CXX_EXTENSIONS OFF
@ -36,6 +41,8 @@ set_target_properties( godot-cpp-test
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
@ -47,22 +54,28 @@ set_target_properties( godot-cpp-test
PREFIX "lib"
OUTPUT_NAME "gdexample.${GODOT_PLATFORM}.${GODOT_TARGET}${DEV_TAG}.${GODOT_ARCH}"
# 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 )
get_target_property( OSX_ARCH godot-cpp::${TEST_TARGET} OSX_ARCHITECTURES )
get_target_property( OSX_ARCH ${LINK_TARGET} OSX_ARCHITECTURES )
set( OUTPUT_DIR "${OUTPUT_DIR}/libgdexample.macos.${TEST_TARGET}.framework")
set_target_properties( godot-cpp-test
set_target_properties( ${TARGET_NAME}
PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>"
RUNTIME_OUTPUT_DIRECTORY "$<1:${OUTPUT_DIR}>"
OUTPUT_NAME "gdexample.macos.${TEST_TARGET}${DEV_TAG}"
OUTPUT_NAME "gdexample.macos.${TARGET_ALIAS}${DEV_TAG}"
SUFFIX ""
#macos options
OSX_ARCHITECTURES "${OSX_ARCH}"
)
endif ()
endforeach()