Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 60 additions & 6 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,23 +1,77 @@
cmake_minimum_required(VERSION 3.2...3.27)
project(cmake_git_version_tracking
LANGUAGES C)

set(PROJECT_NAME ${CMAKE_GIT_PROJECT_PREFIX}cmake_git_version_tracking)
project(${PROJECT_NAME} LANGUAGES C VERSION 1.0)

list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Standard paths
include(install_paths)

# Define the two required variables before including
# the source code for watching a git repository.
set(PRE_CONFIGURE_FILE "git.c.in")
set(POST_CONFIGURE_FILE "${CMAKE_CURRENT_BINARY_DIR}/git.c")
include(git_watcher.cmake)
include(CMakePackageConfigHelpers)

set(CMAKE_CONFIG_FILE "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Config.cmake.in" CACHE INTERNAL "Package config file" )

option(SAVE_GIT_STATE_TO_PY "Creates a .py file containg to be used for python bindings versioning" ON)
if(SAVE_GIT_STATE_TO_PY)
set(GIT_STATE_PY_PATH ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_GIT_PROJECT_PREFIX}git_state.py CACHE INTERNAL "Path to py git state")
endif()
# Create a library out of the compiled post-configure file.
#
# Note that the include is a system include. This was done
# so downstream projects don't suffer from warnings on a
# 3rdparty library.
add_library(${PROJECT_NAME} STATIC ${POST_CONFIGURE_FILE})
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
add_dependencies(${PROJECT_NAME} check_git)

target_include_directories(${PROJECT_NAME}
SYSTEM PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>
)

add_dependencies(${PROJECT_NAME} ${CMAKE_GIT_PROJECT_PREFIX}check_git)

# The C99 standard is only required because we're using <stdbool.h>.
# This could be removed if it's a problem for users, but would require the
# cmake configure() commands to translate true/false literals to 1/0.
set_property(TARGET ${PROJECT_NAME} PROPERTY C_STANDARD 99)

set(PROJECT_CONFIG_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config.cmake")
set(PROJECT_CONFIG_VERSION_FILE "${PROJECT_BINARY_DIR}/${PROJECT_NAME}-config-version.cmake")

configure_package_config_file(
${CMAKE_CONFIG_FILE}
${PROJECT_CONFIG_FILE}
INSTALL_DESTINATION ${INSTALL_CONFIG_DIR})

# This auto-generates a version file.
write_basic_package_version_file(
${PROJECT_CONFIG_VERSION_FILE}
COMPATIBILITY SameMajorVersion)

install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}-targets
RUNTIME DESTINATION ${INSTALL_RUNTIME_DIR}
LIBRARY DESTINATION ${INSTALL_LIBRARY_DIR}
ARCHIVE DESTINATION ${INSTALL_ARCHIVE_DIR})

install(FILES ${HEADER_FILES}
DESTINATION ${INSTALL_INCLUDE_DIR})


install(FILES
${PROJECT_CONFIG_VERSION_FILE}
${PROJECT_CONFIG_FILE}
DESTINATION ${INSTALL_CONFIG_DIR})

install(EXPORT ${PROJECT_NAME}-targets
FILE ${PROJECT_NAME}-targets.cmake
NAMESPACE ${PROJECT_NAME}::
DESTINATION ${INSTALL_CONFIG_DIR})

export(EXPORT ${PROJECT_NAME}-targets
FILE ${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}-targets.cmake
NAMESPACE ${PROJECT_NAME}::)

export(PACKAGE ${PROJECT_NAME})
21 changes: 21 additions & 0 deletions cmake/Config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
@PACKAGE_INIT@
include(CMakeFindDependencyMacro)

get_filename_component(_dir "${CMAKE_CURRENT_LIST_FILE}" PATH)
get_filename_component(_prefix "${_dir}/../../.." ABSOLUTE)
get_filename_component(@PROJECT_NAME@_CMAKE_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)

if(TARGET @PROJECT_NAME@::@PROJECT_NAME@)
set(@PROJECT_NAME@_DIR "${@PROJECT_NAME@_BINARY_DIR}")
message(STATUS "Target @PROJECT_NAME@::@PROJECT_NAME@ Configured with ${@PROJECT_NAME@_DIR}")
elseif(TARGET @PROJECT_NAME@::@PROJECT_NAME@-static)
set(@PROJECT_NAME@_DIR "${CMAKE_CURRENT_BINARY_DIR}")
message(STATUS "Target @PROJECT_NAME@::@PROJECT_NAME@-static Configured with ${@PROJECT_NAME@_DIR}")
else()
include("${@PROJECT_NAME@_CMAKE_DIR}/@[email protected]")
set(@PROJECT_NAME@_DIR "${_prefix}/share/cmake/@PROJECT_NAME@")
set(@PROJECT_NAME@_INCLUDE_DIRS "${_prefix}/include/@PROJECT_NAME@")
message(STATUS "Target <@PROJECT_NAME@> without aliases configured with ${@PROJECT_NAME@_DIR}")
endif()

check_required_components("@PROJECT_NAME@")
45 changes: 45 additions & 0 deletions cmake/install_paths.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)

