Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CMake: Grab bag of tiny refactors and improvements #1683

Draft
wants to merge 9 commits into
base: master
Choose a base branch
from
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ 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
#[[ 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)
13 changes: 12 additions & 1 deletion cmake/android.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,21 @@ Android platforms.
There is further information and examples in the doc/cmake.rst file.

]=======================================================================]

#[============================[ Android Options ]============================]
function( android_options )
# Android Options
#[[ The options present in the SCons build shown below are managed by
toolchain files, further information can be found in doc/cmake.rst

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

#[===========================[ Target Generation ]===========================]
function( android_generate )
target_compile_definitions(${TARGET_NAME}
PUBLIC
Expand Down
79 changes: 43 additions & 36 deletions cmake/common_compiler_flags.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,16 @@ 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 ]]
Expand All @@ -19,12 +29,13 @@ 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( 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
Expand All @@ -44,21 +55,19 @@ function( compiler_detection )
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 )

target_compile_features(${TARGET_NAME}
PUBLIC
cxx_std_17
)

# These compiler options reflect what is in godot/SConstruct.
target_compile_options( ${TARGET_NAME}
# 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}:
Expand All @@ -70,20 +79,19 @@ 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>
>
$<${HOT_RELOAD}:$<${IS_GNU}:-fno-gnu-unique>>

# Warnings below, these do not need to propagate to consumers.
PRIVATE

# MSVC only
$<${IS_MSVC}:
# /MP isn't valid for clang-cl with msvc frontend
$<$<CXX_COMPILER_ID:MSVC>:/MP${PROC_N}>
/W4

/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)
Expand Down Expand Up @@ -124,21 +132,22 @@ function( common_compiler_flags )
-Wplacement-new=1
-Wshadow-local
-Wstringop-overflow=4
>

# Bogus warning fixed in 8+.
$<${GNU_LT_V8}:-Wno-strict-overflow>
# Bogus warning fixed in 8+.
$<${IS_GNU}:$<${LT_V8}:-Wno-strict-overflow>>

$<${GNU_GE_V9}:-Wattribute-alias=2>
$<${IS_GNU}:$<${GE_V9}:-Wattribute-alias=2>>

# Broke on MethodBind templates before GCC 11.
$<${GNU_GT_V11}:-Wlogical-op>
# Broke on MethodBind templates before GCC 11.
$<${IS_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>
# Regression in GCC 9/10, spams so much in our variadic templates that we need to outright disable it.
$<${IS_GNU}:$<${LT_V11}:-Wno-type-limits>>

# False positives in our error macros, see GH-58747.
$<${IS_GNU}:$<${GE_V12}:-Wno-return-type>>

# False positives in our error macros, see GH-58747.
$<${GNU_GE_V12}:-Wno-return-type>
>
)

target_compile_definitions(${TARGET_NAME}
Expand All @@ -158,13 +167,11 @@ function( common_compiler_flags )
)

target_link_options( ${TARGET_NAME}
PUBLIC
$<${IS_MSVC}:
/WX # treat link warnings as errors.
/MANIFEST:NO # We dont need a manifest
>
PRIVATE
$<${IS_MSVC}:/WX /MANIFEST:NO>
# /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>
Expand Down
4 changes: 2 additions & 2 deletions cmake/emsdkHack.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,11 @@ 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_SHARED_LIBRARY_SUFFIX ".wasm") # SCons uses .wasm as a suffix
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.
# and copies that to CMAKE_SYSTEM_PROCESSOR. We dont want that.
set(CMAKE_SYSTEM_PROCESSOR "wasm32" )
# the above prevents the need for logic like:
#if( ${CMAKE_SYSTEM_NAME} STREQUAL Emscripten )
Expand Down
65 changes: 36 additions & 29 deletions cmake/godotcpp.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -11,18 +11,12 @@ This if statement simply silences that warning.
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

]=======================================================================]
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/common_compiler_flags.cmake)
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/android.cmake)
include( ${CMAKE_CURRENT_SOURCE_DIR}/cmake/ios.cmake)
Expand All @@ -43,7 +37,8 @@ set( PLATFORM_LIST linux macos windows android ios web )
# List of known architectures
set( ARCH_LIST universal x86_32 x86_64 arm32 arm64 rv64 ppc32 ppc64 wasm32 )

# Function to map processors to known architectures
#[=============================[ godot_arch_map ]=============================]
#[[ Function to map CMAKE_SYSTEM_PROCESSOR names to godot arch equivalents ]]
function( godot_arch_map ALIAS PROC )
string( TOLOWER "${PROC}" PROC )

Expand Down Expand Up @@ -157,7 +152,7 @@ function( godotcpp_options )
windows_options()
endfunction()

