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
6 changes: 6 additions & 0 deletions .cmake-format
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,13 @@ parse:
NAMESPACE: 1
INCLUDE_DIR: 1
INCLUDE_DESTINATION: 1
INCLUDE_HEADER_PATTERN: 1
BINARY_DIR: 1
COMPATIBILITY: 1
VERSION_HEADER: 1
EXPORT_HEADER: 1
DISABLE_VERSION_SUFFIX: 1
CPACK: 1
RUNTIME_DESTINATION: 1
DEPENDENCIES: +
HEADER_SETS: +
1 change: 1 addition & 0 deletions .github/workflows/install.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ jobs:
- name: build and install library
run: |
cmake -S. -Bbuild -DCMAKE_BUILD_TYPE=Release
cmake --build build --target all_verify_interface_header_sets
sudo cmake --build build --target install
rm -rf build

Expand Down
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
build/
/build*
/.vscode
/cpm_modules
.DS_Store
.DS_Store
55 changes: 40 additions & 15 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
cmake_minimum_required(VERSION 3.14...3.22)
cmake_minimum_required(VERSION 3.24...3.31)

# ---- Project ----

Expand All @@ -24,15 +24,20 @@ endif()
include(cmake/CPM.cmake)

# PackageProject.cmake will be used to make our target installable
CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.8.0")
include(cmake/PackageProject.cmake)
# XXX # CPMAddPackage("gh:TheLartians/PackageProject.cmake@1.13.0")

# XXX set(CMAKE_SKIP_INSTALL_RULES YES)

CPMAddPackage(
NAME fmt
GIT_TAG 10.2.1
GIT_TAG 11.1.4
GITHUB_REPOSITORY fmtlib/fmt
OPTIONS "FMT_INSTALL YES" # create an installable target
)

set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${PROJECT_IS_TOP_LEVEL})

# ---- Add source files ----

