Browse Source
[cmake] more modules, general "cleanup" (#3126)
[cmake] more modules, general "cleanup" (#3126)
Successor to that old MoltenVK PR. Does a lot of cleanups within root CMakeLists.txt, hands over MoltenVK and VulkanValidationLayers to CPMUtil, and separates out common operations into my modules. Hopefully reduces the monstrosity that is root CMakeLists.txt. Please test: - builds on all platforms - VulkanValidationLayers Signed-off-by: crueter <crueter@eden-emu.dev> Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3126 Reviewed-by: Lizzie <lizzie@eden-emu.dev> Reviewed-by: CamilleLaVey <camillelavey99@gmail.com>pull/3141/head
No known key found for this signature in database
GPG Key ID: 425ACD2D4830EBC6
21 changed files with 699 additions and 640 deletions
-
2.ci/license-header.sh
-
381CMakeLists.txt
-
49CMakeModules/GetSCMRev.cmake
-
12cpmfile.json
-
14externals/CMakeLists.txt
-
17externals/cmake-modules/DefaultConfig.cmake
-
225externals/cmake-modules/DetectArchitecture.cmake
-
151externals/cmake-modules/DetectPlatform.cmake
-
58externals/cmake-modules/FasterLinker.cmake
-
162externals/cmake-modules/GetGitRevisionDescription.cmake
-
45externals/cmake-modules/GetGitRevisionDescription.cmake.in
-
85externals/cmake-modules/GetSCMRev.cmake
-
34externals/cmake-modules/UseCcache.cmake
-
17externals/cmake-modules/UseLTO.cmake
-
20externals/cpmfile.json
-
14src/dynarmic/CMakeLists.txt
-
5src/dynarmic/CMakeModules/TargetArchitectureSpecificSources.cmake
-
2src/dynarmic/tests/CMakeLists.txt
-
6src/yuzu/CMakeLists.txt
-
26tools/cpm/check-updates.sh
-
14tools/cpm/download.sh
@ -1,49 +0,0 @@ |
|||
# SPDX-FileCopyrightText: 2025 crueter |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
include(GetGitRevisionDescription) |
|||
|
|||
function(trim var) |
|||
string(REGEX REPLACE "\n" "" new "${${var}}") |
|||
set(${var} ${new} PARENT_SCOPE) |
|||
endfunction() |
|||
|
|||
set(TAG_FILE ${CMAKE_SOURCE_DIR}/GIT-TAG) |
|||
set(REF_FILE ${CMAKE_SOURCE_DIR}/GIT-REFSPEC) |
|||
set(COMMIT_FILE ${CMAKE_SOURCE_DIR}/GIT-COMMIT) |
|||
set(RELEASE_FILE ${CMAKE_SOURCE_DIR}/GIT-RELEASE) |
|||
|
|||
if (EXISTS ${REF_FILE} AND EXISTS ${COMMIT_FILE}) |
|||
file(READ ${REF_FILE} GIT_REFSPEC) |
|||
file(READ ${COMMIT_FILE} GIT_COMMIT) |
|||
else() |
|||
get_git_head_revision(GIT_REFSPEC GIT_COMMIT) |
|||
git_branch_name(GIT_REFSPEC) |
|||
if (GIT_REFSPEC MATCHES "NOTFOUND") |
|||
set(GIT_REFSPEC 1.0.0) |
|||
set(GIT_COMMIT stable) |
|||
endif() |
|||
endif() |
|||
|
|||
if (EXISTS ${TAG_FILE}) |
|||
file(READ ${TAG_FILE} GIT_TAG) |
|||
else() |
|||
git_describe(GIT_TAG --tags --abbrev=0) |
|||
if (GIT_TAG MATCHES "NOTFOUND") |
|||
set(GIT_TAG "${GIT_REFSPEC}") |
|||
endif() |
|||
endif() |
|||
|
|||
if (EXISTS ${RELEASE_FILE}) |
|||
file(READ ${RELEASE_FILE} GIT_RELEASE) |
|||
trim(GIT_RELEASE) |
|||
message(STATUS "Git release: ${GIT_RELEASE}") |
|||
endif() |
|||
|
|||
trim(GIT_REFSPEC) |
|||
trim(GIT_COMMIT) |
|||
trim(GIT_TAG) |
|||
|
|||
message(STATUS "Git commit: ${GIT_COMMIT}") |
|||
message(STATUS "Git tag: ${GIT_TAG}") |
|||
message(STATUS "Git refspec: ${GIT_REFSPEC}") |
|||
@ -0,0 +1,17 @@ |
|||
# SPDX-FileCopyrightText: Copyright 2025 crueter |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
## DefaultConfig ## |
|||
|
|||
# Generally, you will always want "some" default configuration for your project. |
|||
# This module does nothing but enforce that. :) |
|||
|
|||
set(CMAKE_BUILD_TYPE_DEFAULT "Release" CACHE STRING "Default build type") |
|||
|
|||
get_property(IS_MULTI_CONFIG GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG) |
|||
if (NOT IS_MULTI_CONFIG AND NOT CMAKE_BUILD_TYPE) |
|||
set(CMAKE_BUILD_TYPE "${CMAKE_BUILD_TYPE_DEFAULT}" |
|||
CACHE STRING "Choose the type of build." FORCE) |
|||
message(STATUS "[DefaultConfig] Defaulting to a " |
|||
"${CMAKE_BUILD_TYPE_DEFAULT} build") |
|||
endif() |
|||
@ -0,0 +1,225 @@ |
|||
# SPDX-FileCopyrightText: Copyright 2025 crueter |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
## DetectArchitecture ## |
|||
#[[ |
|||
Does exactly as it sounds. Detects common symbols defined for different architectures and |
|||
adds compile definitions thereof. Namely: |
|||
- arm64 |
|||
- arm |
|||
- x86_64 |
|||
- x86 |
|||
- ia64 |
|||
- mips64 |
|||
- mips |
|||
- ppc64 |
|||
- ppc |
|||
- riscv |
|||
- riscv64 |
|||
- loongarch64 |
|||
- wasm |
|||
|
|||
Unsupported architectures: |
|||
- ARMv2-6 |
|||
- m68k |
|||
- PIC |
|||
|
|||
This file WILL NOT detect endian-ness for you. |
|||
|
|||
This file is based off of Yuzu and Dynarmic. |
|||
]] |
|||
|
|||
# multiarch builds are a special case and also very difficult |
|||
# this is what I have for now, but it's not ideal |
|||
|
|||
# Do note that situations where multiple architectures are defined |
|||
# should NOT be too dependent on the architecture |
|||
# otherwise, you may end up with duplicate code |
|||
if (CMAKE_OSX_ARCHITECTURES) |
|||
set(MULTIARCH_BUILD 1) |
|||
set(ARCHITECTURE "${CMAKE_OSX_ARCHITECTURES}") |
|||
|
|||
# hope and pray the architecture names match |
|||
foreach(ARCH IN ${CMAKE_OSX_ARCHITECTURES}) |
|||
set(ARCHITECTURE_${ARCH} 1 PARENT_SCOPE) |
|||
add_definitions(-DARCHITECTURE_${ARCH}=1) |
|||
endforeach() |
|||
|
|||
return() |
|||
endif() |
|||
|
|||
include(CheckSymbolExists) |
|||
function(detect_architecture symbol arch) |
|||
# The output variable needs to be unset between invocations otherwise |
|||
# CMake's crazy scope rules will keep it defined |
|||
unset(SYMBOL_EXISTS CACHE) |
|||
|
|||
if (NOT DEFINED ARCHITECTURE) |
|||
set(CMAKE_REQUIRED_QUIET 1) |
|||
check_symbol_exists("${symbol}" "" SYMBOL_EXISTS) |
|||
unset(CMAKE_REQUIRED_QUIET) |
|||
|
|||
if (SYMBOL_EXISTS) |
|||
set(ARCHITECTURE "${arch}" PARENT_SCOPE) |
|||
set(ARCHITECTURE_${arch} 1 PARENT_SCOPE) |
|||
add_definitions(-DARCHITECTURE_${arch}=1) |
|||
endif() |
|||
endif() |
|||
endfunction() |
|||
|
|||
function(detect_architecture_symbols) |
|||
if (DEFINED ARCHITECTURE) |
|||
return() |
|||
endif() |
|||
|
|||
set(oneValueArgs ARCH) |
|||
set(multiValueArgs SYMBOLS) |
|||
|
|||
cmake_parse_arguments(ARGS "" "${oneValueArgs}" "${multiValueArgs}" |
|||
"${ARGN}") |
|||
|
|||
set(arch "${ARGS_ARCH}") |
|||
foreach(symbol ${ARGS_SYMBOLS}) |
|||
detect_architecture("${symbol}" "${arch}") |
|||
|
|||
if (ARCHITECTURE_${arch}) |
|||
message(DEBUG "[DetectArchitecture] Found architecture symbol ${symbol} for ${arch}") |
|||
set(ARCHITECTURE "${arch}" PARENT_SCOPE) |
|||
set(ARCHITECTURE_${arch} 1 PARENT_SCOPE) |
|||
add_definitions(-DARCHITECTURE_${arch}=1) |
|||
|
|||
return() |
|||
endif() |
|||
endforeach() |
|||
endfunction() |
|||
|
|||
function(DetectArchitecture) |
|||
# arches here are put in a sane default order of importance |
|||
# notably, amd64, arm64, and riscv (in order) are BY FAR the most common |
|||
# mips is pretty popular in embedded |
|||
# ppc64 is pretty popular in supercomputing |
|||
# sparc is uh |
|||
# ia64 exists |
|||
# the rest exist, but are probably less popular than ia64 |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH arm64 |
|||
SYMBOLS |
|||
"__ARM64__" |
|||
"__aarch64__" |
|||
"_M_ARM64") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH x86_64 |
|||
SYMBOLS |
|||
"__x86_64" |
|||
"__x86_64__" |
|||
"__amd64" |
|||
"_M_X64" |
|||
"_M_AMD64") |
|||
|
|||
# riscv is interesting since it generally does not define a riscv64-specific symbol |
|||
# We can, however, check for the rv32 zcf extension which is good enough of a heuristic on GCC |
|||
detect_architecture_symbols( |
|||
ARCH riscv |
|||
SYMBOLS |
|||
"__riscv_zcf") |
|||
|
|||
# if zcf doesn't exist we can safely assume it's riscv64 |
|||
detect_architecture_symbols( |
|||
ARCH riscv64 |
|||
SYMBOLS |
|||
"__riscv") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH x86 |
|||
SYMBOLS |
|||
"__i386" |
|||
"__i386__" |
|||
"_M_IX86") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH arm |
|||
SYMBOLS |
|||
"__arm__" |
|||
"__TARGET_ARCH_ARM" |
|||
"_M_ARM") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH ia64 |
|||
SYMBOLS |
|||
"__ia64" |
|||
"__ia64__" |
|||
"_M_IA64") |
|||
|
|||
# mips is probably the least fun to detect due to microMIPS |
|||
# Because microMIPS is such cancer I'm considering it out of scope for now |
|||
detect_architecture_symbols( |
|||
ARCH mips64 |
|||
SYMBOLS |
|||
"__mips64") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH mips |
|||
SYMBOLS |
|||
"__mips" |
|||
"__mips__" |
|||
"_M_MRX000") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH ppc64 |
|||
SYMBOLS |
|||
"__ppc64__" |
|||
"__powerpc64__" |
|||
"_ARCH_PPC64" |
|||
"_M_PPC64") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH ppc |
|||
SYMBOLS |
|||
"__ppc__" |
|||
"__ppc" |
|||
"__powerpc__" |
|||
"_ARCH_COM" |
|||
"_ARCH_PWR" |
|||
"_ARCH_PPC" |
|||
"_M_MPPC" |
|||
"_M_PPC") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH sparc64 |
|||
SYMBOLS |
|||
"__sparc_v9__") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH sparc |
|||
SYMBOLS |
|||
"__sparc__" |
|||
"__sparc") |
|||
|
|||
# I don't actually know about loongarch32 since crossdev does not support it, only 64 |
|||
detect_architecture_symbols( |
|||
ARCH loongarch64 |
|||
SYMBOLS |
|||
"__loongarch__" |
|||
"__loongarch64") |
|||
|
|||
detect_architecture_symbols( |
|||
ARCH wasm |
|||
SYMBOLS |
|||
"__EMSCRIPTEN__") |
|||
|
|||
# "generic" target |
|||
# If you have reached this point, you're on some as-of-yet unsupported architecture. |
|||
# See the docs up above for known unsupported architectures |
|||
# If you're not in the list... I think you know what you're doing. |
|||
if (NOT DEFINED ARCHITECTURE) |
|||
set(ARCHITECTURE "GENERIC") |
|||
set(ARCHITECTURE_GENERIC 1) |
|||
add_definitions(-DARCHITECTURE_GENERIC=1) |
|||
endif() |
|||
|
|||
message(STATUS "[DetectArchitecture] Target architecture: ${ARCHITECTURE}") |
|||
set(ARCHITECTURE "${ARCHITECTURE}" PARENT_SCOPE) |
|||
set(ARCHITECTURE_${ARCHITECTURE} 1 PARENT_SCOPE) |
|||
endfunction() |
|||
@ -0,0 +1,151 @@ |
|||
# SPDX-FileCopyrightText: Copyright 2025 crueter |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
## DetectPlatform ## |
|||
|
|||
# This is a small helper that sets PLATFORM_<platform> variables for various |
|||
# operating systems and distributions. Note that Apple, Windows, Android, etc. |
|||
# are not covered, as CMake already does that for us. |
|||
|
|||
# It also sets CXX_<compiler> for the C++ compiler. |
|||
|
|||
# Furthermore, some platforms have really silly requirements/quirks, so this |
|||
# also does a few of those. |
|||
|
|||
# This module contains contributions from the Eden Emulator Project, |
|||
# notably from crueter and Lizzie. |
|||
|
|||
if (${CMAKE_SYSTEM_NAME} STREQUAL "SunOS") |
|||
set(PLATFORM_SUN ON) |
|||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "FreeBSD") |
|||
set(PLATFORM_FREEBSD ON) |
|||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "OpenBSD") |
|||
set(PLATFORM_OPENBSD ON) |
|||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "NetBSD") |
|||
set(PLATFORM_NETBSD ON) |
|||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "DragonFly") |
|||
set(PLATFORM_DRAGONFLYBSD ON) |
|||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Haiku") |
|||
set(PLATFORM_HAIKU ON) |
|||
elseif (${CMAKE_SYSTEM_NAME} STREQUAL "Linux") |
|||
set(PLATFORM_LINUX ON) |
|||
endif() |
|||
|
|||
# dumb heuristic to detect msys2 |
|||
if (CMAKE_COMMAND MATCHES "msys64") |
|||
set(PLATFORM_MSYS ON) |
|||
endif() |
|||
|
|||
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang") |
|||
set(CXX_CLANG ON) |
|||
if (MSVC) |
|||
set(CXX_CLANG_CL ON) |
|||
endif() |
|||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") |
|||
set(CXX_GCC ON) |
|||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC") |
|||
set(CXX_CL ON) |
|||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "IntelLLVM") |
|||
set(CXX_ICC ON) |
|||
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "AppleClang") |
|||
set(CXX_APPLE ON) |
|||
endif() |
|||
|
|||
# https://gitlab.kitware.com/cmake/cmake/-/merge_requests/11112 |
|||
# This works totally fine on MinGW64, but not CLANG{,ARM}64 |
|||
if(MINGW AND CXX_CLANG) |
|||
set(CMAKE_SYSTEM_VERSION 10.0.0) |
|||
endif() |
|||
|
|||
# NB: this does not account for SPARC |
|||
if (PLATFORM_SUN) |
|||
# Terrific OpenIndiana pkg shenanigans |
|||
list(APPEND CMAKE_PREFIX_PATH |
|||
"${CMAKE_SYSROOT}/usr/lib/qt/6.6/lib/amd64/cmake") |
|||
list(APPEND CMAKE_MODULE_PATH |
|||
"${CMAKE_SYSROOT}/usr/lib/qt/6.6/lib/amd64/cmake") |
|||
|
|||
# Amazing - absolutely incredible |
|||
list(APPEND CMAKE_PREFIX_PATH "${CMAKE_SYSROOT}/usr/lib/amd64/cmake") |
|||
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SYSROOT}/usr/lib/amd64/cmake") |
|||
|
|||
# For some mighty reason, doing a normal release build sometimes |
|||
# may not trigger the proper -O3 switch to materialize |
|||
if (CMAKE_BUILD_TYPE MATCHES "Release") |
|||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O3") |
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O3") |
|||
endif() |
|||
if (CMAKE_BUILD_TYPE MATCHES "RelWithDebInfo") |
|||
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -O2") |
|||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -O2") |
|||
endif() |
|||
endif() |
|||
|
|||
# MSYS2 utilities |
|||
|
|||
# Sometimes, PkgConfig modules will incorrectly reference / when CMake |
|||
# wants you to reference it as C:/msys64/. This function corrects that. |
|||
# Example in a Find module: |
|||
#[[ |
|||
if (PLATFORM_MSYS) |
|||
FixMsysPath(PkgConfig::OPUS) |
|||
endif() |
|||
]] |
|||
|
|||
function(FixMsysPath target) |
|||
get_target_property(include_dir ${target} INTERFACE_INCLUDE_DIRECTORIES) |
|||
|
|||
if (NOT (include_dir MATCHES "^/")) |
|||
return() |
|||
endif() |
|||
|
|||
set(root_default $ENV{MSYS2_LOCATION}) |
|||
if (root_default STREQUAL "") |
|||
set(root_default "C:/msys64") |
|||
endif() |
|||
|
|||
set(MSYS_ROOT_PATH ${root_default} |
|||
CACHE STRING "Location of the MSYS2 root") |
|||
|
|||
set(include_dir "C:/msys64${include_dir}") |
|||
set_target_properties(${target} PROPERTIES |
|||
INTERFACE_INCLUDE_DIRECTORIES ${include_dir}) |
|||
endfunction() |
|||
|
|||
# MSYSTEM handling + program_path |
|||
if (PLATFORM_MSYS) |
|||
# really, really dumb heuristic to detect what environment we are in |
|||
macro(system var) |
|||
if (CMAKE_COMMAND MATCHES ${var}) |
|||
set(MSYSTEM ${var}) |
|||
endif() |
|||
endmacro() |
|||
|
|||
system(mingw64) |
|||
system(clang64) |
|||
system(clangarm64) |
|||
system(ucrt64) |
|||
|
|||
if (NOT DEFINED MSYSTEM) |
|||
set(MSYSTEM msys2) |
|||
endif() |
|||
|
|||
# We generally want to prioritize environment-specific binaries if possible |
|||
# some, like autoconf, are not present on environments besides msys2 though |
|||
set(CMAKE_PROGRAM_PATH C:/msys64/${MSYSTEM}/bin C:/msys64/usr/bin) |
|||
set(ENV{PKG_CONFIG_PATH} C:/msys64/${MSYSTEM}/lib/pkgconfig) |
|||
endif() |
|||
|
|||
# This saves a truly ridiculous amount of time during linking |
|||
# In my tests, without this, Eden takes 2 mins, with this, it takes 3-5 seconds |
|||
# or on GitHub Actions, 10 minutes -> 3 seconds |
|||
if (MINGW) |
|||
set(MINGW_FLAGS "-Wl,--strip-all -Wl,--gc-sections") |
|||
set(CMAKE_EXE_LINKER_FLAGS_RELEASE |
|||
"${CMAKE_EXE_LINKER_FLAGS_RELEASE} ${MINGW_FLAGS}") |
|||
endif() |
|||
|
|||
# awesome |
|||
if (PLATFORM_FREEBSD OR PLATFORM_DRAGONFLYBSD) |
|||
set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L${CMAKE_SYSROOT}/usr/local/lib") |
|||
endif() |
|||
@ -0,0 +1,58 @@ |
|||
# SPDX-FileCopyrightText: Copyright 2025 crueter |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
## FasterLinker ## |
|||
|
|||
# This finds a faster linker for your compiler, if available. |
|||
# Only really tested on Linux. I would not recommend this on MSYS2. |
|||
|
|||
#[[ |
|||
search order: |
|||
- gold (GCC only) - the best, generally, but not packaged anymore |
|||
- mold (GCC only) - generally does well on GCC |
|||
- lld - preferred on clang |
|||
- bfd - the final fallback |
|||
- If none are found (macOS uses ld.prime, etc) just use the default linker |
|||
]] |
|||
|
|||
# This module is based on the work of Yuzu, specifically Liam White, |
|||
# and later extended by crueter. |
|||
|
|||
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU") |
|||
set(CXX_GCC ON) |
|||
endif() |
|||
|
|||
find_program(LINKER_BFD bfd) |
|||
if (LINKER_BFD) |
|||
set(LINKER bfd) |
|||
endif() |
|||
|
|||
find_program(LINKER_LLD lld) |
|||
if (LINKER_LLD) |
|||
set(LINKER lld) |
|||
endif() |
|||
|
|||
if (CXX_GCC) |
|||
find_program(LINKER_MOLD mold) |
|||
if (LINKER_MOLD AND CMAKE_CXX_COMPILER_VERSION VERSION_GREATER_EQUAL "12.1") |
|||
set(LINKER mold) |
|||
endif() |
|||
|
|||
find_program(LINKER_GOLD gold) |
|||
if (LINKER_GOLD) |
|||
set(LINKER gold) |
|||
endif() |
|||
endif() |
|||
|
|||
if (LINKER) |
|||
message(NOTICE "[FasterLinker] Selecting ${LINKER} as linker") |
|||
add_link_options("-fuse-ld=${LINKER}") |
|||
else() |
|||
message(WARNING "[FasterLinker] No faster linker found--using default") |
|||
endif() |
|||
|
|||
if (LINKER STREQUAL "lld" AND CXX_GCC) |
|||
message(WARNING |
|||
"[FasterLinker] Using lld on GCC may cause issues " |
|||
"with certain LTO settings.") |
|||
endif() |
|||
@ -1,162 +0,0 @@ |
|||
# SPDX-FileCopyrightText: 2009 Iowa State University |
|||
# SPDX-FileContributor: Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> |
|||
# SPDX-License-Identifier: BSL-1.0 |
|||
|
|||
# - Returns a version string from Git |
|||
# |
|||
# These functions force a re-configure on each git commit so that you can |
|||
# trust the values of the variables in your build system. |
|||
# |
|||
# get_git_head_revision(<refspecvar> <hashvar> [<additional arguments to git describe> ...]) |
|||
# |
|||
# Returns the refspec and sha hash of the current head revision |
|||
# |
|||
# git_describe(<var> [<additional arguments to git describe> ...]) |
|||
# |
|||
# Returns the results of git describe on the source tree, and adjusting |
|||
# the output so that it tests false if an error occurs. |
|||
# |
|||
# git_get_exact_tag(<var> [<additional arguments to git describe> ...]) |
|||
# |
|||
# Returns the results of git describe --exact-match on the source tree, |
|||
# and adjusting the output so that it tests false if there was no exact |
|||
# matching tag. |
|||
# |
|||
# Requires CMake 2.6 or newer (uses the 'function' command) |
|||
# |
|||
# Original Author: |
|||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> |
|||
# http://academic.cleardefinition.com |
|||
# Iowa State University HCI Graduate Program/VRAC |
|||
# |
|||
# Copyright Iowa State University 2009-2010. |
|||
# Distributed under the Boost Software License, Version 1.0. |
|||
# (See accompanying file LICENSE_1_0.txt or copy at |
|||
# http://www.boost.org/LICENSE_1_0.txt) |
|||
|
|||
if(__get_git_revision_description) |
|||
return() |
|||
endif() |
|||
set(__get_git_revision_description YES) |
|||
|
|||
# We must run the following at "include" time, not at function call time, |
|||
# to find the path to this module rather than the path to a calling list file |
|||
get_filename_component(_gitdescmoddir ${CMAKE_CURRENT_LIST_FILE} PATH) |
|||
|
|||
function(get_git_head_revision _refspecvar _hashvar) |
|||
set(GIT_PARENT_DIR "${CMAKE_CURRENT_SOURCE_DIR}") |
|||
set(GIT_DIR "${GIT_PARENT_DIR}/.git") |
|||
while(NOT EXISTS "${GIT_DIR}") # .git dir not found, search parent directories |
|||
set(GIT_PREVIOUS_PARENT "${GIT_PARENT_DIR}") |
|||
get_filename_component(GIT_PARENT_DIR ${GIT_PARENT_DIR} PATH) |
|||
if(GIT_PARENT_DIR STREQUAL GIT_PREVIOUS_PARENT) |
|||
# We have reached the root directory, we are not in git |
|||
set(${_refspecvar} "GITDIR-NOTFOUND" PARENT_SCOPE) |
|||
set(${_hashvar} "GITDIR-NOTFOUND" PARENT_SCOPE) |
|||
return() |
|||
endif() |
|||
set(GIT_DIR "${GIT_PARENT_DIR}/.git") |
|||
endwhile() |
|||
# check if this is a submodule |
|||
if(NOT IS_DIRECTORY ${GIT_DIR}) |
|||
file(READ ${GIT_DIR} submodule) |
|||
string(REGEX REPLACE "gitdir: (.*)\n$" "\\1" GIT_DIR_RELATIVE ${submodule}) |
|||
get_filename_component(SUBMODULE_DIR ${GIT_DIR} PATH) |
|||
get_filename_component(GIT_DIR ${SUBMODULE_DIR}/${GIT_DIR_RELATIVE} ABSOLUTE) |
|||
endif() |
|||
set(GIT_DATA "${CMAKE_CURRENT_BINARY_DIR}/CMakeFiles/git-data") |
|||
if(NOT EXISTS "${GIT_DATA}") |
|||
file(MAKE_DIRECTORY "${GIT_DATA}") |
|||
endif() |
|||
|
|||
if(NOT EXISTS "${GIT_DIR}/HEAD") |
|||
return() |
|||
endif() |
|||
set(HEAD_FILE "${GIT_DATA}/HEAD") |
|||
configure_file("${GIT_DIR}/HEAD" "${HEAD_FILE}" COPYONLY) |
|||
|
|||
configure_file("${_gitdescmoddir}/GetGitRevisionDescription.cmake.in" |
|||
"${GIT_DATA}/grabRef.cmake" |
|||
@ONLY) |
|||
include("${GIT_DATA}/grabRef.cmake") |
|||
|
|||
set(${_refspecvar} "${HEAD_REF}" PARENT_SCOPE) |
|||
set(${_hashvar} "${HEAD_HASH}" PARENT_SCOPE) |
|||
endfunction() |
|||
|
|||
function(git_branch_name _var) |
|||
if(NOT GIT_FOUND) |
|||
find_package(Git QUIET) |
|||
endif() |
|||
|
|||
if(NOT GIT_FOUND) |
|||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) |
|||
return() |
|||
endif() |
|||
|
|||
execute_process(COMMAND |
|||
"${GIT_EXECUTABLE}" |
|||
rev-parse --abbrev-ref HEAD |
|||
WORKING_DIRECTORY |
|||
"${CMAKE_SOURCE_DIR}" |
|||
RESULT_VARIABLE |
|||
res |
|||
OUTPUT_VARIABLE |
|||
out |
|||
ERROR_QUIET |
|||
OUTPUT_STRIP_TRAILING_WHITESPACE) |
|||
if(NOT res EQUAL 0) |
|||
set(out "${out}-${res}-NOTFOUND") |
|||
endif() |
|||
|
|||
set(${_var} "${out}" PARENT_SCOPE) |
|||
endfunction() |
|||
|
|||
function(git_describe _var) |
|||
if(NOT GIT_FOUND) |
|||
find_package(Git QUIET) |
|||
endif() |
|||
#get_git_head_revision(refspec hash) |
|||
if(NOT GIT_FOUND) |
|||
set(${_var} "GIT-NOTFOUND" PARENT_SCOPE) |
|||
return() |
|||
endif() |
|||
#if(NOT hash) |
|||
# set(${_var} "HEAD-HASH-NOTFOUND" PARENT_SCOPE) |
|||
# return() |
|||
#endif() |
|||
|
|||
# TODO sanitize |
|||
#if((${ARGN}" MATCHES "&&") OR |
|||
# (ARGN MATCHES "||") OR |
|||
# (ARGN MATCHES "\\;")) |
|||
# message("Please report the following error to the project!") |
|||
# message(FATAL_ERROR "Looks like someone's doing something nefarious with git_describe! Passed arguments ${ARGN}") |
|||
#endif() |
|||
|
|||
#message(STATUS "Arguments to execute_process: ${ARGN}") |
|||
|
|||
execute_process(COMMAND |
|||
"${GIT_EXECUTABLE}" |
|||
describe |
|||
${hash} |
|||
${ARGN} |
|||
WORKING_DIRECTORY |
|||
"${CMAKE_SOURCE_DIR}" |
|||
RESULT_VARIABLE |
|||
res |
|||
OUTPUT_VARIABLE |
|||
out |
|||
ERROR_QUIET |
|||
OUTPUT_STRIP_TRAILING_WHITESPACE) |
|||
if(NOT res EQUAL 0) |
|||
set(out "${out}-${res}-NOTFOUND") |
|||
endif() |
|||
|
|||
set(${_var} "${out}" PARENT_SCOPE) |
|||
endfunction() |
|||
|
|||
function(git_get_exact_tag _var) |
|||
git_describe(out --exact-match ${ARGN}) |
|||
set(${_var} "${out}" PARENT_SCOPE) |
|||
endfunction() |
|||
@ -1,45 +0,0 @@ |
|||
# SPDX-FileCopyrightText: 2009 Iowa State University |
|||
# SPDX-FileContributor: Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> |
|||
# SPDX-License-Identifier: BSL-1.0 |
|||
|
|||
# Internal file for GetGitRevisionDescription.cmake |
|||
# |
|||
# Requires CMake 2.6 or newer (uses the 'function' command) |
|||
# |
|||
# Original Author: |
|||
# 2009-2010 Ryan Pavlik <rpavlik@iastate.edu> <abiryan@ryand.net> |
|||
# http://academic.cleardefinition.com |
|||
# Iowa State University HCI Graduate Program/VRAC |
|||
# |
|||
# Copyright Iowa State University 2009-2010. |
|||
# Distributed under the Boost Software License, Version 1.0. |
|||
# (See accompanying file LICENSE_1_0.txt or copy at |
|||
# http://www.boost.org/LICENSE_1_0.txt) |
|||
|
|||
set(HEAD_HASH) |
|||
|
|||
file(READ "@HEAD_FILE@" HEAD_CONTENTS LIMIT 1024) |
|||
|
|||
string(STRIP "${HEAD_CONTENTS}" HEAD_CONTENTS) |
|||
if(HEAD_CONTENTS MATCHES "ref") |
|||
# named branch |
|||
string(REPLACE "ref: " "" HEAD_REF "${HEAD_CONTENTS}") |
|||
if(EXISTS "@GIT_DIR@/${HEAD_REF}") |
|||
configure_file("@GIT_DIR@/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) |
|||
elseif(EXISTS "@GIT_DIR@/logs/${HEAD_REF}") |
|||
configure_file("@GIT_DIR@/logs/${HEAD_REF}" "@GIT_DATA@/head-ref" COPYONLY) |
|||
set(HEAD_HASH "${HEAD_REF}") |
|||
endif() |
|||
else() |
|||
# detached HEAD |
|||
configure_file("@GIT_DIR@/HEAD" "@GIT_DATA@/head-ref" COPYONLY) |
|||
endif() |
|||
|
|||
if(NOT HEAD_HASH) |
|||
if(EXISTS "@GIT_DATA@/head-ref") |
|||
file(READ "@GIT_DATA@/head-ref" HEAD_HASH LIMIT 1024) |
|||
string(STRIP "${HEAD_HASH}" HEAD_HASH) |
|||
else() |
|||
set(HEAD_HASH "Unknown") |
|||
endif() |
|||
endif() |
|||
@ -0,0 +1,85 @@ |
|||
# SPDX-FileCopyrightText: Copyright 2025 crueter |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
## GetSCMRev ## |
|||
# Name is self explanatory. Gets revision information from files, OR from git. |
|||
# Prioritizes GIT-TAG, GIT-REFSPEC, GIT-COMMIT, GIT-RELEASE files within the root directory, |
|||
# otherwise grabs stuff from Git. |
|||
|
|||
# loosely based on Ryan Pavlik's work |
|||
find_package(Git QUIET) |
|||
|
|||
# commit: git rev-parse HEAD |
|||
# tag: git describe --tags --abbrev=0 |
|||
# branch: git rev-parse --abbrev-ref=HEAD |
|||
|
|||
function(run_git_command variable) |
|||
if(NOT GIT_FOUND) |
|||
set(${variable} "GIT-NOTFOUND" PARENT_SCOPE) |
|||
return() |
|||
endif() |
|||
|
|||
execute_process(COMMAND |
|||
"${GIT_EXECUTABLE}" |
|||
${ARGN} |
|||
WORKING_DIRECTORY |
|||
"${CMAKE_SOURCE_DIR}" |
|||
RESULT_VARIABLE |
|||
res |
|||
OUTPUT_VARIABLE |
|||
out |
|||
ERROR_QUIET |
|||
OUTPUT_STRIP_TRAILING_WHITESPACE) |
|||
|
|||
if(NOT res EQUAL 0) |
|||
set(out "${out}-${res}-NOTFOUND") |
|||
endif() |
|||
|
|||
set(${variable} "${out}" PARENT_SCOPE) |
|||
endfunction() |
|||
|
|||
function(trim var) |
|||
string(REGEX REPLACE "\n" "" new "${${var}}") |
|||
set(${var} ${new} PARENT_SCOPE) |
|||
endfunction() |
|||
|
|||
set(TAG_FILE ${CMAKE_SOURCE_DIR}/GIT-TAG) |
|||
set(REF_FILE ${CMAKE_SOURCE_DIR}/GIT-REFSPEC) |
|||
set(COMMIT_FILE ${CMAKE_SOURCE_DIR}/GIT-COMMIT) |
|||
set(RELEASE_FILE ${CMAKE_SOURCE_DIR}/GIT-RELEASE) |
|||
|
|||
if (EXISTS ${REF_FILE} AND EXISTS ${COMMIT_FILE}) |
|||
file(READ ${REF_FILE} GIT_REFSPEC) |
|||
file(READ ${COMMIT_FILE} GIT_COMMIT) |
|||
else() |
|||
run_git_command(GIT_COMMIT rev-parse HEAD) |
|||
run_git_command(GIT_REFSPEC rev-parse --abbrev-ref HEAD) |
|||
|
|||
if (GIT_REFSPEC MATCHES "NOTFOUND") |
|||
set(GIT_REFSPEC 1.0.0) |
|||
set(GIT_COMMIT stable) |
|||
endif() |
|||
endif() |
|||
|
|||
if (EXISTS ${TAG_FILE}) |
|||
file(READ ${TAG_FILE} GIT_TAG) |
|||
else() |
|||
run_git_command(GIT_TAG describe --tags --abbrev=0) |
|||
if (GIT_TAG MATCHES "NOTFOUND") |
|||
set(GIT_TAG "${GIT_REFSPEC}") |
|||
endif() |
|||
endif() |
|||
|
|||
if (EXISTS ${RELEASE_FILE}) |
|||
file(READ ${RELEASE_FILE} GIT_RELEASE) |
|||
trim(GIT_RELEASE) |
|||
message(STATUS "[GetSCMRev] Git release: ${GIT_RELEASE}") |
|||
endif() |
|||
|
|||
trim(GIT_REFSPEC) |
|||
trim(GIT_COMMIT) |
|||
trim(GIT_TAG) |
|||
|
|||
message(STATUS "[GetSCMRev] Git commit: ${GIT_COMMIT}") |
|||
message(STATUS "[GetSCMRev] Git tag: ${GIT_TAG}") |
|||
message(STATUS "[GetSCMRev] Git refspec: ${GIT_REFSPEC}") |
|||
@ -0,0 +1,34 @@ |
|||
# SPDX-FileCopyrightText: Copyright 2025 crueter |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
## UseCcache ## |
|||
|
|||
# Adds an option to enable CCache and uses it if provided. |
|||
# Also does some debug info downgrading to make it easier. |
|||
# Credit to DraVee for his work on this |
|||
|
|||
option(USE_CCACHE "Use ccache for compilation" OFF) |
|||
set(CCACHE_PATH "ccache" CACHE STRING "Path to ccache binary") |
|||
if(USE_CCACHE) |
|||
find_program(CCACHE_BINARY ${CCACHE_PATH}) |
|||
if(CCACHE_BINARY) |
|||
message(STATUS "[UseCcache] Found ccache at: ${CCACHE_BINARY}") |
|||
set(CMAKE_C_COMPILER_LAUNCHER ${CCACHE_BINARY}) |
|||
set(CMAKE_CXX_COMPILER_LAUNCHER ${CCACHE_BINARY}) |
|||
else() |
|||
message(FATAL_ERROR "[UseCcache] USE_CCACHE enabled, but no " |
|||
"executable found at: ${CCACHE_PATH}") |
|||
endif() |
|||
# Follow SCCache recommendations: |
|||
# <https://github.com/mozilla/sccache/blob/main/README.md?plain=1#L144> |
|||
if(WIN32) |
|||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_DEBUG |
|||
"${CMAKE_CXX_FLAGS_DEBUG}") |
|||
string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_DEBUG |
|||
"${CMAKE_C_FLAGS_DEBUG}") |
|||
string(REPLACE "/Zi" "/Z7" CMAKE_CXX_FLAGS_RELWITHDEBINFO |
|||
"${CMAKE_CXX_FLAGS_RELWITHDEBINFO}") |
|||
string(REPLACE "/Zi" "/Z7" CMAKE_C_FLAGS_RELWITHDEBINFO |
|||
"${CMAKE_C_FLAGS_RELWITHDEBINFO}") |
|||
endif() |
|||
endif() |
|||
@ -0,0 +1,17 @@ |
|||
# SPDX-FileCopyrightText: Copyright 2025 crueter |
|||
# SPDX-License-Identifier: GPL-3.0-or-later |
|||
|
|||
## UseLTO ## |
|||
|
|||
# Enable Interprocedural Optimization (IPO). |
|||
# Self-explanatory. |
|||
|
|||
include(CheckIPOSupported) |
|||
check_ipo_supported(RESULT COMPILER_SUPPORTS_LTO) |
|||
if(NOT COMPILER_SUPPORTS_LTO) |
|||
message(FATAL_ERROR |
|||
"Your compiler does not support interprocedural optimization" |
|||
" (IPO).") |
|||
endif() |
|||
set(CMAKE_POLICY_DEFAULT_CMP0069 NEW) |
|||
set(CMAKE_INTERPROCEDURAL_OPTIMIZATION ${COMPILER_SUPPORTS_LTO}) |
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue