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

Optimized CMake Build Process #5657

Open
wants to merge 44 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
2ca8153
Add files via upload
AverageNerdz Nov 4, 2024
8d8e41a
Update godot-cpp-windows.cmake
AverageNerdz Nov 4, 2024
cf599f6
Update CMakeLists.txt
AverageNerdz Nov 4, 2024
6efe70f
Update CMakeLists.txt
AverageNerdz Nov 4, 2024
39c8d75
Update CMakeLists.txt
AverageNerdz Nov 4, 2024
a816afc
Update CMakeLists.txt
AverageNerdz Nov 5, 2024
16d087b
Update CMakeLists.txt
AverageNerdz Nov 5, 2024
f2022e9
Update CMakeLists.txt
AverageNerdz Nov 5, 2024
1c86977
Update CMakeLists.txt
AverageNerdz Nov 5, 2024
b0893e0
Update CMakeLists.txt
AverageNerdz Nov 5, 2024
f9c10bf
Update CMakeLists.txt
AverageNerdz Nov 5, 2024
b5e3941
Update CMakeLists.txt
AverageNerdz Nov 5, 2024
eac3748
Update CMakeLists.txt
AverageNerdz Nov 5, 2024
ffc6ca7
Update CMakeLists.txt
AverageNerdz Nov 7, 2024
6cecb91
Add files via upload
AverageNerdz Nov 7, 2024
8c3d3c7
Update CMakeLists.txt
AverageNerdz Nov 7, 2024
5eee53a
Update godot-cpp-windows.cmake
AverageNerdz Nov 7, 2024
b9204f5
Update CMakeLists.txt
AverageNerdz Nov 7, 2024
d9a6e2d
Update CMakeLists.txt
AverageNerdz Nov 7, 2024
d985ba6
Update CMakeLists.txt
AverageNerdz Nov 7, 2024
33e2d9a
Update CMakeLists.txt
AverageNerdz Nov 7, 2024
39791d2
Merge branch 'master' into cmake_win_fix
AverageNerdz Nov 7, 2024
d82992e
Updated message status
AverageNerdz Nov 7, 2024
c93cfd6
Update wrong project parameter
AverageNerdz Nov 7, 2024
b67d1c0
Reworked root configuration
AverageNerdz Nov 8, 2024
bba1d30
Created separate MSCV configuration
AverageNerdz Nov 8, 2024
b50d783
Updated CMakeConfiguration.cmake
AverageNerdz Nov 8, 2024
4fd8316
Cleaned up CMakeHelperFunctions.cmake
AverageNerdz Nov 8, 2024
514612b
remade thirdparty integration
AverageNerdz Nov 8, 2024
8def9cd
Updated extension list
AverageNerdz Nov 8, 2024
449f381
pretty much explained in root
AverageNerdz Nov 8, 2024
476f5f9
Update early checks
AverageNerdz Nov 8, 2024
2311a5c
Merge branch 'master' into cmake_win_fix
AverageNerdz Nov 8, 2024
dc72d67
Merge branch 'master' into cmake_win_fix
AverageNerdz Nov 8, 2024
2c4b723
Deleted Scripts/MSVCConfiguration.cmake
AverageNerdz Nov 9, 2024
78afd37
optimized script to prevent failure in compile
AverageNerdz Nov 9, 2024
4a85d81
optimized script to prevent failure in compile
AverageNerdz Nov 9, 2024
78657ef
Updated problematic root
AverageNerdz Nov 9, 2024
9e405f1
fixed wrong indentation
AverageNerdz Nov 10, 2024
4271c83
fixed problematic thirdparty file
AverageNerdz Nov 10, 2024
4bcfa91
Updated windows godot-cpp
AverageNerdz Nov 10, 2024
b39f840
Updated problematic native file
AverageNerdz Nov 10, 2024
84ab0ec
updated problematic early_checks file
AverageNerdz Nov 10, 2024
f2ac07c
Updated problematic extension file
AverageNerdz Nov 10, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
170 changes: 53 additions & 117 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
# Native code side of Thrive
cmake_minimum_required(VERSION 3.10)
cmake_minimum_required(VERSION 3.13)

project(Thrive)
# Must be defined before project() call
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;Distribution" CACHE STRING "" FORCE)
Copy link
Member

Choose a reason for hiding this comment

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

You should copy the comment from where you moved this code (the reason why the non-standard distribution type is here).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

done, i added something to it too :]

Copy link
Member

Choose a reason for hiding this comment

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

I still don't see the comment text about Jolt requiring the Distribution type...


# If you want to get compile commands run cmake with
# "-DCMAKE_EXPORT_COMPILE_COMMANDS=ON"
project(Thrive)

