From d0680ad1f1a8883f12498da479afbec3c7823642 Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Tue, 25 Jun 2024 11:21:58 +0200 Subject: [PATCH 1/2] cmake: rewrite the build options and the flag setting - Add USE_LTO to enable LTO, enabled by default. - Add USE_EXTRA_OPTIMIZATION to also enable -O3 when it is not used by default enabled by default. - Add USE_FAST_MATH, to produce reproducible CRN files this should be disabled, enabled by default. - Increase warning verbosity level. - Generate maximum amount of debug information, including macro definitions. - Always disable strict aliasing, the code requires it to always be disabled. Fixes https://github.com/DaemonEngine/crunch/issues/29 --- CMakeLists.txt | 102 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 89 insertions(+), 13 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 0a3564e3..af7b424f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,8 +8,11 @@ set(CRUNCH_EXE_NAME crunch) project(${CRUNCH_PROJECT_NAME}) -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE Release) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE "Release" CACHE + STRING "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel" FORCE) endif() find_package(Git) @@ -27,27 +30,100 @@ if (Git_FOUND) endif() endif() +macro(set_cxx_flag FLAG) + if (${ARGC} GREATER 1) + set(CMAKE_CXX_FLAGS_${ARGV1} "${CMAKE_CXX_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${FLAG}") + endif() +endmacro() + +macro(set_linker_flag FLAG) + if (${ARGC} GREATER 1) + set(CMAKE_EXE_LINKER_FLAGS_${ARGV1} "${CMAKE_EXE_LINKER_FLAGS_${ARGV1}} ${FLAG}") + set(CMAKE_SHARED_LINKER_FLAGS_${ARGV1} "${CMAKE_SHARED_LINKER_FLAGS_${ARGV1}} ${FLAG}") + set(CMAKE_MODULE_LINKER_FLAGS_${ARGV1} "${CMAKE_MODULE_LINKER_FLAGS_${ARGV1}} ${FLAG}") + else() + set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${FLAG}") + set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${FLAG}") + set(CMAKE_MODULE_LINKER_FLAGS "${CMAKE_MODULE_LINKER_FLAGS} ${FLAG}") + endif() +endmacro() + +# This option decides if crunch is dynamically linked against libcrn.so +# statically linked against libcrn.o, enabling it always build libcrn.so. +# This option is a builtin CMake one, the name means “build executables +# against shader libraries”, not “build the shared libraries”. option(BUILD_SHARED_LIBS "Link executables against shared library" OFF) +# Always build libcrn.so even if crunch is linked to libcrn statically. option(BUILD_SHARED_LIBCRN "Build shared libcrn" OFF) +# Always build libcrn.a even if crunch is linked to libcrn dynamically. option(BUILD_STATIC_LIBCRN "Build static libcrn" OFF) +# Build the crunch tool, implies the build of libcrn.o or libcrn.so. option(BUILD_CRUNCH "Build crunch" ON) +# Build the provided examples, they only build on Windows for now. option(BUILD_EXAMPLES "Build examples" OFF) -if (NOT MSVC) - option(OPTIMIZE_RELEASE "Optimize release build" ON) -endif() +# Enable extra optimization flags, like using -O3 even in RelWithDebInfo build. +option(USE_EXTRA_OPTIMIZATION "Enable extra optimization" ON) +# Enable link time optimization, slows down the build but produce faster and smaller binaries. +option(USE_LTO "Enable link-time optimization" ON) +# Enabling fast math makes generated images less likely to be reproducible. +# See https://github.com/DaemonEngine/crunch/issues/29 +option(USE_FAST_MATH "Enable fast math (generated images are less likely to be reproducible)" ON) -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_BINARY_DIR}) +if (MSVC) + # Enable MSVC parallel compilation. + set_cxx_flag("/MP") -if (NOT MSVC) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-unused-value -Wno-unused") -endif() + # MSVC doesn't implement strict aliasing so there is nothing else to do. + + # CMake already sets the /O2 flag on Release and RelWithDebInfo build and /O[1-2] already sets the /Oy flag. -if(OPTIMIZE_RELEASE) - # CMake already sets -O3 flag on release build - set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -fomit-frame-pointer -ffast-math -fno-math-errno -fno-strict-aliasing") + if (USE_FAST_MATH) + set_cxx_flag("/fp:fast") + endif() + + if (USE_LTO) + set_cxx_flag("/GL" RELEASE) + set_cxx_flag("/GL" RELWITHDEBINFO) + set_cxx_flag("/GL" MINSIZEREL) + set_linker_flag("/LTCG" RELEASE) + set_linker_flag("/LTCG" RELWITHDEBINFO) + set_linker_flag("/LTCG" MINSIZEREL) + endif() +else() + # As written in crnlib.h and stb_image.h, strict aliasing should always be disabled. + set_cxx_flag("-fno-strict-aliasing") + + # Generate maxmimum amount of debug information, including macro definitions. + set_cxx_flag("-g3" DEBUG) + set_cxx_flag("-g3" RELWITHDEBINFO) + + if (USE_EXTRA_OPTIMIZATION) + # CMake already sets the -O3 flag on Release build and -O[1-3s] already sets the -fomit-frame-pointer flag. + set_cxx_flag("-Og" DEBUG) + set_cxx_flag("-O3" RELWITHDEBINFO) + endif() + + if (USE_FAST_MATH) + set_cxx_flag("-ffast-math -fno-math-errno") + endif() + + # It should be done at the very end because it copies all compiler flags + # to the linker flags. + if (USE_LTO) + set_cxx_flag("-flto" RELEASE) + set_cxx_flag("-flto" RELWITHDEBINFO) + set_cxx_flag("-flto" MINSIZEREL) + set_linker_flag("${CMAKE_CXX_FLAGS}" RELEASE) + set_linker_flag("${CMAKE_CXX_FLAGS}" RELWITHDEBINFO) + set_linker_flag("${CMAKE_CXX_FLAGS}" MINSIZEREL) + endif() endif() -add_subdirectory(crnlib) +if (BUILD_SHARED_LIBCRN OR BUILD_STATIC_LIBCRN OR BUILD_CRUNCH) + add_subdirectory(crnlib crnlib) +endif() if (BUILD_CRUNCH) add_subdirectory(crunch _crunch) From b58e434aebd8bd5746dc36eda92f15f053a5d9ae Mon Sep 17 00:00:00 2001 From: Thomas Debesse Date: Thu, 27 Jun 2024 23:50:21 +0200 Subject: [PATCH 2/2] bikeshedding: unify cmake whitespace --- CMakeLists.txt | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index af7b424f..dba76ea1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,16 +18,16 @@ endif() find_package(Git) if (Git_FOUND) - execute_process( - COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - OUTPUT_VARIABLE GIT_VERSION - OUTPUT_STRIP_TRAILING_WHITESPACE - ) - - if (GIT_VERSION) - add_definitions(-DCOMPUTED_VERSION_SUFFIX="Built from git-${GIT_VERSION}") - endif() + execute_process( + COMMAND ${GIT_EXECUTABLE} rev-parse --short HEAD + WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} + OUTPUT_VARIABLE GIT_VERSION + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + if (GIT_VERSION) + add_definitions(-DCOMPUTED_VERSION_SUFFIX="Built from git-${GIT_VERSION}") + endif() endif() macro(set_cxx_flag FLAG) @@ -122,15 +122,15 @@ else() endif() if (BUILD_SHARED_LIBCRN OR BUILD_STATIC_LIBCRN OR BUILD_CRUNCH) - add_subdirectory(crnlib crnlib) + add_subdirectory(crnlib crnlib) endif() if (BUILD_CRUNCH) - add_subdirectory(crunch _crunch) + add_subdirectory(crunch _crunch) endif() -if(BUILD_EXAMPLES) - add_subdirectory(example1 _example1) - add_subdirectory(example2 _example2) - add_subdirectory(example3 _example3) +if (BUILD_EXAMPLES) + add_subdirectory(example1 _example1) + add_subdirectory(example2 _example2) + add_subdirectory(example3 _example3) endif()