chore: Add Git information compile-time info to only one file (#6464)

The existing code added the git commit info (`GIT_COMMIT_HASH` and `GIT_BRANCH`) to every file, which was a problem for leveraging `ccache` to cache build objects. This change adds a separate C++ file from where these compile-time variables are propagated to wherever they are needed. A new CMake file is added to set the commit info if the `git` binary is available.
This commit is contained in:
Ayaz Salikhov
2026-03-04 19:45:28 +00:00
committed by GitHub
parent 595f0dd461
commit c69091bded
13 changed files with 137 additions and 65 deletions

View File

@@ -49,6 +49,11 @@ jobs:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prepare runner
uses: XRPLF/actions/prepare-runner@2cbf481018d930656e9276fcc20dc0e3a0be5b6d
with:
enable_ccache: false
- name: Get number of processors
uses: XRPLF/actions/get-nproc@cf0433aa74563aead044a1e395610c96d65a37cf
id: nproc

View File

@@ -36,26 +36,6 @@ endif ()
# Enable ccache to speed up builds.
include(Ccache)
# make GIT_COMMIT_HASH define available to all sources
find_package(Git)
if (Git_FOUND)
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse
HEAD OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gch)
if (gch)
set(GIT_COMMIT_HASH "${gch}")
message(STATUS gch: ${GIT_COMMIT_HASH})
add_definitions(-DGIT_COMMIT_HASH="${GIT_COMMIT_HASH}")
endif ()
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${CMAKE_CURRENT_SOURCE_DIR}/.git rev-parse
--abbrev-ref HEAD OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE gb)
if (gb)
set(GIT_BRANCH "${gb}")
message(STATUS gb: ${GIT_BRANCH})
add_definitions(-DGIT_BRANCH="${GIT_BRANCH}")
endif ()
endif () # git
if (thread_safety_analysis)
add_compile_options(-Wthread-safety -D_LIBCPP_ENABLE_THREAD_SAFETY_ANNOTATIONS
-DXRPL_ENABLE_THREAD_SAFETY_ANNOTATIONS)

21
cmake/GitInfo.cmake Normal file
View File

@@ -0,0 +1,21 @@
include_guard()
set(GIT_BUILD_BRANCH "")
set(GIT_COMMIT_HASH "")
find_package(Git)
if (NOT Git_FOUND)
message(WARNING "Git not found. Git branch and commit hash will be empty.")
return()
endif ()
set(GIT_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/.git)
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${GIT_DIRECTORY} rev-parse --abbrev-ref HEAD
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE GIT_BUILD_BRANCH)
execute_process(COMMAND ${GIT_EXECUTABLE} --git-dir=${GIT_DIRECTORY} rev-parse HEAD
OUTPUT_STRIP_TRAILING_WHITESPACE OUTPUT_VARIABLE GIT_COMMIT_HASH)
message(STATUS "Git branch: ${GIT_BUILD_BRANCH}")
message(STATUS "Git commit hash: ${GIT_COMMIT_HASH}")

View File