# Options
# Building either the faster variant with AVX or without for older CPU support
Expand Down Expand Up @@ -39,121 +39,27 @@ option(USE_ATOMIC_COLLISION_WRITE
"If on uses atomic write to collision data that multiple threads might want to read/write"
OFF)

option(WARNINGS_AS_ERRORS "When on treat compiler warnings as errors" ON)
option(WARNINGS_AS_ERRORS "Treat compiler warnings as errors" OFF)

option(NULL_HAS_UNUSUAL_REPRESENTATION
"When on it is not assumed that null equals numeric 0" OFF)
"When on it is not assumed that null equals numeric 0" OFF)

# Extra CMake module load path if we ever need those for Thrive
# set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${PROJECT_SOURCE_DIR}/CMake")
# Option to print source files during build
option(PRINT_SOURCE_FILES "Print source files during build" OFF)

option(THRIVE_GODOT_API_FILE "Set to override folder Godot API file is looked for in"
"")
# Add our custom CMake scripts directory
list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/Scripts")
include(CMakeConfiguration)
include(CMakeHelperFunctions)

# Also use a lib prefix on windows for consistency
if(WIN32)
set(CMAKE_SHARED_LIBRARY_PREFIX_CXX "lib")
endif()

if(NOT THRIVE_AVX)
message(STATUS "Building without AVX support")
set(CMAKE_SHARED_LIBRARY_SUFFIX "_without_avx${CMAKE_SHARED_LIBRARY_SUFFIX}")
set(CMAKE_STATIC_LIBRARY_SUFFIX "_without_avx${CMAKE_STATIC_LIBRARY_SUFFIX}")
endif()

# static building (on Linux)
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
set(BUILD_SHARED_LIBS OFF)

# Configuration types. Jolt requires a "Distribution" build type
set(CMAKE_CONFIGURATION_TYPES "Debug;Release;RelWithDebInfo;Distribution")

# Set flags for Distribution configuration
# These are based on relwithdebinfo as we want symbols for eventual crash reporting
set(CMAKE_C_FLAGS_DISTRIBUTION "${CMAKE_C_FLAGS_RELWITHDEBINFO}" CACHE
STRING "Flags used by the C compiler during Distribution builds." FORCE)
set(CMAKE_CXX_FLAGS_DISTRIBUTION "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}" CACHE
STRING "Flags used by the CXX compiler during Distribution builds." FORCE)
set(CMAKE_EXE_LINKER_FLAGS_DISTRIBUTION "${CMAKE_EXE_LINKER_FLAGS_RELWITHDEBINFO}" CACHE
STRING "Flags used for linking binaries during Distribution builds." FORCE)
set(CMAKE_SHARED_LINKER_FLAGS_DISTRIBUTION "${CMAKE_SHARED_LINKER_FLAGS_RELWITHDEBINFO}" CACHE
STRING "Flags used by the shared libraries linker during Distribution builds." FORCE)
set(CMAKE_STATIC_LINKER_FLAGS_DISTRIBUTION "${CMAKE_STATIC_LINKER_FLAGS_RELWITHDEBINFO}" CACHE
STRING "Flags used by the static libraries linker during Distribution builds." FORCE)

mark_as_advanced(
CMAKE_CXX_FLAGS_DISTRIBUTION
CMAKE_C_FLAGS_DISTRIBUTION
CMAKE_EXE_LINKER_FLAGS_DISTRIBUTION
CMAKE_SHARED_LINKER_FLAGS_DISTRIBUTION
CMAKE_STATIC_LINKER_FLAGS_DISTRIBUTION
)

# If wanted, and extra safety check before LTO enable
# if(THRIVE_LTO)
# include(CheckIPOSupported)
# check_ipo_supported(RESULT supported OUTPUT error)
# if(supported)
# set(CMAKE_INTERPROCEDURAL_OPTIMIZATION TRUE)
# else()
# message(WARNING "LTO is not supported: ${error}")
# endif()
# endif()

# Common options
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING
"Set the build type, usually Debug or Distribution" FORCE)
endif()

if(CMAKE_BUILD_TYPE STREQUAL "Debug")
set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/debug")
else()
set(CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}/release")
endif()

# Standard library and other linking flags
if(CMAKE_CXX_COMPILER_ID STREQUAL "Clang")

set(CLANG_DEFAULT_CXX_STDLIB libc++)
set(CLANG_DEFAULT_RTLIB compiler-rt)

# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -stdlib=libc++")
### apparently lld can't be specified here as llvm-ar will complain
# set(CMAKE_STATIC_LINKER_FLAGS
# "${CMAKE_STATIC_LINKER_FLAGS} -lc++abi -static-libstdc++ -fuse-ld=lld")
#set(CMAKE_STATIC_LINKER_FLAGS
# "${CMAKE_STATIC_LINKER_FLAGS} -static -lc++abi -pthread -fuse-ld=lld")
#set(CMAKE_SHARED_LINKER_FLAGS
# "${CMAKE_SHARED_LINKER_FLAGS} -static -lc++abi -pthread -fuse-ld=lld")

