Skip to content

Commit

Permalink
Merge pull request #966 from dkorolev/current_build_autogen_header_fo…
Browse files Browse the repository at this point in the history
…r_cmake
  • Loading branch information
mzhurovich authored Mar 10, 2024
2 parents 76ad8b9 + e75696b commit e5c9807
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 26 deletions.
17 changes: 16 additions & 1 deletion cmake/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,39 @@ function(UseOrGitClone dep remote branch)
message(STATUS "Using `${dep}` from `CMAKE_SOURCE_DIR/${dep}'.")
add_subdirectory("${CMAKE_SOURCE_DIR}/${dep}" ${dep})
message(STATUS "Using `${dep}` from `CMAKE_SOURCE_DIR/${dep}': Configured.")
set("SRC_DIR_${dep}" "${CMAKE_SOURCE_DIR}/${dep}" PARENT_SCOPE)
elseif(EXISTS "${CMAKE_SOURCE_DIR}/../${dep}" AND IS_DIRECTORY "${CMAKE_SOURCE_DIR}/../${dep}")
message(STATUS "Using `${dep}` from `CMAKE_SOURCE_DIR/../${dep}'.")
add_subdirectory("${CMAKE_SOURCE_DIR}/../${dep}" ${dep})
message(STATUS "Using `${dep}` from `CMAKE_SOURCE_DIR/../${dep}': Configured.")
set("SRC_DIR_${dep}" "${CMAKE_SOURCE_DIR}/../${dep}" PARENT_SCOPE)
elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/../${dep}" AND IS_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/../${dep}")
message(STATUS "Using `${dep}` from `CMAKE_CURRENT_SOURCE_DIR/../${dep}'.")
add_subdirectory("${CMAKE_CURRENT_SOURCE_DIR}/../${dep}" ${dep})
message(STATUS "Using `${dep}` from `CMAKE_CURRENT_SOURCE_DIR/../${dep}': Configured.")
set("SRC_DIR_${dep}" "${CMAKE_CURRENT_SOURCE_DIR}/../${dep}" PARENT_SCOPE)
else()
message(STATUS "Cloning `${dep}` from `${remote}:${branch}` ...")
execute_process(OUTPUT_QUIET ERROR_QUIET COMMAND git clone --depth 1 -b ${branch} ${remote})
file(TOUCH .gitignore)
file(APPEND .gitignore "${dep}/\n")
add_subdirectory("${CMAKE_SOURCE_DIR}/${dep}" ${dep})
message(STATUS "Cloning `${dep}` from `${remote}:${branch}`: Configured.")
set("SRC_DIR_${dep}" "${CMAKE_SOURCE_DIR}/${dep}" PARENT_SCOPE)
endif()
endfunction()

