diff options
-rw-r--r-- | CMakeLists.txt | 6 | ||||
-rw-r--r-- | cmake/CheckGit.cmake | 84 | ||||
-rw-r--r-- | cmake/git_version.hpp.in | 15 | ||||
-rw-r--r-- | include/libfud.hpp | 16 | ||||
-rw-r--r-- | source/libfud.cpp | 16 | ||||
-rw-r--r-- | test/CMakeLists.txt | 2 | ||||
-rw-r--r-- | test/test_fud.cpp | 42 |
7 files changed, 173 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 45387ce..f372f97 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -32,6 +32,7 @@ include(cmake/warnings.cmake) target_compile_options(fud PRIVATE "${FUD_WARNINGS}") target_include_directories(fud PUBLIC include ${SQLite3_INCLUDE_DIRS}) +target_include_directories(fud PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/include) target_link_libraries(fud ${SQLite3_LIBRARIES}) @@ -110,3 +111,8 @@ install(TARGETS fud PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/ ) +include(cmake/CheckGit.cmake) +CheckGitSetup(GIT_HASH) + +configure_file(cmake/git_version.hpp.in include/git_version.hpp @ONLY) +add_dependencies(fud AlwaysCheckGit) diff --git a/cmake/CheckGit.cmake b/cmake/CheckGit.cmake new file mode 100644 index 0000000..bd17447 --- /dev/null +++ b/cmake/CheckGit.cmake @@ -0,0 +1,84 @@ +set(CURRENT_LIST_DIR ${CMAKE_CURRENT_LIST_DIR}) +if (NOT DEFINED pre_configure_dir) + set(pre_configure_dir ${CMAKE_CURRENT_LIST_DIR}) +endif () + +if (NOT DEFINED post_configure_dir) + set(post_configure_dir ${CMAKE_BINARY_DIR}/include) +endif () + +set(pre_configure_file ${pre_configure_dir}/git_version.hpp.in) +set(post_configure_file ${post_configure_dir}/git_version.hpp) + +function(CheckGitWrite git_hash) + file(WRITE ${CMAKE_BINARY_DIR}/git-state.txt ${git_hash}) +endfunction() + +function(CheckGitRead git_hash) + if (EXISTS ${CMAKE_BINARY_DIR}/git-state.txt) + file(STRINGS ${CMAKE_BINARY_DIR}/git-state.txt CONTENT) + LIST(GET CONTENT 0 var) + + set(${git_hash} ${var} PARENT_SCOPE) + endif () +endfunction() + +function(CheckGitVersion git_hash) + # Get the latest abbreviated commit hash of the working branch + execute_process( + COMMAND git log -1 --format=%H + WORKING_DIRECTORY ${CMAKE_CURRENT_LIST_DIR} + OUTPUT_VARIABLE GIT_HASH + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + + CheckGitRead(GIT_HASH_CACHE) + if (NOT EXISTS ${post_configure_dir}) + file(MAKE_DIRECTORY ${post_configure_dir}) + endif () + + # if (NOT EXISTS ${post_configure_dir}/git_version.h) + # file(COPY ${pre_configure_dir}/git_version.h DESTINATION ${post_configure_dir}) + # endif() + + if (NOT DEFINED GIT_HASH_CACHE) + set(GIT_HASH_CACHE "INVALID") + endif () + + # Only update the git_version.cpp if the hash has changed. This will + # prevent us from rebuilding the project more than we need to. + if (NOT ${GIT_HASH} STREQUAL ${GIT_HASH_CACHE} OR NOT EXISTS ${post_configure_file}) + # Set che GIT_HASH_CACHE variable the next build won't have + # to regenerate the source file. + CheckGitWrite(${GIT_HASH}) + + configure_file(${pre_configure_file} ${post_configure_file} @ONLY) + endif () + set(${git_hash} ${GIT_HASH} PARENT_SCOPE) + + +endfunction() + +function(CheckGitSetup top_git_hash) + + add_custom_target(AlwaysCheckGit COMMAND ${CMAKE_COMMAND} + -DRUN_CHECK_GIT_VERSION=1 + -Dpre_configure_dir=${pre_configure_dir} + -Dpost_configure_file=${post_configure_dir} + -DGIT_HASH_CACHE=${GIT_HASH_CACHE} + -P ${CURRENT_LIST_DIR}/CheckGit.cmake + BYPRODUCTS ${post_configure_file} + ) + + add_library(git_version INTERFACE ${CMAKE_BINARY_DIR}/include/git_version.hpp) + add_dependencies(git_version AlwaysCheckGit) + + CheckGitVersion(git_hash) + set(${top_git_hash} ${git_hash} PARENT_SCOPE) +endfunction() + +# This is used to run this function from an external cmake process. +if (RUN_CHECK_GIT_VERSION) + CheckGitVersion(git_hash) + set(${GIT_HASH} ${git_hash}) +endif () diff --git a/cmake/git_version.hpp.in b/cmake/git_version.hpp.in new file mode 100644 index 0000000..ede9623 --- /dev/null +++ b/cmake/git_version.hpp.in @@ -0,0 +1,15 @@ +#ifndef GIT_VERSION_HPP +#define GIT_VERSION_HPP + +#include <cstdint> + +namespace fud { + +constexpr uint8_t FudVersionMajor = @PROJECT_VERSION_MAJOR@; +constexpr uint8_t FudVersionMinor = @PROJECT_VERSION_MINOR@; +constexpr uint8_t FudVersionPatch = @PROJECT_VERSION_PATCH@; +constexpr const char GitHash[] = "@GIT_HASH@"; + +} // namespace fud + +#endif diff --git a/include/libfud.hpp b/include/libfud.hpp index c4fa8d7..70165b3 100644 --- a/include/libfud.hpp +++ b/include/libfud.hpp @@ -21,22 +21,22 @@ #include "fud_result.hpp" #include "fud_status.hpp" #include "fud_string.hpp" +#include "fud_array.hpp" #include <cstdint> namespace fud { +constexpr size_t GIT_REV_CHARS = 13; + struct FUD { - uint8_t Major; - uint8_t Minor; - uint8_t Patch; + uint8_t major; + uint8_t minor; + uint8_t patch; + Array<char, GIT_REV_CHARS> revision; }; -/** \brief Fear, unknown, doubt. Call at your own peril. */ -constexpr FUD fud() -{ - return FUD{0, 42, 0}; -} +FUD fud(); /** * \brief Get an environmental variable if it exists. diff --git a/source/libfud.cpp b/source/libfud.cpp index e1dad1d..252eae0 100644 --- a/source/libfud.cpp +++ b/source/libfud.cpp @@ -17,10 +17,26 @@ #include "libfud.hpp" +#include "fud_assert.hpp" +#include "git_version.hpp" + #include <cstdlib> namespace fud { +FUD fud() +{ + FUD fudInfo{}; + fudInfo.major = FudVersionMajor; + fudInfo.minor = FudVersionMinor; + fudInfo.patch = FudVersionPatch; + static_assert(sizeof(GitHash) >= sizeof(fudInfo.revision)); + auto copyResult = copyMem(fudInfo.revision.data(), fudInfo.revision.size(), GitHash, fudInfo.revision.size() - 1); + fudAssert(copyResult == FudStatus::Success); + fudInfo.revision[fudInfo.revision.size() - 1] = '\0'; + return fudInfo; +} + Result<String, FudStatus> getEnv(const char* name) { using RetType = Result<String, FudStatus>; diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index 9061d55..19a5b98 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -36,6 +36,7 @@ function(fud_add_test test_name) target_include_directories(${test_name} PUBLIC $<TARGET_PROPERTY:fud>) target_link_libraries(${test_name} PUBLIC GTest::gtest_main fud) + target_include_directories(${test_name} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/../include) target_compile_options(${test_name} PRIVATE ${CVG_FLAGS}) target_link_options(${test_name} PRIVATE ${CVG_FLAGS}) @@ -51,6 +52,7 @@ function(fud_add_test test_name) gtest_discover_tests(${test_name}) endfunction() +fud_add_test(test_fud SOURCES test_fud.cpp) fud_add_test(test_result SOURCES test_result.cpp) fud_add_test(test_string SOURCES test_string.cpp) fud_add_test(test_sqlite SOURCES test_sqlite.cpp) diff --git a/test/test_fud.cpp b/test/test_fud.cpp new file mode 100644 index 0000000..a6519fb --- /dev/null +++ b/test/test_fud.cpp @@ -0,0 +1,42 @@ +/* + * libfud + * Copyright 2024 Dominick Allen + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "git_version.hpp" +#include "libfud.hpp" + +#include "gtest/gtest.h" + +namespace fud { + +TEST(FudTest, FudFud) +{ + FUD fudInfo{fud()}; + + EXPECT_EQ(fudInfo.major, FudVersionMajor); + EXPECT_EQ(fudInfo.minor, FudVersionMinor); + EXPECT_EQ(fudInfo.patch, FudVersionPatch); + auto compareResult = compareMem( + fudInfo.revision.data(), + fudInfo.revision.size(), + GitHash, + fudInfo.revision.size() - 1); + ASSERT_TRUE(compareResult.isOkay()); + EXPECT_EQ(compareResult.getOkay(), 0); + EXPECT_EQ(fudInfo.revision[fudInfo.revision.size() - 1], '\0'); +} + +} // namespace fud |