summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt6
-rw-r--r--cmake/CheckGit.cmake84
-rw-r--r--cmake/git_version.hpp.in15
-rw-r--r--include/libfud.hpp16
-rw-r--r--source/libfud.cpp16
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/test_fud.cpp42
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