diff --git a/CMakeLists.txt b/CMakeLists.txt index eddda01b..5bb596ab 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,8 @@ cmake_minimum_required(VERSION 3.14.1) - project(C5T LANGUAGES C CXX) -message(STATUS "Add `C5T` into `target_link_libraries()` of your `CMakeLists.txt` to use `current` headers.") - -add_library(C5T INTERFACE) -target_include_directories(C5T INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") +if (NOT TARGET C5T) + message(STATUS "Add `C5T` into `target_link_libraries()` of your `CMakeLists.txt` to use `current` headers.") + add_library(C5T INTERFACE) + target_include_directories(C5T INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") +endif() diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt index e390faea..5be5d346 100644 --- a/cmake/CMakeLists.txt +++ b/cmake/CMakeLists.txt @@ -67,13 +67,15 @@ function(UseGitOrCloneBranch remote branch) UseGitOrCloneImpl("${remote}" TRUE "${branch}") endfunction() -UseGitOrClone(https://github.com/c5t/current) +UseGitOrCloneBranch(https://github.com/dkorolev/current use_current_deps_github_org) # Set `C5T_NO_GTEST` in the `Makefile` to any non-empty value to speed up the builds that do not need `googletest`. -if("$ENV{C5T_NO_GTEST}" STREQUAL "") - UseGitOrClone(https://github.com/c5t/googletest) -else() - message(STATUS "Skipping `googletest` as `C5T_NO_GTEST` is set.") +if(NOT TARGET gtest) + if("$ENV{C5T_NO_GTEST}" STREQUAL "") + UseGitOrClone(https://github.com/current-deps/googletest) + else() + message(STATUS "Skipping `googletest` as `C5T_NO_GTEST` is set.") + endif() endif() set_property(GLOBAL PROPERTY C5T_PATH ${C5T_DEP_DIR_current}) @@ -83,20 +85,34 @@ if(NOT "${C5T_DEPS_1}" STREQUAL "") string(REPLACE ":" ";" C5T_DEPS_2 "${C5T_DEPS_1}") string(REPLACE " " ";" C5T_DEPS_3 "${C5T_DEPS_2}") foreach(C5T_DEP IN LISTS C5T_DEPS_3) - UseGitOrClone("https://github.com/c5t/${C5T_DEP}") + UseGitOrClone("https://github.com/current-deps/${C5T_DEP}") endforeach() endif() get_property(C5T_LIBRARIES GLOBAL PROPERTY C5T_LIBRARIES_PROPERTY) add_custom_target(C5T_CURRENT_BUILD_INFO_H_TARGET ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/inc/current_build_info.h") +add_custom_target(C5T_CUSTOM_PER_BUILD_SCRIPT_TARGET ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/inc/pre_build_sh_output.inl") add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/inc/current_build_info.h" COMMAND "${C5T_DEP_DIR_current}/scripts/gen-current-build.sh" ARGS "${CMAKE_CURRENT_BINARY_DIR}/inc/current_build_info.h" DEPENDS inc/current_build_info.h.force_rebuild) +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/inc") +if(EXISTS "${CMAKE_SOURCE_DIR}/src/pre_build.sh") + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/inc/pre_build_sh_output.inl" + COMMAND "${CMAKE_SOURCE_DIR}/src/pre_build.sh" + ARGS "${CMAKE_CURRENT_BINARY_DIR}/inc/pre_build_sh_output.inl" + WORKING_DIRECTORY "${CMAKE_SOURCE_DIR}" + DEPENDS inc/pre_build_sh_output.inl.force_rebuild) +else() + file(TOUCH "${CMAKE_CURRENT_BINARY_DIR}/inc/pre_build_sh_output.inl") + file(APPEND "${CMAKE_CURRENT_BINARY_DIR}/inc/pre_build_sh_output.inl" "#pragma once\n// No `src/pre_build.sh` found.\n") +endif() + add_custom_command(OUTPUT inc/current_build_info.h.force_rebuild COMMAND cmake -E echo >/dev/null) +add_custom_command(OUTPUT inc/pre_build_sh_output.inl.force_rebuild COMMAND cmake -E echo >/dev/null) if("${C5T_PROJECT_ROOT}" STREQUAL "") set(C5T_PROJECT_ROOT_SRC "src") @@ -109,33 +125,33 @@ file(GLOB_RECURSE BINARY_SOURCE_FILES "${C5T_PROJECT_ROOT_SRC}/dlib_*.cc") 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}") - add_dependencies(${SHARED_LIBRARY_TARGET_NAME} C5T_CURRENT_BUILD_INFO_H_TARGET) + add_dependencies(${SHARED_LIBRARY_TARGET_NAME} C5T_CURRENT_BUILD_INFO_H_TARGET C5T_CUSTOM_PER_BUILD_SCRIPT_TARGET) # 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_compile_definitions(${SHARED_LIBRARY_TARGET_NAME} PRIVATE C5T_DLIB) - target_include_directories(${SHARED_LIBRARY_TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/inc") + target_include_directories(${SHARED_LIBRARY_TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/inc" ${C5T_DEP_DIR_current}) target_link_libraries(${SHARED_LIBRARY_TARGET_NAME} PRIVATE "${C5T_LIBRARIES}") endforeach() -# Declare libraries as library targets. First, and add them into the `ALL_LIBRARIES` list. -set(ALL_LIBRARIES "${C5T_LIBRARIES}") +# Declare user-defined libraries as library targets. +set(USR_LIBRARIES) file(GLOB_RECURSE LIBRARY_SOURCE_FILES "${C5T_PROJECT_ROOT_SRC}/lib_*.cc") foreach(LIBRARY_SOURCE_FILE ${LIBRARY_SOURCE_FILES}) get_filename_component(LIBRARY_TARGET_NAME "${LIBRARY_SOURCE_FILE}" NAME_WE) - list(APPEND ALL_LIBRARIES "${LIBRARY_TARGET_NAME}") + list(APPEND USR_LIBRARIES "${LIBRARY_TARGET_NAME}") endforeach() # Then build all the libraries, such that every library is linked against every other library. file(GLOB_RECURSE LIBRARY_SOURCE_FILES "${C5T_PROJECT_ROOT_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}") - add_dependencies(${LIBRARY_TARGET_NAME} C5T_CURRENT_BUILD_INFO_H_TARGET) + add_library(${LIBRARY_TARGET_NAME} STATIC "${LIBRARY_SOURCE_FILE}") + add_dependencies(${LIBRARY_TARGET_NAME} C5T_CURRENT_BUILD_INFO_H_TARGET C5T_CUSTOM_PER_BUILD_SCRIPT_TARGET) target_compile_definitions(${LIBRARY_TARGET_NAME} PRIVATE C5T_CMAKE_PROJECT) - target_include_directories(${LIBRARY_TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/inc") - set(LIBRARY_DEPS_WO_SELF "${ALL_LIBRARIES}") - list(REMOVE_ITEM LIBRARY_DEPS_WO_SELF ${LIBRARY_TARGET_NAME}) - target_link_libraries(${LIBRARY_TARGET_NAME} PRIVATE "${LIBRARY_DEPS_WO_SELF}") + target_include_directories(${LIBRARY_TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/inc" ${C5T_DEP_DIR_current}) + set(USR_LIBRARIES_WO_SELF "${USR_LIBRARIES}") + list(REMOVE_ITEM USR_LIBRARIES_WO_SELF ${LIBRARY_TARGET_NAME}) + target_link_libraries(${LIBRARY_TARGET_NAME} PRIVATE "${USR_LIBRARIES_WO_SELF}") endforeach() # Declare binaries as binary targets. And link them against all the libraries. @@ -144,10 +160,11 @@ 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}") - add_dependencies(${BINARY_TARGET_NAME} C5T_CURRENT_BUILD_INFO_H_TARGET) + add_dependencies(${BINARY_TARGET_NAME} C5T_CURRENT_BUILD_INFO_H_TARGET C5T_CUSTOM_PER_BUILD_SCRIPT_TARGET) target_compile_definitions(${BINARY_TARGET_NAME} PRIVATE C5T_CMAKE_PROJECT) target_include_directories(${BINARY_TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/inc") - target_link_libraries(${BINARY_TARGET_NAME} PRIVATE "${ALL_LIBRARIES}") + target_link_libraries(${BINARY_TARGET_NAME} PRIVATE "${C5T_LIBRARIES}") + target_link_libraries(${BINARY_TARGET_NAME} PRIVATE "${USR_LIBRARIES}") endif() endforeach() @@ -157,8 +174,9 @@ file(GLOB_RECURSE TEST_SOURCE_FILES "${C5T_PROJECT_ROOT_SRC}/test_*.cc") foreach(TEST_SOURCE_FILE ${TEST_SOURCE_FILES}) get_filename_component(TEST_TARGET_NAME "${TEST_SOURCE_FILE}" NAME_WE) add_executable(${TEST_TARGET_NAME} "${TEST_SOURCE_FILE}") - add_dependencies(${TEST_TARGET_NAME} C5T_CURRENT_BUILD_INFO_H_TARGET) + add_dependencies(${TEST_TARGET_NAME} C5T_CURRENT_BUILD_INFO_H_TARGET C5T_CUSTOM_PER_BUILD_SCRIPT_TARGET) target_include_directories(${TEST_TARGET_NAME} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/inc") - target_link_libraries(${TEST_TARGET_NAME} PRIVATE gtest_main "${ALL_LIBRARIES}") + target_link_libraries(${TEST_TARGET_NAME} PRIVATE gtest_main "${C5T_LIBRARIES}") + target_link_libraries(${TEST_TARGET_NAME} PRIVATE "${USR_LIBRARIES}") add_test(NAME ${TEST_TARGET_NAME} COMMAND ${TEST_TARGET_NAME}) endforeach() diff --git a/cmake/Makefile b/cmake/Makefile index b30d6220..6af22f57 100644 --- a/cmake/Makefile +++ b/cmake/Makefile @@ -7,7 +7,7 @@ # # Besides, this `Makefiles` makes `:mak` in Vim work like a charm! -.PHONY: release debug release_dir debug_dir release_test debug_test test fmt clean +.PHONY: release debug _release_dir _debug_dir release_test debug_test test fmt clean # When this `Makefile` is used to run a `cmake`-based Current build, user-defined dependencies go here. # No quotes needed. Space- or colon- or semicolon-separated all work fine. @@ -29,22 +29,22 @@ endif CLANG_FORMAT=$(shell echo "$${CLANG_FORMAT:-clang-format}") -release: release_dir CMakeLists.txt +release: _release_dir CMakeLists.txt @MAKEFLAGS=--no-print-directory cmake --build "${RELEASE_BUILD_DIR}" -j ${CORES} -release_dir: ${RELEASE_BUILD_DIR} .gitignore +_release_dir: ${RELEASE_BUILD_DIR} .gitignore @grep "^${RELEASE_BUILD_DIR}/$$" .gitignore >/dev/null || echo "${RELEASE_BUILD_DIR}/" >>.gitignore ${RELEASE_BUILD_DIR}: CMakeLists.txt src @C5T_DEPS="${C5T_DEPS}" C5T_NO_GTEST="${C5T_NO_GTEST}" cmake -DCMAKE_BUILD_TYPE=Release -B "${RELEASE_BUILD_DIR}" . -test: release +release_test: release @(cd "${RELEASE_BUILD_DIR}"; make test) -debug: debug_dir CMakeLists.txt +debug: _debug_dir CMakeLists.txt @MAKEFLAGS=--no-print-directory cmake --build "${DEBUG_BUILD_DIR}" -j ${CORES} -debug_dir: ${DEBUG_BUILD_DIR} .gitignore +_debug_dir: ${DEBUG_BUILD_DIR} .gitignore @grep "^${DEBUG_BUILD_DIR}/$$" .gitignore >/dev/null || echo "${DEBUG_BUILD_DIR}/" >>.gitignore ${DEBUG_BUILD_DIR}: CMakeLists.txt src @@ -53,7 +53,7 @@ ${DEBUG_BUILD_DIR}: CMakeLists.txt src debug_test: debug @(cd "${DEBUG_BUILD_DIR}"; make test) -test: release_test +test: debug_test fmt: ${CLANG_FORMAT} -i src/*.cc src/*.h diff --git a/cmake/run-cmake-test.sh b/cmake/run-cmake-test.sh index 238138c5..e6db5716 100755 --- a/cmake/run-cmake-test.sh +++ b/cmake/run-cmake-test.sh @@ -173,7 +173,7 @@ touch CMakeLists.txt echo echo "::group::release_test" -make test +make release_test echo "::endgroup::" echo "::group::debug_test" @@ -185,14 +185,14 @@ echo touch src/test_gtest.cc T0_GTEST=$(date +%s) echo "::group::one line change google gtest release" -make test +make release_test echo "::endgroup::" T1_GTEST=$(date +%s) touch src/test_current_gtest.cc T0_CURRENT_GTEST=$(date +%s) echo "::group::one line change current gtest release" -make test +make release_test echo "::endgroup::" T1_CURRENT_GTEST=$(date +%s) @@ -269,7 +269,6 @@ touch CMakeLists.txt echo "::group::build .current/libdlib_mul.{so|dylib} and .current/call_dynamic_mul" make echo "::endgroup::" - echo "::group::build .current_debug/libdlib_mul.{so|dylib} and .current_debug/call_dynamic_mul" make debug echo "::endgroup::" diff --git a/scripts/gen-current-build.sh b/scripts/gen-current-build.sh index 484cc05b..5ba2e4c3 100755 --- a/scripts/gen-current-build.sh +++ b/scripts/gen-current-build.sh @@ -15,9 +15,9 @@ if [[ $? -ne 0 ]]; then fi COMPILER_INFO=${COMPILER_INFO//$'\n'/\\n} # JSON-friendly newlines. -GIT_COMMIT="$(git rev-parse HEAD 2>/dev/null || echo '')" -GIT_BRANCH="$(git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '')" -GIT_STATUS="$(git status 2>/dev/null || echo '')" +GIT_COMMIT="$( (git rev-parse HEAD 2>/dev/null || echo '') | tail -n 1)" +GIT_BRANCH="$( (git rev-parse --abbrev-ref HEAD 2>/dev/null || echo '') | tail -n 1)" +GIT_STATUS="$( (git status 2>/dev/null || echo '') | tail -n 1)" # NOTE(dkorolev): Removing the commands that may potentially run for a long time. #GIT_DIFF_NAMES_MULTILINE="$(git diff --name-only 2>/dev/null || echo '')"