# Note: globbing sources is considered bad practice as CMake's generators may not detect new files
Expand All @@ -42,9 +47,27 @@ file(GLOB_RECURSE sources CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/source/

# ---- Create library ----

# the location where the project's version header will be placed should match the project's regular
# header paths
string(TOLOWER ${PROJECT_NAME}/version.h VERSION_HEADER_LOCATION)

# Note: for header-only libraries change all PUBLIC flags to INTERFACE and create an interface
# target: add_library(${PROJECT_NAME} INTERFACE)
add_library(${PROJECT_NAME} ${headers} ${sources})
add_library(${PROJECT_NAME})
target_sources(
${PROJECT_NAME}
PRIVATE ${sources}
PUBLIC FILE_SET
public_headers
TYPE
HEADERS
BASE_DIRS
${CMAKE_CURRENT_SOURCE_DIR}/include
${CMAKE_CURRENT_BINARY_DIR}
FILES
${headers}
${CMAKE_CURRENT_BINARY_DIR}/${VERSION_HEADER_LOCATION}
)
set_target_properties(${PROJECT_NAME} PROPERTIES CXX_STANDARD 17)

# being a cross-platform target, we enforce standards conformance on MSVC
Expand All @@ -53,26 +76,28 @@ target_compile_options(${PROJECT_NAME} PUBLIC "$<$<COMPILE_LANG_AND_ID:CXX,MSVC>
# Link dependencies
target_link_libraries(${PROJECT_NAME} PRIVATE fmt::fmt)

target_include_directories(
${PROJECT_NAME} PUBLIC $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include/${PROJECT_NAME}-${PROJECT_VERSION}>
)
set(GREETER_VERSION \"${PROJECT_VERSION}\")
string(TOUPPER ${PROJECT_NAME} UPPERCASE_PROJECT_NAME)
configure_file(${PACKAGE_PROJECT_ROOT_PATH}/version.h.in ${VERSION_HEADER_LOCATION} @ONLY)

if(CMAKE_SKIP_INSTALL_RULES)
add_library(${PROJECT_NAME}::${PROJECT_NAME} ALIAS ${PROJECT_NAME})
return()
endif()

# ---- Create an installable target ----
# this allows users to install and find the library via `find_package()`.

# the location where the project's version header will be placed should match the project's regular
# header paths
string(TOLOWER ${PROJECT_NAME}/version.h VERSION_HEADER_LOCATION)
include(cmake/AddUninstallTarget.cmake)

packageProject(
NAME ${PROJECT_NAME}
VERSION ${PROJECT_VERSION}
NAMESPACE ${PROJECT_NAME}
BINARY_DIR ${PROJECT_BINARY_DIR}
INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
INCLUDE_DESTINATION include/${PROJECT_NAME}-${PROJECT_VERSION}
VERSION_HEADER "${VERSION_HEADER_LOCATION}"
# Not used! INCLUDE_DIR ${PROJECT_SOURCE_DIR}/include
COMPATIBILITY SameMajorVersion
DEPENDENCIES "fmt 10.2.1"
RUNTIME_DESTINATION /
DEPENDENCIES "fmt 11.1.4"
HEADER_SETS public_headers
)
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ This template is the result of learnings from many previous projects and should
Eventually, you can remove any unused files, such as the standalone directory or irrelevant github workflows for your project.
Feel free to replace the License with one suited for your project.

To cleanly separate the library and subproject code, the outer `CMakeList.txt` only defines the library itself while the tests and other subprojects are self-contained in their own directories.
To cleanly separate the library and subproject code, the outer `CMakeList.txt` only defines the library itself while the tests and other subprojects are self-contained in their own directories.
During development it is usually convenient to [build all subprojects at once](#build-everything-at-once).

### Build and run the standalone target
Expand All @@ -66,7 +66,7 @@ cmake -S test -B build/test
cmake --build build/test
CTEST_OUTPUT_ON_FAILURE=1 cmake --build build/test --target test

# or simply call the executable:
# or simply call the executable:
./build/test/GreeterTests
```

Expand All @@ -91,7 +91,7 @@ See [Format.cmake](https://github.com/TheLartians/Format.cmake) for details.
These dependencies can be easily installed using pip.

```bash
pip install clang-format==14.0.6 cmake_format==0.6.11 pyyaml
pip install cmake clang-format cmake_format==0.6.11 pyyaml
```

### Build the documentation
Expand Down
2 changes: 1 addition & 1 deletion all/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# this script adds all subprojects to a single build to allow IDEs understand the full project
# structure.

cmake_minimum_required(VERSION 3.14...3.22)
cmake_minimum_required(VERSION 3.24...3.31)

project(BuildAll LANGUAGES CXX)

Expand Down
101 changes: 101 additions & 0 deletions cmake/AddUninstallTarget.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# SPDX-FileCopyrightText: 2012-2021 Istituto Italiano di Tecnologia (IIT) SPDX-FileCopyrightText:
# 2008-2013 Kitware Inc. SPDX-License-Identifier: BSD-3-Clause

#[=======================================================================[.rst:
AddUninstallTarget
------------------

Add the "uninstall" target for your project::

include(AddUninstallTarget)


will create a file ``cmake_uninstall.cmake`` in the build directory and add a
custom target ``uninstall`` (or ``UNINSTALL`` on Visual Studio and Xcode) that
will remove the files installed by your package (using
``install_manifest.txt``).
See also
https://gitlab.kitware.com/cmake/community/wikis/FAQ#can-i-do-make-uninstall-with-cmake

The :module:`AddUninstallTarget` module must be included in your main
``CMakeLists.txt``. If included in a subdirectory it does nothing.
This allows you to use it safely in your main ``CMakeLists.txt`` and include
your project using ``add_subdirectory`` (for example when using it with
:cmake:module:`FetchContent`).

If the ``uninstall`` target already exists, the module does nothing.
#]=======================================================================]

# AddUninstallTarget works only when included in the main CMakeLists.txt
if(NOT "${CMAKE_CURRENT_BINARY_DIR}" STREQUAL "${CMAKE_BINARY_DIR}")
return()
endif()

# The name of the target is uppercase in MSVC and Xcode (for coherence with the other standard
# targets)
if("${CMAKE_GENERATOR}" MATCHES "^(Visual Studio|Xcode)")
set(_uninstall "UNINSTALL")
else()
set(_uninstall "uninstall")
endif()

# If target is already defined don't do anything
if(TARGET ${_uninstall})
return()
endif()

set(_filename cmake_uninstall.cmake)

file(
WRITE "${CMAKE_CURRENT_BINARY_DIR}/${_filename}"
"if(NOT EXISTS \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\")
message(WARNING \"Cannot find install manifest: \\\"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\\\"\")
return()
endif()

file(READ \"${CMAKE_CURRENT_BINARY_DIR}/install_manifest.txt\" files)
string(STRIP \"\${files}\" files)
string(REGEX REPLACE \"\\n\" \";\" files \"\${files}\")
list(REVERSE files)
foreach(file \${files})
if(IS_SYMLINK \"\$ENV{DESTDIR}\${file}\" OR EXISTS \"\$ENV{DESTDIR}\${file}\")
message(STATUS \"Uninstalling: \$ENV{DESTDIR}\${file}\")
execute_process(
COMMAND \${CMAKE_COMMAND} -E remove \"\$ENV{DESTDIR}\${file}\"
OUTPUT_VARIABLE rm_out
RESULT_VARIABLE rm_retval)
if(NOT \"\${rm_retval}\" EQUAL 0)
message(FATAL_ERROR \"Problem when removing \\\"\$ENV{DESTDIR}\${file}\\\"\")
endif()
else()
message(STATUS \"Not-found: \$ENV{DESTDIR}\${file}\")
endif()
endforeach(file)
"
)

set(_desc "Uninstall the project...")
if(CMAKE_GENERATOR STREQUAL "Unix Makefiles")
set(_comment
COMMAND
\$\(CMAKE_COMMAND\)
-E
cmake_echo_color
--switch=$\(COLOR\)
--cyan
"${_desc}"
)
else()
set(_comment COMMENT "${_desc}")
endif()
add_custom_target(
${_uninstall}
${_comment}
COMMAND ${CMAKE_COMMAND} -P ${_filename}
USES_TERMINAL
BYPRODUCTS uninstall_byproduct
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
)
set_property(SOURCE uninstall_byproduct PROPERTY SYMBOLIC 1)

set_property(TARGET ${_uninstall} PROPERTY FOLDER "CMakePredefinedTargets")
4 changes: 2 additions & 2 deletions cmake/CPM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#
# SPDX-FileCopyrightText: Copyright (c) 2019-2023 Lars Melchior and contributors

set(CPM_DOWNLOAD_VERSION 0.40.2)
set(CPM_HASH_SUM "c8cdc32c03816538ce22781ed72964dc864b2a34a310d3b7104812a5ca2d835d")
set(CPM_DOWNLOAD_VERSION 0.40.7)
set(CPM_HASH_SUM "c0fc82149e00c43a21febe7b2ca57b2ffea2b8e88ab867022c21d6b81937eb50")

if(CPM_SOURCE_CACHE)
set(CPM_DOWNLOAD_LOCATION "${CPM_SOURCE_CACHE}/cpm/CPM_${CPM_DOWNLOAD_VERSION}.cmake")
Expand Down
10 changes: 10 additions & 0 deletions cmake/Config.cmake.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
include(CMakeFindDependencyMacro)

string(REGEX MATCHALL "[^;]+" SEPARATE_DEPENDENCIES "@PROJECT_DEPENDENCIES@")

foreach(dependency ${SEPARATE_DEPENDENCIES})
string(REPLACE " " ";" args "${dependency}")
find_dependency(${args})
endforeach()

include("${CMAKE_CURRENT_LIST_DIR}/@PROJECT_NAME@Targets.cmake")
Loading