# Function to configure and generate the targets
#[===========================[ Target Generation ]===========================]
function( godotcpp_generate )
#[[ Multi-Threaded MSVC Compilation
When using the MSVC compiler the build command -j <n> only specifies
Expand Down Expand Up @@ -240,16 +235,15 @@ 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>
$<$<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( APPEND 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(REPLACE ";" "" SYSTEM_NAME "${SYSTEM_NAME}")

### Use the arch from the toolchain if it isn't set manually
if( GODOT_ARCH )
Expand All @@ -272,8 +266,6 @@ function( godotcpp_generate )
message( WARNING "=> GODOT_DEV_BUILD implies a Debug-like build but CMAKE_BUILD_TYPE is '${CMAKE_BUILD_TYPE}'")
endif ()
set( IS_DEV_BUILD "$<BOOL:${GODOT_DEV_BUILD}>")
# The .dev portion of the name if GODOT_DEV_BUILD is true.
set( DEV_TAG "$<${IS_DEV_BUILD}:.dev>" )

### Define our godot-cpp library targets
foreach ( TARGET_ALIAS template_debug template_release editor )
Expand All @@ -283,6 +275,17 @@ function( godotcpp_generate )
set( DEBUG_FEATURES "$<NOT:$<STREQUAL:${TARGET_ALIAS},template_release>>" )
set( HOT_RELOAD "$<IF:${HOT_RELOAD-UNSET},${DEBUG_FEATURES},$<BOOL:${GODOT_USE_HOT_RELOAD}>>" )

# Suffix
string( JOIN "" GODOT_SUFFIX
"$<1:.${SYSTEM_NAME}>"
"$<1:.${TARGET_ALIAS}>"
"$<${IS_DEV_BUILD}:.dev>"
"$<$<STREQUAL:${GODOT_PRECISION},double>:.double>"
"$<1:.${SYSTEM_ARCH}>"
# missing IOS_SIMULATOR
# missing THREADS
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The threads vs no threads distinction a pretty important one. A reusable GDExtension (ie not one for a specific project) that supports web will very likely want to have builds for both

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Given that its important, I have submitted #1698 to make that happen.

)

# the godot-cpp.* library targets
add_library( ${TARGET_NAME} STATIC EXCLUDE_FROM_ALL )
add_library( godot-cpp::${TARGET_ALIAS} ALIAS ${TARGET_NAME} )
Expand All @@ -308,17 +311,21 @@ function( godotcpp_generate )
CXX_VISIBILITY_PRESET ${GODOT_SYMBOL_VISIBILITY}

COMPILE_WARNING_AS_ERROR ${GODOT_WARNING_AS_ERROR}

POSITION_INDEPENDENT_CODE ON
BUILD_RPATH_USE_ORIGIN ON
INTERFACE_POSITION_INDEPENDENT_CODE ON

PREFIX "lib"
OUTPUT_NAME "${PROJECT_NAME}${GODOT_SUFFIX}"

PREFIX lib
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_ALIAS}"
GODOT_ARCH "${SYSTEM_ARCH}"
GODOT_PLATFORM "${SYSTEM_NAME}"
GODOT_TARGET "${TARGET_ALIAS}"
GODOT_ARCH "${SYSTEM_ARCH}"
GODOT_PRECISION "${GODOT_PRECISION}"
GODOT_SUFFIX "${GODOT_SUFFIX}"

# Some IDE's respect this property to logically group targets
FOLDER "godot-cpp"
Expand Down
12 changes: 11 additions & 1 deletion cmake/ios.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,20 @@ This file contains functions for options and configuration for targeting the
Ios platform

]=======================================================================]

#[==============================[ iOS Options ]==============================]
function(ios_options)
# iOS options
# TODO "ios_simulator", "Target iOS Simulator", False
# TODO "ios_min_version", "Target minimum iphoneos/iphonesimulator version", "12.0"
# TODO "IOS_TOOLCHAIN_PATH",
# "Path to iOS toolchain",
# "/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain",
# TODO "IOS_SDK_PATH", "Path to the iOS SDK", ""
#
# TODO if has_ios_osxcross(): "ios_triple", "Triple for ios toolchain", ""
endfunction()

#[===========================[ Target Generation ]===========================]
function(ios_generate)
target_compile_definitions(${TARGET_NAME}
PUBLIC
Expand Down
10 changes: 9 additions & 1 deletion cmake/linux.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,18 @@ This file contains functions for options and configuration for targeting the
Linux platform

]=======================================================================]

#[=============================[ Linux Options ]=============================]
function( linux_options )
# Linux Options
#[[ The options present in the SCons build shown below are managed by
toolchain files, further information can be found in doc/cmake.rst

use_llvm : Use the LLVM compiler
Default: False
]]
endfunction()

#[===========================[ Target Generation ]===========================]
function( linux_generate )
target_compile_definitions( ${TARGET_NAME}
PUBLIC
Expand Down
20 changes: 13 additions & 7 deletions cmake/macos.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,26 @@ MacOS platform

]=======================================================================]

# Find Requirements
IF(APPLE)
#[===========================[ Find Dependencies ]===========================]
# APPLE is set to True when the target system is an Apple platform
# (macOS, iOS, tvOS, visionOS or watchOS).
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 )

#[=============================[ MacOS Options ]=============================]
function( macos_options )
# macos options here
# TODO "macos_deployment_target" "macOS deployment target" "default"
# TODO "macos_sdk_path" "macOS SDK path" ""
# TODO if has_osxcross(): "osxcross_sdk" "OSXCross SDK version" "darwin16"
endfunction()


#[===========================[ Target Generation ]===========================]
function( macos_generate )

# OSX_ARCHITECTURES does not support generator expressions.
Expand All @@ -36,7 +40,9 @@ function( macos_generate )
set_target_properties( ${TARGET_NAME}
PROPERTIES

# Specify multiple architectures for universal builds
OSX_ARCHITECTURES "${OSX_ARCH}"
GODOT_ARCH ${SYSTEM_ARCH}
)

target_compile_definitions(${TARGET_NAME}
Expand Down
Loading