# set(CMAKE_EXE_LINKER_FLAGS )

# static can't specify a linker, seems to use llvm-ar thankfully
# set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -fuse-ld=lld")
set(CMAKE_SHARED_LINKER_FLAGS
"${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=lld")

# fully static standard lib, seems to fail as libc is not relocatable code
# set(CMAKE_SHARED_LINKER_FLAGS
# "${CMAKE_SHARED_LINKER_FLAGS} -static")
# set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -static")
# set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -static")

elseif(CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_STATIC_LINKER_FLAGS "${CMAKE_STATIC_LINKER_FLAGS} -fuse-ld=gold")
set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -fuse-ld=gold")
else()
set(CMAKE_GENERATOR_PLATFORM x64)
endif()

# Make better loading Linux binaries
set(CMAKE_BUILD_WITH_INSTALL_RPATH ON)
set(CMAKE_INSTALL_RPATH "$ORIGIN")
message(STATUS "Building for ${THRIVE_OS} on ${THRIVE_ARCH}")

# Detect library version
Copy link
Member

Choose a reason for hiding this comment

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

I think this code still very much needs to be after the user-configurable option variables which I think should be as close to the top of the file as possible. I'd put them even way before including any of the helper functions etc.

file(READ "src/native/NativeConstants.cs" versionFile)

file(READ "${CMAKE_CURRENT_SOURCE_DIR}/src/native/NativeConstants.cs" versionFile)
string(REGEX MATCH "Version = ([0-9]+);" _ "${versionFile}")
set(NATIVE_LIBRARY_VERSION ${CMAKE_MATCH_1})

Expand All @@ -175,24 +81,51 @@ if(NOT THRIVE_EXTENSION_VERSION)
message(FATAL_ERROR "Failed to parse Thrive GDExtensions library version")
endif()

message(STATUS "Configured native library version ${NATIVE_LIBRARY_VERSION}")
# Set default build type if not specified
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Debug)
endif()

# Handle RelWithDebInfo as Release for installation purposes
if(CMAKE_BUILD_TYPE STREQUAL "RelWithDebInfo")
set(INSTALL_BUILD_TYPE "release")
else()
string(TOLOWER "${CMAKE_BUILD_TYPE}" INSTALL_BUILD_TYPE)
endif()

# Set installation prefix
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install/${THRIVE_OS}/${INSTALL_BUILD_TYPE}"
CACHE PATH "Installation directory" FORCE)

# Configure output directories
foreach(CONFIG ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${CONFIG} CONFIG_UPPER)
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_${CONFIG_UPPER} "${CMAKE_BINARY_DIR}/bin/${CONFIG}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY_${CONFIG_UPPER} "${CMAKE_BINARY_DIR}/lib/${CONFIG}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_UPPER} "${CMAKE_BINARY_DIR}/lib/${CONFIG}")
endforeach()

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin/${INSTALL_BUILD_TYPE}")
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${INSTALL_BUILD_TYPE}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib/${INSTALL_BUILD_TYPE}")

# Configure include file
configure_file("src/native/Include.h.in" "${PROJECT_BINARY_DIR}/Include.h")
include_directories(${PROJECT_BINARY_DIR})
configure_file(
"${CMAKE_CURRENT_SOURCE_DIR}/src/native/Include.h.in"
"${CMAKE_BINARY_DIR}/Include.h"
@ONLY
)

include_directories(${CMAKE_BINARY_DIR})

# Configure gdextension stuff
if(THRIVE_GODOT_API_FILE)
set(GODOT_GDEXTENSION_DIR "${THRIVE_GODOT_API_FILE}")
include_directories("${THRIVE_GODOT_API_FILE}")
message(STATUS "Using custom location of Godot API file")
else()
set(GODOT_GDEXTENSION_DIR "${CMAKE_BINARY_DIR}/api")
include_directories("${CMAKE_BINARY_DIR}/api")
endif()

# Float precision configuration for Godot
set(FLOAT_PRECISION "single")
include_directories(${GODOT_GDEXTENSION_DIR})

# GODOT_CPP_SYSTEM_HEADERS
# GODOT_CPP_WARNING_AS_ERROR
Expand All @@ -208,3 +141,6 @@ endif()
add_subdirectory(src/native)
add_subdirectory(src/extension)

message(STATUS "Building Thrive version ${NATIVE_LIBRARY_VERSION}")
AverageNerdz marked this conversation as resolved.
Show resolved Hide resolved
message(STATUS "Build type: ${CMAKE_BUILD_TYPE}")
message(STATUS "Install prefix: ${CMAKE_INSTALL_PREFIX}")
102 changes: 102 additions & 0 deletions Scripts/CMakeConfiguration.cmake
Copy link
Member

