Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: reorganize modules and add the first project module #115

Merged
merged 1 commit into from
Jul 15, 2024
Merged
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
19 changes: 19 additions & 0 deletions cmake/ProjectDefault.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#[[
This module contains default modules and settings that can be used by all projects.
]]

include_guard(GLOBAL)

# Prevent the module from being used in the wrong location
if(NOT CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
message(FATAL_ERROR "This module should be in the project root directory")
endif()

include(${CMAKE_CURRENT_LIST_DIR}/configure/Default.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/build/Default.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/test/Default.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/install/Default.cmake)

add_debug_macro()

create_uninstall_target()
3 changes: 3 additions & 0 deletions cmake/build/Default.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,6 @@ set(BUILD_SHARED_LIBS
"This will cause all libraries to be built shared unless the library was explicitly added as a static library.
This variable is often added to projects as an ``option()`` so that each user of a project can decide if they want
to build the project using shared or static libraries.")

include(${CMAKE_CURRENT_LIST_DIR}/Ccache.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/LinkOptimization.cmake)
4 changes: 4 additions & 0 deletions cmake/configure/Default.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,7 @@ set(CMAKE_INCLUDE_DIRECTORIES_PROJECT_BEFORE
set(FETCHCONTENT_QUIET
ON
CACHE BOOL "Don't print messages about fetch operations.")

include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/CheckBuildDir.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/UniqueOutputBinaryDir.cmake)
229 changes: 0 additions & 229 deletions cmake/install/Common.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ This module provides some common tools.
]]

include_guard(GLOBAL)
include(${CMAKE_CURRENT_LIST_DIR}/InstallCopyright.cmake)

#[[
Show installation directories
Expand All @@ -16,234 +15,6 @@ macro(show_installation)
endforeach()
endmacro()

#[[
A function to add install config rules to target

Arguments:
NAME - A name as the installation export name. (required)
VERSION - The target version. Default to "0.0.0". (optional)
COMPATIBILITY - Compatibility on version. Default to SameMajorVersion. (optional)
CONFIGURE_PACKAGE_CONFIG_FILE - The file to generate config file. (optional)
INCLUDES - The include directories to install. (optional)
INCLUDE_FILES - The include files to install. (optional)
TARGETS - The targets to pack. (required)
DEPENDENCIES - The dependencies to check in config file. (required)

Note:

Includes from sources can be installed by PUBLIC_HEADER using set_target_properties
which flattens the hierarchy and puts the header files into the same directory. So
the recommended way it to use INCLUDES or INCLUDE_FILES.
see https://stackoverflow.com/questions/54271925/how-to-configure-cmakelists-txt-to-install-public-headers-of-a-shared-library

Example:

add_library(header INTERFACE)
target_include_interface_directories(header ${CMAKE_CURRENT_SOURCE_DIR}/include)
target_link_libraries(header INTERFACE absl::log)
set_target_properties(header PROPERTIES PUBLIC_HEADER "${public_headers}")
install_target(
NAME
header
VERSION
${CMAKE_PROJECT_VERSION}
INCLUDES
${CMAKE_CURRENT_SOURCE_DIR}/include/ # install subdirectories with /
TARGETS
header
DEPENDENCIES
"absl:log")

]]
function(install_target)
set(_opts)
set(_single_opts NAME VERSION COMPATIBILITY CONFIGURE_PACKAGE_CONFIG_FILE)
set(_multi_opts TARGETS INCLUDES INCLUDE_FILES DEPENDENCIES LICENSE_FILE_LIST)
cmake_parse_arguments(PARSE_ARGV 0 arg "${_opts}" "${_single_opts}"
"${_multi_opts}")

include(GNUInstallDirs)
# Specify rules at install time
install(
TARGETS ${arg_TARGETS}
EXPORT ${arg_NAME}-targets
LIBRARY DESTINATION $<$<CONFIG:Debug>:debug/>${CMAKE_INSTALL_LIBDIR}
COMPONENT ${arg_NAME}_runtime
ARCHIVE DESTINATION $<$<CONFIG:Debug>:debug/>${CMAKE_INSTALL_LIBDIR}
COMPONENT ${arg_NAME}_runtime
RUNTIME DESTINATION $<$<CONFIG:Debug>:debug/>${CMAKE_INSTALL_BINDIR}
COMPONENT ${arg_NAME}_runtime
PUBLIC_HEADER DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${arg_NAME}
COMPONENT ${arg_NAME}_development)

if(arg_INCLUDES)
install(DIRECTORY ${arg_INCLUDES}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${arg_NAME})
endif()

if(arg_INCLUDE_FILES)
install(FILES ${arg_INCLUDE_FILES}
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/${arg_NAME})
endif()

if(arg_LICENSE_FILE_LIST)
install_copyright(FILE_LIST ${arg_LICENSE_FILE_LIST} DESTINATION
share/${arg_NAME})
endif()

install(
EXPORT ${arg_NAME}-targets
FILE ${arg_NAME}-targets.cmake
NAMESPACE ${arg_NAME}::
DESTINATION share/${arg_NAME}
COMPONENT ${arg_NAME}_development)

set(_cache_dir
${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CURRENT_FUNCTION}/${arg_NAME})

