Files
azahar/CMakeModules/GenerateBuildInfo.cmake
T
davey 16a93508b5 build: Report the real version in linked worktrees
Version detection is gated on .git/objects existing, which it does not in a
linked worktree, where .git is a file pointing at the common gitdir. Every
worktree build fell through to the self-packed-archive branch and was stamped
UNKNOWN, so the title bar read "azahar UNKNOWN" and the log reported
"UNKNOWN | UNKNOWN-UNKNOWN". Testing for .git itself covers both layouts; a
source tree with no .git at all still takes the archive branch.

That is enough for the branch name and the description, which shell out to git,
but not for the hash. get_git_head_revision() resolves HEAD by hand, and a
worktree keeps its own HEAD while the ref that HEAD names lives in the common
gitdir, which GetGitRevisionDescription.cmake does not follow. Fall back to git
rev-parse, which knows where to look. A normal checkout resolves the hash as
before and never reaches the fallback.
2026-10-15 22:23:04 +01:00

83 lines
3.3 KiB
CMake

macro(generate_build_info)
find_package(Git QUIET)
# Gets a UTC timstamp and sets the provided variable to it
function(get_timestamp _var)
string(TIMESTAMP timestamp UTC)
set(${_var} "${timestamp}" PARENT_SCOPE)
endfunction()
get_timestamp(BUILD_DATE)
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/externals/cmake-modules")
if (EXISTS "${CMAKE_SOURCE_DIR}/GIT-COMMIT" AND EXISTS "${CMAKE_SOURCE_DIR}/GIT-TAG")
file(READ "${CMAKE_SOURCE_DIR}/GIT-COMMIT" GIT_REV_RAW LIMIT 64)
string(STRIP "${GIT_REV_RAW}" GIT_REV)
string(SUBSTRING "${GIT_REV_RAW}" 0 9 GIT_DESC)
set(GIT_BRANCH "HEAD")
# A linked worktree has a .git file pointing at the real gitdir, not a .git directory, so
# testing for objects/ inside it silently downgrades every worktree build to "UNKNOWN".
elseif (EXISTS "${CMAKE_SOURCE_DIR}/.git")
# Find the package here with the known path so that the GetGit commands can find it as well
find_package(Git QUIET PATHS "${GIT_EXECUTABLE}")
# only use Git to check revision info when source is obtained via Git
include(GetGitRevisionDescription)
get_git_head_revision(GIT_REF_SPEC GIT_REV)
# In a linked worktree HEAD lives in the worktree's own gitdir, but the ref it names does
# not, so the lookup above finds no hash. Ask git, which knows where to look.
if (NOT GIT_REV MATCHES "^[0-9a-f]+$")
execute_process(COMMAND "${GIT_EXECUTABLE}" rev-parse HEAD
WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}"
OUTPUT_VARIABLE GIT_REV
OUTPUT_STRIP_TRAILING_WHITESPACE
ERROR_QUIET)
endif()
git_describe(GIT_DESC --always --long --dirty)
git_branch_name(GIT_BRANCH)
if (DEFINED ENV{CITRA_USE_TAG_AS_VERSION})
git_describe(GIT_TAG --tags --dirty)
endif()
else()
# self-packed archive?
set(GIT_REV "UNKNOWN")
set(GIT_DESC "UNKNOWN")
set(GIT_BRANCH "UNKNOWN")
endif()
string(SUBSTRING "${GIT_REV}" 0 7 GIT_SHORT_REV)
# Set build version
set(REPO_NAME "")
set(BUILD_VERSION "0")
set(BUILD_FULLNAME "${GIT_SHORT_REV}")
if (NOT DEFINED GIT_TAG)
if ((DEFINED ENV{CI} AND DEFINED ENV{GITHUB_ACTIONS}))
if ($ENV{GITHUB_REF_TYPE} STREQUAL "tag")
set(GIT_TAG $ENV{GITHUB_REF_NAME})
endif()
elseif (EXISTS "${CMAKE_SOURCE_DIR}/GIT-COMMIT" AND EXISTS "${CMAKE_SOURCE_DIR}/GIT-TAG")
file(READ "${CMAKE_SOURCE_DIR}/GIT-TAG" GIT_TAG)
string(STRIP ${GIT_TAG} GIT_TAG)
endif()
endif()
if (DEFINED GIT_TAG AND NOT "${GIT_TAG}" STREQUAL "unknown")
set(BUILD_VERSION "${GIT_TAG}")
set(BUILD_FULLNAME "${BUILD_VERSION}")
endif()
# Set build variant
set(BUILD_VARIANT "") # Empty string on non-Windows platforms
if (WIN32)
if (CMAKE_HOST_SYSTEM_NAME STREQUAL "Linux" AND MINGW)
set(BUILD_VARIANT "MXE")
elseif(MINGW)
set(BUILD_VARIANT "MSYS2")
elseif(MSVC)
set(BUILD_VARIANT "MSVC")
else()
set(BUILD_VARIANT "Unknown")
endif()
endif()
endmacro()