@@ -58,6 +58,12 @@ include(target_link_modules)
add_module(xrpl beast)
target_link_libraries(xrpl.libxrpl.beast PUBLIC xrpl.imports.main)
include(GitInfo)
add_module(xrpl git)
target_compile_definitions(xrpl.libxrpl.git PRIVATE GIT_COMMIT_HASH="${GIT_COMMIT_HASH}"
GIT_BUILD_BRANCH="${GIT_BUILD_BRANCH}")
target_link_libraries(xrpl.libxrpl.git PUBLIC xrpl.imports.main)
# Level 02
add_module(xrpl basics)
target_link_libraries(xrpl.libxrpl.basics PUBLIC xrpl.libxrpl.beast)
@@ -71,7 +77,8 @@ target_link_libraries(xrpl.libxrpl.crypto PUBLIC xrpl.libxrpl.basics)
# Level 04
add_module(xrpl protocol)
target_link_libraries(xrpl.libxrpl.protocol PUBLIC xrpl.libxrpl.crypto xrpl.libxrpl.json)
target_link_libraries(xrpl.libxrpl.protocol PUBLIC xrpl.libxrpl.crypto xrpl.libxrpl.git
xrpl.libxrpl.json)
# Level 05
add_module(xrpl core)
@@ -135,6 +142,7 @@ target_link_modules(
conditions
core
crypto
git
json
ledger
net

View File

@@ -23,6 +23,7 @@ install(TARGETS common
xrpl.libxrpl.conditions
xrpl.libxrpl.core
xrpl.libxrpl.crypto
xrpl.libxrpl.git
xrpl.libxrpl.json
xrpl.libxrpl.rdb
xrpl.libxrpl.ledger

View File

@@ -1,6 +1,7 @@
#pragma once
#include <string>
#include <string_view>
#include <vector>
namespace beast {
@@ -26,14 +27,14 @@ public:
SemanticVersion();
SemanticVersion(std::string const& version);
SemanticVersion(std::string_view version);
/** Parse a semantic version string.
The parsing is as strict as possible.
@return `true` if the string was parsed.
*/
bool
parse(std::string const& input);
parse(std::string_view input);
/** Produce a string from semantic version components. */
std::string

13
include/xrpl/git/Git.h Normal file
View File

@@ -0,0 +1,13 @@
#pragma once
#include <string>
namespace xrpl::git {
std::string const&
getCommitHash();
std::string const&
getBuildBranch();
} // namespace xrpl::git

View File

@@ -49,7 +49,7 @@ getFullVersionString();
@return the encoded version in a 64-bit integer
*/
std::uint64_t
encodeSoftwareVersion(char const* const versionStr);
encodeSoftwareVersion(std::string_view versionStr);
/** Returns this server's version packed in a 64-bit integer. */
std::uint64_t

View File

@@ -138,14 +138,14 @@ SemanticVersion::SemanticVersion() : majorVersion(0), minorVersion(0), patchVers
{
}
SemanticVersion::SemanticVersion(std::string const& version) : SemanticVersion()
SemanticVersion::SemanticVersion(std::string_view version) : SemanticVersion()
{
if (!parse(version))
throw std::invalid_argument("invalid version string");
}
bool
SemanticVersion::parse(std::string const& input)
SemanticVersion::parse(std::string_view input)
{
// May not have leading or trailing whitespace
auto left_iter = std::find_if_not(input.begin(), input.end(), [](std::string::value_type c) {

31
src/libxrpl/git/Git.cpp Normal file
View File

@@ -0,0 +1,31 @@
#include "xrpl/git/Git.h"
#include <string>
#ifndef GIT_COMMIT_HASH
#error "GIT_COMMIT_HASH must be defined"
#endif
#ifndef GIT_BUILD_BRANCH
#error "GIT_BUILD_BRANCH must be defined"
#endif
namespace xrpl::git {
static constexpr char kGIT_COMMIT_HASH[] = GIT_COMMIT_HASH;
static constexpr char kGIT_BUILD_BRANCH[] = GIT_BUILD_BRANCH;
std::string const&
getCommitHash()
{
static std::string const kVALUE = kGIT_COMMIT_HASH;
return kVALUE;
}
std::string const&
getBuildBranch()
{
static std::string const kVALUE = kGIT_BUILD_BRANCH;
return kVALUE;
}
} // namespace xrpl::git

View File

@@ -1,6 +1,7 @@
#include <xrpl/basics/contract.h>
#include <xrpl/beast/core/LexicalCast.h>
#include <xrpl/beast/core/SemanticVersion.h>
#include <xrpl/git/Git.h>
#include <xrpl/protocol/BuildInfo.h>
#include <boost/preprocessor/stringize.hpp>
@@ -14,44 +15,60 @@ namespace xrpl {
namespace BuildInfo {
namespace {
//--------------------------------------------------------------------------
// The build version number. You must edit this for each release
// and follow the format described at http://semver.org/
//------------------------------------------------------------------------------
// clang-format off
char const* const versionString = "3.2.0-b0"
// clang-format on
#if defined(DEBUG) || defined(SANITIZERS)
"+"
#ifdef GIT_COMMIT_HASH
GIT_COMMIT_HASH
"."
#endif
#ifdef DEBUG
"DEBUG"
#ifdef SANITIZERS
"."
#endif
#endif
#ifdef SANITIZERS
BOOST_PP_STRINGIZE(SANITIZERS) // cspell: disable-line
#endif
#endif
//--------------------------------------------------------------------------
// clang-format on
;
//
// Don't touch anything below this line
//
std::string
buildVersionString()
{
std::string version = versionString;
#if defined(DEBUG) || defined(SANITIZERS)
std::string metadata;
std::string const& commitHash = xrpl::git::getCommitHash();
if (!commitHash.empty())
metadata += commitHash + ".";
#ifdef DEBUG
metadata += "DEBUG";
#endif
#if defined(DEBUG) && defined(SANITIZERS)
metadata += ".";
#endif
#ifdef SANITIZERS
metadata += BOOST_PP_STRINGIZE(SANITIZERS); // cspell: disable-line
#endif
if (!metadata.empty())
version += "+" + metadata;
#endif
return version;
}
} // namespace
std::string const&
getVersionString()
{
static std::string const value = [] {
std::string const s = versionString;
std::string const s = buildVersionString();
beast::SemanticVersion v;
if (!v.parse(s) || v.print() != s)
LogicError(s + ": Bad server version string");
@@ -71,13 +88,13 @@ static constexpr std::uint64_t implementationVersionIdentifier = 0x183B'0000'000
static constexpr std::uint64_t implementationVersionIdentifierMask = 0xFFFF'0000'0000'0000LLU;
std::uint64_t
encodeSoftwareVersion(char const* const versionStr)
encodeSoftwareVersion(std::string_view versionStr)
{
std::uint64_t c = implementationVersionIdentifier;
beast::SemanticVersion v;
if (v.parse(std::string(versionStr)))
if (v.parse(versionStr))
{
if (v.majorVersion >= 0 && v.majorVersion <= 255)
c |= static_cast<std::uint64_t>(v.majorVersion) << 40;
@@ -137,7 +154,7 @@ encodeSoftwareVersion(char const* const versionStr)
std::uint64_t
getEncodedVersion()
{
static std::uint64_t const cookie = {encodeSoftwareVersion(versionString)};
static std::uint64_t const cookie = {encodeSoftwareVersion(getVersionString())};
return cookie;
}

View File

@@ -6,6 +6,7 @@
#include <xrpl/basics/Log.h>
#include <xrpl/beast/core/CurrentThreadName.h>
#include <xrpl/git/Git.h>
#include <xrpl/protocol/BuildInfo.h>
#include <xrpl/server/Vacuum.h>
@@ -476,12 +477,8 @@ run(int argc, char** argv)
if (vm.count("version"))
{
std::cout << "rippled version " << BuildInfo::getVersionString() << std::endl;
#ifdef GIT_COMMIT_HASH
std::cout << "Git commit hash: " << GIT_COMMIT_HASH << std::endl;
#endif
#ifdef GIT_BRANCH
std::cout << "Git build branch: " << GIT_BRANCH << std::endl;
#endif
std::cout << "Git commit hash: " << xrpl::git::getCommitHash() << std::endl;
std::cout << "Git build branch: " << xrpl::git::getBuildBranch() << std::endl;
return 0;
}

View File

@@ -40,6 +40,7 @@
#include <xrpl/core/PerfLog.h>
#include <xrpl/crypto/RFC1751.h>
#include <xrpl/crypto/csprng.h>
#include <xrpl/git/Git.h>
#include <xrpl/ledger/AmendmentTable.h>
#include <xrpl/ledger/OrderBookDB.h>
#include <xrpl/protocol/BuildInfo.h>
@@ -2593,17 +2594,14 @@ NetworkOPsImp::getServerInfo(bool human, bool admin, bool counters)
}
}
#if defined(GIT_COMMIT_HASH) || defined(GIT_BRANCH)
if (!xrpl::git::getCommitHash().empty() || !xrpl::git::getBuildBranch().empty())
{
auto& x = (info[jss::git] = Json::objectValue);
#ifdef GIT_COMMIT_HASH
x[jss::hash] = GIT_COMMIT_HASH;
#endif
#ifdef GIT_BRANCH
x[jss::branch] = GIT_BRANCH;
#endif
if (!xrpl::git::getCommitHash().empty())
x[jss::hash] = xrpl::git::getCommitHash();
if (!xrpl::git::getBuildBranch().empty())
x[jss::branch] = xrpl::git::getBuildBranch();
}
#endif
}
info[jss::io_latency_ms] = static_cast<Json::UInt>(registry_.app().getIOLatency().count());