if(NOT arg_CONFIGURE_PACKAGE_CONFIG_FILE)

set(_configure_package_config_file_content
"#[=======================================================================[.rst:
${arg_NAME}-config.cmake
-------------------

${arg_NAME} cmake module.
This module sets the following variables in your project:

::

${arg_NAME}_FOUND - true if ${arg_NAME} found on the system
${arg_NAME}_VERSION - ${arg_NAME} version in format Major.Minor.Release
")
string(
APPEND
_configure_package_config_file_content
"

Exported targets:

::

If ${arg_NAME} is found, this module defines the following :prop_tgt:`IMPORTED`
targets. ::
")
foreach(_tgt ${arg_TARGETS})
get_target_property(_target_type "${_tgt}" TYPE)
string(
APPEND
_configure_package_config_file_content
"
${arg_NAME}::${_tgt} - the main ${arg_NAME} ${_target_type} with header & defs attached."
)
endforeach()

string(
APPEND
_configure_package_config_file_content
"


Suggested usage:

::

find_package(${arg_NAME})
find_package(${arg_NAME} CONFIG REQUIRED)


The following variables can be set to guide the search for this package:

::

${arg_NAME}_DIR - CMake variable, set to directory containing this Config file
CMAKE_PREFIX_PATH - CMake variable, set to root directory of this package
PATH - environment variable, set to bin directory of this package
CMAKE_DISABLE_FIND_PACKAGE_${arg_NAME} - CMake variable, disables find_package(${arg_NAME})
perhaps to force internal build

#]=======================================================================]
")

string(
APPEND
_configure_package_config_file_content
"@PACKAGE_INIT@

include(CMakeFindDependencyMacro)
")
string(APPEND _configure_package_config_file_content "
# Dependency check here")
foreach(_dep ${arg_DEPENDENCIES})
string(APPEND _configure_package_config_file_content "
find_dependency(${_dep} REQUIRED)")
endforeach()

string(REPLACE ";" " " _tgts "${arg_TARGETS}")
string(
APPEND
_configure_package_config_file_content
"

include(\"\${CMAKE_CURRENT_LIST_DIR}/${arg_NAME}-targets.cmake\")
check_required_components(${_tgts})
")

file(WRITE ${_cache_dir}/${arg_NAME}-config.cmake.in
${_configure_package_config_file_content})
set(arg_CONFIGURE_PACKAGE_CONFIG_FILE
${_cache_dir}/${arg_NAME}-config.cmake.in)
endif()

include(CMakePackageConfigHelpers)

configure_package_config_file(
${arg_CONFIGURE_PACKAGE_CONFIG_FILE} ${_cache_dir}/${arg_NAME}-config.cmake
INSTALL_DESTINATION share/${arg_NAME})

if(NOT arg_COMPATIBILITY)
set(arg_COMPATIBILITY SameMajorVersion)
endif()

if(NOT arg_VERSION)
set(arg_VERSION "0.0.0")
endif()

write_basic_package_version_file(
${_cache_dir}/${arg_NAME}-config-version.cmake
VERSION ${arg_VERSION}
COMPATIBILITY ${arg_COMPATIBILITY})

install(FILES ${_cache_dir}/${arg_NAME}-config.cmake
${_cache_dir}/${arg_NAME}-config-version.cmake
DESTINATION share/${arg_NAME})

# Export from build tree
export(
EXPORT ${arg_NAME}-targets
FILE ${_cache_dir}/${arg_NAME}-targets.cmake
NAMESPACE ${arg_NAME}::)

export(PACKAGE ${arg_NAME})

# Generate the usage file
set(_usage_targets)
foreach(_target ${arg_TARGETS})
string(APPEND _usage_targets "${arg_NAME}::${_target} ")
endforeach()
string(STRIP ${_usage_targets} _usage_targets)
set(USAGE_FILE_CONTENT
"# The package ${arg_NAME} provides the following CMake targets:

find_package(${arg_NAME} CONFIG REQUIRED)
target_link_libraries(main PRIVATE ${_usage_targets})
")
file(WRITE ${_cache_dir}/usage ${USAGE_FILE_CONTENT})
install(FILES ${_cache_dir}/usage DESTINATION share/${arg_NAME})
install(CODE "MESSAGE(STATUS \"${USAGE_FILE_CONTENT}\")")

endfunction()

#[[
A function to provide a target to uninstall things from the command `cmake install`.

Expand Down
6 changes: 6 additions & 0 deletions cmake/install/Default.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@
Default to installation.
]]
include_guard(GLOBAL)

include(${CMAKE_CURRENT_LIST_DIR}/Common.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/InstallCopyright.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/InstallTarget.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/InstallDependency.cmake)
include(${CMAKE_CURRENT_LIST_DIR}/Runpath.cmake)
4 changes: 4 additions & 0 deletions cmake/install/InstallCopyright.cmake
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
#[[
This module provides tools to handle cmake copyright installations painlessly.
]]

include_guard(GLOBAL)

#[[.md
Expand Down
2 changes: 1 addition & 1 deletion cmake/install/InstallDependency.cmake
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
#[[
This module provides tools to handle cmake installations painlessly.
This module provides tools to handle cmake dependency installations painlessly.
]]

include_guard(GLOBAL)
Expand Down
Loading
Loading