find_package(PkgConfig REQUIRED)
find_package (Python3 COMPONENTS Interpreter Development REQUIRED)
pkg_get_variable(SYSTEMD_UNIT_DIR systemd systemdsystemunitdir)
# If no build type was specified, set it to Release.
if(NOT SYSTEMD_UNIT_DIR)
set(SYSTEMD_UNIT_DIR ${CMAKE_INSTALL_PREFIX}/etc/systemd/system CACHE STRING
"Default install path for services" FORCE)
endif(NOT SYSTEMD_UNIT_DIR)

# If no build type was specified, set it to Release.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING
"Choose the type of build, options are: None Debug Release."
FORCE)
endif(NOT CMAKE_BUILD_TYPE)

# If no installation prefix is given manually, install locally.
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(CMAKE_INSTALL_PREFIX "${CMAKE_BINARY_DIR}/install" CACHE STRING
"The install location"
FORCE)
endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)

# Projectwise paths
set(PROJECT_PREFIX ${PROJECT_NAME})
set(INSTALL_RUNTIME_DIR ${CMAKE_INSTALL_BINDIR})
set(INSTALL_CONFIG_DIR ${CMAKE_INSTALL_DATAROOTDIR}/cmake/${PROJECT_NAME})
set(INSTALL_SERVICES_CFG_DIR ${CMAKE_INSTALL_DATAROOTDIR}/service_cfg)
set(INSTALL_SYSCONFIG_DIR ${CMAKE_INSTALL_SYSCONFDIR})
set(INSTALL_LIBRARY_DIR ${CMAKE_INSTALL_LIBDIR})
set(INSTALL_ARCHIVE_DIR ${CMAKE_INSTALL_LIBDIR})
set(INSTALL_INCLUDE_DIR ${CMAKE_INSTALL_INCLUDEDIR}/${PROJECT_NAME})
set(INSTALL_SRC_DIR src/${PROJECT_NAME})
cmake_path (GET Python3_SITELIB FILENAME THIRD_PARTY_DIR_NAME)
cmake_path (GET Python3_STDLIB FILENAME PYTHON3_DIR)
set(INSTALL_PYTHON_DIR ${INSTALL_LIBRARY_DIR}/${PYTHON3_DIR}/${THIRD_PARTY_DIR_NAME})

if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(INSTALL_SYSTEMD_SERVICE ${CMAKE_INSTALL_PREFIX}/${SYSTEMD_UNIT_DIR})
else(NOT CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
set(INSTALL_SYSTEMD_SERVICE ${SYSTEMD_UNIT_DIR})
endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
39 changes: 37 additions & 2 deletions git_watcher.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,39 @@ function(GetGitState _working_dir)

endfunction()

function(SaveGitStateToPy)
GetGitState("${GIT_WORKING_DIR}")

# Format git state to .py file
if("$ENV{GIT_IS_DIRTY}" STREQUAL "true")
set(PY_GIT_IS_DIRTY True)
else()
set(PY_GIT_IS_DIRTY False)
endif()

set(GIT_STATE
PY_GIT_HEAD_SHA = \"$ENV{GIT_HEAD_SHA1}\"\n
PY_GIT_IS_DIRTY = ${ES_GIT_IS_DIRTY}\n
PY_GIT_AUTHOR_NAME = \"$ENV{GIT_AUTHOR_NAME}\"\n
PY_GIT_AUTHOR_EMAIL = \"$ENV{GIT_AUTHOR_EMAIL}\"\n
PY_GIT_COMMIT_DATE = \"$ENV{GIT_COMMIT_DATE_ISO8601}\"\n
PY_GIT_COMMIT_SUBJECT = \"$ENV{GIT_COMMIT_SUBJECT}\"\n
PY_GIT_COMMIT_BODY = \"$ENV{GIT_COMMIT_BODY}\"\n
PY_GIT_DESCRIBE = \"$ENV{GIT_DESCRIBE}\"\n
PY_GIT_BRANCH = \"$ENV{GIT_BRANCH}\"\n)
string(REGEX REPLACE ";" "" GIT_STATE "${GIT_STATE}")

if(EXISTS ${GIT_STATE_PY_PATH})
file(READ ${GIT_STATE_PY_PATH} GIT_STATE_)
else()
set(GIT_STATE_ "")
endif()

if (NOT "${GIT_STATE}" STREQUAL "${GIT_STATE_}")
file(WRITE ${GIT_STATE_PY_PATH} "${GIT_STATE}")
endif()

endfunction()

# Function: GitStateChangedAction
# Description: this function is executed when the state of the git
Expand All @@ -263,7 +295,6 @@ function(GitStateChangedAction)
endfunction()



# Function: HashGitState
# Description: loop through the git state variables and compute a unique hash.
# Args:
Expand Down Expand Up @@ -324,7 +355,7 @@ endfunction()
# check the state of git before every build. If the state has
# changed, then a file is configured.
function(SetupGitMonitoring)
add_custom_target(check_git
add_custom_target(${CMAKE_GIT_PROJECT_PREFIX}check_git
ALL
DEPENDS ${PRE_CONFIGURE_FILE}
BYPRODUCTS
Expand Down Expand Up @@ -360,6 +391,10 @@ function(Main)
else()
# >> Executes at configure time.
SetupGitMonitoring()
# Save the git state in py file
if(SAVE_GIT_STATE_TO_PY)
SaveGitStateToPy()
endif()
endif()
endfunction()

Expand Down