Choose a reason for hiding this comment

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

Thisi file has wrong indentation and doesn't end with a newline, same with the other added cmake file in this folder.

Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
# Architecture detection
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(THRIVE_ARCH "x64")
set(FLOAT_PRECISION "double")
add_definitions(-DTHRIVE_64_BIT)
else()
set(THRIVE_ARCH "x86")
set(FLOAT_PRECISION "single")
add_definitions(-DTHRIVE_32_BIT)
message(WARNING "32-bit build detected. Some features may not work correctly.")
endif()

# OS Detection
if(WIN32)
set(THRIVE_OS "windows")
else()
set(THRIVE_OS "linux")
endif()

# CPU core optimization
include(ProcessorCount)
ProcessorCount(CPU_CORES)
if(CPU_CORES EQUAL 0)
set(CPU_CORES 1)
elseif(CPU_CORES GREATER 4)
math(EXPR CPU_CORES "${CPU_CORES} - 1")
endif()

# Common compiler options
if(WIN32 AND MSVC)
add_compile_options(
/MP${CPU_CORES}
/bigobj
/GR
/EHsc
/nologo
)

# Force consistent runtime
set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL")
endif()

# Target configuration functions
function(configure_windows_target target)
if(NOT WIN32 OR NOT MSVC)
message(FATAL_ERROR "function called on non-Windows/MSVC platform for target ${target}")
return()
endif()

target_compile_definitions(${target} PRIVATE
NOMINMAX
_CRT_SECURE_NO_WARNINGS
_HAS_EXCEPTIONS=1
)

# Create a Windows header that defines WIN32_LEAN_AND_MEAN
set(WIN32_HEADER "${CMAKE_BINARY_DIR}/windows_lean_mean.h")
file(WRITE ${WIN32_HEADER} "#ifndef WIN32_LEAN_AND_MEAN\n#define WIN32_LEAN_AND_MEAN\n#endif\n")

# Force include the header before any other includes
target_compile_options(${target} PRIVATE /FI"${WIN32_HEADER}")

set_target_properties(${target} PROPERTIES
MSVC_RUNTIME_LIBRARY "MultiThreaded$<$<CONFIG:Debug>:Debug>DLL"
)

configure_unity_build(${target})
endfunction()

function(configure_linux_target target)
if(WIN32)
message(FATAL_ERROR "configure_linux_target called on Windows platform")
return()
endif()

target_compile_options(${target} PRIVATE
-Wall
$<$<OR:$<CONFIG:Release>,$<CONFIG:Distribution>>:-O3>
)

if(WARNINGS_AS_ERRORS)
target_compile_options(${target} PRIVATE -Werror)
endif()

set_target_properties(${target} PROPERTIES
POSITION_INDEPENDENT_CODE ON
)
endfunction()

# Common target configuration function
function(configure_target_build target)
if(WIN32 AND MSVC)
configure_windows_target(${target})

target_include_directories(${target} BEFORE PRIVATE
${CMAKE_CXX_IMPLICIT_INCLUDE_DIRECTORIES}
${PROJECT_BINARY_DIR}
)
else()
configure_linux_target(${target})
endif()
endfunction()
45 changes: 45 additions & 0 deletions Scripts/CMakeHelperFunctions.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
# Print source files for a target (only if enabled)
function(print_source_files target)
if(NOT PRINT_SOURCE_FILES)
return()
endif()

get_target_property(target_sources ${target} SOURCES)
if(target_sources)
set(cpp_files "")
foreach(source ${target_sources})
if(source MATCHES ".*\\.(cpp|cxx|cc)$")
get_filename_component(filename ${source} NAME)
list(APPEND cpp_files ${filename})
endif()
endforeach()

list(LENGTH cpp_files total_files)
if(total_files GREATER 0)
list(SORT cpp_files)
message(STATUS "Files for ${target}:")
foreach(filename ${cpp_files})
message(STATUS " ${filename}")
endforeach()
endif()
endif()
endfunction()

# Unity build configuration based on CPU cores
function(configure_unity_build target)
if(WIN32 AND MSVC)
if(CPU_CORES LESS 4)
set(UNITY_BATCH_SIZE 10)
elseif(CPU_CORES LESS 8)
set(UNITY_BATCH_SIZE 20)
else()
set(UNITY_BATCH_SIZE 30)
endif()

set_target_properties(${target} PROPERTIES
UNITY_BUILD ON
UNITY_BUILD_MODE GROUP
UNITY_BUILD_BATCH_SIZE ${UNITY_BATCH_SIZE}
)
endif()
endfunction()
Loading