diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 8700f59a58bc2a0aa50b4c93295eaf194342494b..557914a85cddeafc9c7db872061eafdb7b138ae8 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -38,4 +38,8 @@ check-recipes: - cmake --build 05_build - 05_build/version-info - - cmake -S 06_git_configure -B 06_build \ No newline at end of file + - cmake -S 06_git_configure -B 06_build + + - cmake -S 07_git_build -B 07_build + - cmake --build 07_build + - 07_build/git-hash \ No newline at end of file diff --git a/07_git_build/CMakeLists.txt b/07_git_build/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..07bfea8b33a0f4d2a54ef23bf86e519e4844ba70 --- /dev/null +++ b/07_git_build/CMakeLists.txt @@ -0,0 +1,27 @@ +cmake_minimum_required(VERSION 3.20) + +project(07_git_build + LANGUAGES CXX) + +add_executable(git-hash) +target_sources(git-hash PRIVATE main.cpp githash.hpp) +target_sources(git-hash PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/githash.cpp) +target_include_directories(git-hash PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}) + +set(GIT_HASH_INPUT ${CMAKE_CURRENT_SOURCE_DIR}/githash.cpp.in) +set(GIT_HASH_OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/githash.cpp) +add_custom_command( + OUTPUT + ${GIT_HASH_OUTPUT} + ALL + COMMAND + ${CMAKE_COMMAND} -DINPUT_FILE=${GIT_HASH_INPUT} -DOUTPUT_FILE=${GIT_HASH_OUTPUT} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmake/update_git_hash.cmake +) +add_custom_target( + update-git-hash + ALL + DEPENDS + ${GIT_HASH_OUTPUT} +) +add_dependencies(git-hash update-git-hash) + diff --git a/07_git_build/README.md b/07_git_build/README.md new file mode 100644 index 0000000000000000000000000000000000000000..f7834726819c0f658d10f015e2e0a85743afa172 --- /dev/null +++ b/07_git_build/README.md @@ -0,0 +1,18 @@ +# How to get the current git hash at build time? + +We will use the ability of CMake to run as an interpreter +[interpreter](https://cmake.org/cmake/help/latest/manual/cmake.1.html#run-a-script) +to retrieve the git hash at runtime. +The idea works as follows: + * Use [How to get the current git hash at configure time?](06_git_configure) to get the git hash. + * Use [How to pass information from CMake to your code?](05_configure_file) to write the hash + into a source file. + * Move the logic into a separate CMake [file](cmake/update_git_hash.cmake). + * Use [add_custom_command](https://cmake.org/cmake/help/latest/command/add_custom_command.html) + to invoke the [CMake interpreter](https://cmake.org/cmake/help/latest/manual/cmake.1.html#run-a-script). + * Move everything into its own target to allow parallel execution: + [add_custom_target](https://cmake.org/cmake/help/latest/command/add_custom_target.html). + * Add a [dependency](https://cmake.org/cmake/help/latest/command/add_dependencies.html) + so it gets executed whenever the project is rebuild. + +Note, we configure a cpp file here to avoid recompilation of huge portions of the code! \ No newline at end of file diff --git a/07_git_build/cmake/update_git_hash.cmake b/07_git_build/cmake/update_git_hash.cmake new file mode 100644 index 0000000000000000000000000000000000000000..c7646914f35bfb9f934ecb5b8ec5076a5e20d59c --- /dev/null +++ b/07_git_build/cmake/update_git_hash.cmake @@ -0,0 +1,18 @@ +set(GIT_HASH "unknown") + +find_package(Git QUIET) +if (GIT_FOUND) + execute_process( + COMMAND ${GIT_EXECUTABLE} log -1 --pretty=format:%H + OUTPUT_VARIABLE GIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} + ) +endif () + +configure_file( + ${INPUT_FILE} + ${OUTPUT_FILE} + @ONLY +) \ No newline at end of file diff --git a/07_git_build/githash.cpp.in b/07_git_build/githash.cpp.in new file mode 100644 index 0000000000000000000000000000000000000000..178f2de3100dac09b0806ec861db3687bbbdf081 --- /dev/null +++ b/07_git_build/githash.cpp.in @@ -0,0 +1,3 @@ +#include "githash.hpp" + +char const * GIT_HASH = "@GIT_HASH@"; diff --git a/07_git_build/githash.hpp b/07_git_build/githash.hpp new file mode 100644 index 0000000000000000000000000000000000000000..f71c94daffde3d6aeceb258b6812289555aacaaf --- /dev/null +++ b/07_git_build/githash.hpp @@ -0,0 +1,3 @@ +#pragma once + +extern char const * GIT_HASH; diff --git a/07_git_build/main.cpp b/07_git_build/main.cpp new file mode 100644 index 0000000000000000000000000000000000000000..603b43e5551fa82a438b78a574a93573798f2fbe --- /dev/null +++ b/07_git_build/main.cpp @@ -0,0 +1,9 @@ +#include <iostream> + +#include "githash.hpp" + +int main() +{ + std::cout << "git hash: " << GIT_HASH << std::endl; + exit(EXIT_SUCCESS); +} diff --git a/README.md b/README.md index 315c99b2400016468feec9f9331035f2f345ea09..c38c340990d003c4716478d95d059624347a3f70 100644 --- a/README.md +++ b/README.md @@ -14,6 +14,7 @@ we run them in our CI. * [Local and cache variables?](https://cliutils.gitlab.io/modern-cmake/chapters/basics/variables.html) * [How to pass information from CMake to your code?](05_configure_file) * [How to get the current git hash at configure time?](06_git_configure) + * [How to get the current git hash at build time?](07_git_build) ## Why CMake? * Automatically search for programs, libraries, and header files