UseOrGitClone(current https://github.com/c5t/current stable)
# NOTE(dkorolev): This is about to be changed back once https://github.com/C5T/Current/pull/966 is merged!
UseOrGitClone(current https://github.com/dkorolev/current current_build_autogen_header_for_cmake)
UseOrGitClone(googletest https://github.com/c5t/googletest v1.14)

add_custom_target(C5T_CURRENT_BUILD_H_TARGET ALL DEPENDS "${SRC_DIR_current}/current_build.h")

add_custom_command(OUTPUT "${SRC_DIR_current}/current_build.h"
COMMAND "${SRC_DIR_current}/scripts/gen-current-build.sh"
ARGS "${SRC_DIR_current}/current_build.h"
DEPENDS src)

set(C5T_LIBRARIES "Threads::Threads" "C5T")

# Declare shared libraries as shared library targets. Do not link them against anything external.
Expand All @@ -46,6 +58,7 @@ foreach(SHARED_LIBRARY_SOURCE_FILE ${BINARY_SOURCE_FILES})
get_filename_component(SHARED_LIBRARY_TARGET_NAME "${SHARED_LIBRARY_SOURCE_FILE}" NAME_WE)
add_library(${SHARED_LIBRARY_TARGET_NAME} SHARED "${SHARED_LIBRARY_SOURCE_FILE}")
# TODO(dkorolev): Might be worth it to `grep` this `dlib_*.cc` source file for required library dependencies.
target_compile_definitions(${SHARED_LIBRARY_TARGET_NAME} PRIVATE C5T_CMAKE_PROJECT)
target_link_libraries(${SHARED_LIBRARY_TARGET_NAME} PRIVATE "${C5T_LIBRARIES}")
endforeach()

Expand All @@ -55,6 +68,7 @@ file(GLOB_RECURSE LIBRARY_SOURCE_FILES "src/lib_*.cc")
foreach(LIBRARY_SOURCE_FILE ${LIBRARY_SOURCE_FILES})
get_filename_component(LIBRARY_TARGET_NAME "${LIBRARY_SOURCE_FILE}" NAME_WE)
add_library(${LIBRARY_TARGET_NAME} "${LIBRARY_SOURCE_FILE}")
target_compile_definitions(${LIBRARY_TARGET_NAME} PRIVATE C5T_CMAKE_PROJECT)
target_link_libraries(${LIBRARY_TARGET_NAME} PRIVATE "${C5T_LIBRARIES}")
list(APPEND ALL_LIBRARIES "${LIBRARY_TARGET_NAME}")
endforeach()
Expand All @@ -65,6 +79,7 @@ foreach(BINARY_SOURCE_FILE ${BINARY_SOURCE_FILES})
get_filename_component(BINARY_TARGET_NAME "${BINARY_SOURCE_FILE}" NAME_WE)
if(NOT (BINARY_TARGET_NAME MATCHES "^lib_.*$" OR BINARY_TARGET_NAME MATCHES "^test_.*$" OR BINARY_TARGET_NAME MATCHES "^dlib_.*$"))
add_executable(${BINARY_TARGET_NAME} "${BINARY_SOURCE_FILE}")
target_compile_definitions(${BINARY_TARGET_NAME} PRIVATE C5T_CMAKE_PROJECT)
target_link_libraries(${BINARY_TARGET_NAME} PRIVATE "${ALL_LIBRARIES}")
endif()
endforeach()
Expand Down
40 changes: 40 additions & 0 deletions cmake/run-cmake-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,43 @@ echo "::group::.current_debug/hw"
.current_debug/hw
echo "::endgroup::"

echo

# Test that the `current_build.h` file is generated automatically for each build.
echo "::group::build build_info"
cat >src/build_info.cc <<EOF
#include <iostream>
#ifndef C5T_CMAKE_PROJECT
#error "'C5T_CMAKE_PROJECT' is not defined, are you using Current under 'cmake' with the proper 'CMakeLists.txt'?"
#endif
#include "current_build.h"
int main() {
std::cout << "Successfully built at: " << current::build::cmake::kBuildDateTime << std::endl;
}
EOF
make
echo "::endgroup::"

echo

echo "::group::run build_info"
.current/build_info
echo "::endgroup::"

echo

echo "::group::re-run build_info"
sleep 1
touch src/build_info.cc
make
.current/build_info
echo "::endgroup::"

# This runs `cmake .` for Release mode, which is output into `.current`.
echo "::group::configure"
make .current
echo "::endgroup::"

cat >src/lib_add.cc <<EOF
#include "lib_add.h"
int lib_add(int a, int b) {
Expand Down Expand Up @@ -126,6 +163,9 @@ TEST(SmokeCurrentGoogletest, TwoPlusThree) {
}
EOF

# Force re-configure after adding more into `src/`, appears to be important on the `macos-latest` GitHub test runner.
touch CMakeLists.txt

echo

echo "::group::release_test"
Expand Down
50 changes: 25 additions & 25 deletions scripts/gen-current-build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -9,28 +9,16 @@ if [[ $? -ne 0 ]]; then
exit 1
fi

COMPILER_INFO="$($CPLUSPLUS -v 2>&1)"
COMPILER_INFO="$(${CPLUSPLUS:-g++} -v 2>&1)"
if [[ $? -ne 0 ]]; then
exit 1
fi
COMPILER_INFO=${COMPILER_INFO//$'\n'/\\n} # JSON-friendly newlines.

GIT_COMMIT="$(git rev-parse HEAD)"
if [[ $? -ne 0 ]]; then
exit 1
fi

GIT_BRANCH="$(git rev-parse --abbrev-ref HEAD)"
if [[ $? -ne 0 ]]; then
exit 1
fi

GIT_STATUS="$(git status)"
if [[ $? -ne 0 ]]; then
exit 1
fi

GIT_DIFF_NAMES_MULTILINE="$(git diff --name-only)"
GIT_COMMIT="$(git rev-parse HEAD 2>/dev/null || echo '<not under git>')"
GIT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '<not under git>')"
GIT_STATUS="$(git status 2>/dev/null || echo '<not under git>')"
GIT_DIFF_NAMES_MULTILINE="$(git diff --name-only 2>/dev/null || echo '<not under git>')"
GIT_DIFF_NAMES=${GIT_DIFF_NAMES_MULTILINE//$'\n'/\\n}

if [[ "$OSTYPE" == "darwin"* ]]; then
Expand All @@ -39,45 +27,51 @@ else
MD5SUM=md5sum
fi

GIT_DIFF_MD5SUM="$(git diff --no-ext-diff | $MD5SUM)"
if [[ $? -ne 0 ]]; then
exit 1
fi
GIT_DIFF_MD5SUM="$(git diff --no-ext-diff 2>/dev/null | $MD5SUM || echo '<not under git>')"

cat >${1:-/dev/stdout} << EOF
// NOTE: With 'C5T_CMAKE_PROJECT' '#define'-d it takes ~0.03 seconds to "build" this file.
cat >$1 << EOF
// clang-format off
#ifndef CURRENT_BUILD_H
#define CURRENT_BUILD_H
#ifndef C5T_CMAKE_PROJECT
#include "$SCRIPT_DIR/../port.h"
#include <chrono>
#include <ctime>
#include <vector>
#include <string>
#include "$SCRIPT_DIR/../typesystem/struct.h"
#include "$SCRIPT_DIR/../typesystem/optional.h"
#include "$SCRIPT_DIR/../bricks/strings/split.h"
#endif // C5T_CMAKE_PROJECT
namespace current {
namespace build {
#ifdef C5T_CMAKE_PROJECT
namespace cmake {
#endif // C5T_CMAKE_PROJECT
constexpr static const char* kBuildDateTime = __DATE__ ", " __TIME__;
constexpr static const char* kGitCommit = "$GIT_COMMIT";
constexpr static const char* kGitBranch = "$GIT_BRANCH";
constexpr static const char* kOS = "$OS_VERSION";
constexpr static const char* kCompiler = "$CPLUSPLUS";
constexpr static const char* kCompiler = "${CPLUSPLUS:-default[g++]}";
constexpr static const char* kCompilerFlags = "$CPPFLAGS";
constexpr static const char* kLinkerFlags = "$LDFLAGS";
constexpr static const char* kCompilerInfo = "$COMPILER_INFO";
#ifndef C5T_CMAKE_PROJECT
inline const std::vector<std::string>& GitDiffNames() {
static std::vector<std::string> result = current::strings::Split("$GIT_DIFF_NAMES", '\n');
return result;
}
// TODO(dkorolev): Maybe this function should be elsewhere, under some "proper" Current source dir?
// A hacky, but cross-platform way to parse \`kBuildDateTime\` since:
// * \`__DATE__\` always contains English months,
// * GCC < 5.0 doesn't have \`get_time\`,
Expand Down Expand Up @@ -201,6 +195,12 @@ CURRENT_STRUCT(BuildInfo) {
return !operator==(rhs);
}
};
#endif // C5T_CMAKE_PROJECT
#ifdef C5T_CMAKE_PROJECT
} // namespace current::build::cmake
using namespace cmake;
#endif // C5T_CMAKE_PROJECT
} // namespace current::build
} // namespace current
Expand Down

0 comments on commit e5c9807

Please sign in to comment.