Skip to content

Commit 8083349

Browse files
cmake package
1 parent e8f2d22 commit 8083349

File tree

7 files changed

+463
-2
lines changed

7 files changed

+463
-2
lines changed

CMakeLists.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ cmake_minimum_required(VERSION 3.22.0 FATAL_ERROR)
99
# ======================================================================================================================
1010

1111
# project
12-
project(cxxitimer LANGUAGES CXX VERSION 2.0.1)
12+
project(cxxitimer LANGUAGES CXX VERSION 2.0.2)
1313

1414
set(Target cxxitimer) # library name
1515
set(STANDARD 20) # C++ Standard
@@ -37,4 +37,4 @@ option(INSTAL_LIB "add library to install target" ON)
3737

3838
# ----------------------------------------------- Do not change --------------------------------------------------------
3939
# ======================================================================================================================
40-
include(setup.cmake)
40+
include(cmake_files/setup.cmake)

cmake_files/ClangFormat.cmake

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
# Copyright Tomas Zeman 2019-2020.
2+
# Distributed under the Boost Software License, Version 1.0.
3+
# (See accompanying file LICENSE_1_0.txt or copy at
4+
# http://www.boost.org/LICENSE_1_0.txt)
5+
6+
function(prefix_clangformat_setup prefix)
7+
if(NOT CLANGFORMAT_EXECUTABLE)
8+
set(CLANGFORMAT_EXECUTABLE clang-format)
9+
endif()
10+
11+
if(NOT EXISTS ${CLANGFORMAT_EXECUTABLE})
12+
find_program(clangformat_executable_tmp ${CLANGFORMAT_EXECUTABLE})
13+
if(clangformat_executable_tmp)
14+
set(CLANGFORMAT_EXECUTABLE ${clangformat_executable_tmp})
15+
unset(clangformat_executable_tmp)
16+
else()
17+
message(FATAL_ERROR "ClangFormat: ${CLANGFORMAT_EXECUTABLE} not found! Aborting")
18+
endif()
19+
endif()
20+
21+
foreach(clangformat_source ${ARGN})
22+
get_filename_component(clangformat_source ${clangformat_source} ABSOLUTE)
23+
list(APPEND clangformat_sources ${clangformat_source})
24+
endforeach()
25+
26+
add_custom_target(${prefix}_clangformat
27+
COMMAND
28+
${CLANGFORMAT_EXECUTABLE}
29+
-style=file
30+
-i
31+
${clangformat_sources}
32+
WORKING_DIRECTORY
33+
${CMAKE_SOURCE_DIR}
34+
COMMENT
35+
"Formatting ${prefix} with ${CLANGFORMAT_EXECUTABLE} ..."
36+
)
37+
38+
if(TARGET clangformat)
39+
add_dependencies(clangformat ${prefix}_clangformat)
40+
else()
41+
add_custom_target(clangformat DEPENDS ${prefix}_clangformat)
42+
endif()
43+
endfunction()
44+
45+
function(clangformat_setup)
46+
prefix_clangformat_setup(${PROJECT_NAME} ${ARGN})
47+
endfunction()
48+
49+
function(target_clangformat_setup target)
50+
get_target_property(target_sources ${target} SOURCES)
51+
prefix_clangformat_setup(${target} ${target_sources})
52+
endfunction()

cmake_files/Config.cmake.in

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
@PACKAGE_INIT@
2+
3+
include("${CMAKE_CURRENT_LIST_DIR}/@Target@Targets.cmake")
4+
5+
check_required_components("@Target@")

cmake_files/compileropts.cmake

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
#
2+
# Copyright (C) 2022 Nikolas Koesling <nikolas@koesling.info>.
3+
# This template is free software. You can redistribute it and/or modify it under the terms of the MIT License.
4+
#
5+
6+
# options that are valid for gcc and clang
7+
function(commonopts target)
8+
# more debugging information
9+
if(OPTIMIZE_DEBUG)
10+
SET(CMAKE_CXX_FLAGS_DEBUG "-g3 -O3")
11+
else()
12+
SET(CMAKE_CXX_FLAGS_DEBUG "-g3")
13+
endif()
14+
15+
if(MAKE_32_BIT_BINARY)
16+
message(STATUS "Compiling as 32 bit binary.")
17+
target_compile_options(${target} PUBLIC -m32)
18+
endif()
19+
20+
if(OPTIMIZE_FOR_ARCHITECTURE)
21+
message(STATUS "using architecture specific code generator: ${ARCHITECTURE}")
22+
target_compile_options(${target} PUBLIC -march=${ARCHITECTURE})
23+
endif()
24+
endfunction()
25+
26+
function(set_options target use_omp)
27+
if(CMAKE_CXX_COMPILER_ID MATCHES "GNU")
28+
commonopts(${target})
29+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
30+
commonopts(${target})
31+
32+
if(CMAKE_SYSTEM_NAME MATCHES "Windows")
33+
# TODO check options
34+
target_compile_options(${target} PUBLIC -D_DLL -D_MT -Xclang --dependent-lib=msvcrtd)
35+
SET(CMAKE_CXX_FLAGS_DEBUG "-g3 -D_DEBUG")
36+
endif()
37+
elseif(CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
38+
# more debugging information
39+
SET(CMAKE_CXX_FLAGS_DEBUG "/Zi")
40+
41+
if(ENABLE_MULTITHREADING AND OPENMP)
42+
target_compile_options(${target} PUBLIC /OpenMP)
43+
endif()
44+
else()
45+
message(AUTHOR_WARNING
46+
"You are using a compiler other than gcc/clang. Only gcc/clang are fully supported by this template.")
47+
endif()
48+
49+
if(use_omp)
50+
find_package(OpenMP)
51+
if (OPENMP_FOUND)
52+
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
53+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS}")
54+
set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
55+
target_link_libraries(${target} PRIVATE OpenMP::OpenMP_CXX)
56+
message(STATUS "openmp enabled")
57+
endif()
58+
endif()
59+
endfunction()

cmake_files/define.cmake

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#
2+
# Copyright (C) 2022 Nikolas Koesling <nikolas@koesling.info>.
3+
# This program is free software. You can redistribute it and/or modify it under the terms of the MIT License.
4+
#
5+
6+
function(set_definitions target)
7+
# compiler
8+
if (CMAKE_CXX_COMPILER_ID MATCHES "GNU")
9+
# compiler specific defines
10+
target_compile_definitions(${target} PUBLIC "COMPILER_GNU")
11+
target_compile_definitions(${target} PUBLIC "COMPILER_GNU_CLANG")
12+
elseif (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
13+
# compiler specific defines
14+
target_compile_definitions(${target} PUBLIC "COMPILER_CLANG")
15+
target_compile_definitions(${target} PUBLIC "COMPILER_GNU_CLANG")
16+
elseif (CMAKE_CXX_COMPILER_ID MATCHES "MSVC")
17+
target_compile_definitions(${target} PUBLIC "COMPILER_MSVC")
18+
message(AUTHOR_WARNING
19+
"You are using a compiler other than gcc/clang. Only gcc/clang are fully supported by this template.")
20+
else ()
21+
target_compile_definitions(${target} PUBLIC "COMPILER_UNKNOWN")
22+
message(AUTHOR_WARNING
23+
"You are using a compiler other than gcc/clang. Only gcc/clang are fully supported by this template.")
24+
endif ()
25+
26+
# project
27+
target_compile_definitions(${target} PUBLIC "PROJECT_VERSION=\"${PROJECT_VERSION}\"")
28+
target_compile_definitions(${target} PUBLIC "PROJECT_VERSION_MAJOR=${PROJECT_VERSION_MAJOR}")
29+
target_compile_definitions(${target} PUBLIC "PROJECT_VERSION_MINOR=${PROJECT_VERSION_MINOR}")
30+
target_compile_definitions(${target} PUBLIC "PROJECT_VERSION_PATCH=${PROJECT_VERSION_PATCH}")
31+
target_compile_definitions(${target} PUBLIC "PROJECT_NAME=\"${PROJECT_NAME}\"")
32+
target_compile_definitions(${target} PUBLIC "COMPILER_INFO=\"${CMAKE_CXX_COMPILER_ID} ${CMAKE_CXX_COMPILER_VERSION}\"")
33+
target_compile_definitions(${target} PUBLIC "SYSTEM_INFO=\"${CMAKE_SYSTEM_NAME} ${CMAKE_SYSTEM_VERSION} ${CMAKE_HOST_SYSTEM_PROCESSOR}\"")
34+
35+
# system
36+
if (CMAKE_SYSTEM_NAME MATCHES "Linux")
37+
target_compile_definitions(${target} PUBLIC "OS_LINUX")
38+
target_compile_definitions(${target} PUBLIC "OS_POSIX")
39+
elseif (CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
40+
target_compile_definitions(${target} PUBLIC "OS_FREEBSD")
41+
target_compile_definitions(${target} PUBLIC "OS_POSIX")
42+
elseif (CMAKE_SYSTEM_NAME MATCHES "Windows")
43+
target_compile_definitions(${target} PUBLIC "OS_WINDOWS")
44+
elseif (CMAKE_SYSTEM_NAME MATCHES "Darwin")
45+
target_compile_definitions(${target} PUBLIC "OS_DARWIN")
46+
target_compile_definitions(${target} PUBLIC "OS_POSIX")
47+
endif ()
48+
49+
# architecture defines
50+
target_compile_definitions(${target} PUBLIC CPU_WORD_BYTES=${CMAKE_SIZEOF_VOID_P})
51+
endfunction()

cmake_files/setup.cmake

Lines changed: 212 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,212 @@
1+
#
2+
# Copyright (C) 2024 Nikolas Koesling <nikolas@koesling.info>.
3+
# This program is free software. You can redistribute it and/or modify it under the terms of the MIT License.
4+
#
5+
6+
set(CMAKE_COMPILE_WARNING_AS_ERROR ON)
7+
8+
include(CTest)
9+
include(GNUInstallDirs)
10+
include(CMakePackageConfigHelpers)
11+
12+
# Determine whether this is a standalone project or included by other projects
13+
set(STANDALONE_PROJECT OFF)
14+
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR)
15+
set(STANDALONE_PROJECT ON)
16+
endif ()
17+
18+
# ----------------------------------------------- clang-tidy -----------------------------------------------------------
19+
# ======================================================================================================================
20+
if(CLANG_TIDY)
21+
if (CMAKE_CXX_COMPILER_ID MATCHES "Clang")
22+
if (${CLANG_TIDY_NO_ERRORS})
23+
set (CLANG_TIDY_CONFIG_FILE ${CMAKE_SOURCE_DIR}/.clang-tidy-noerrors)
24+
else()
25+
set (CLANG_TIDY_CONFIG_FILE ${CMAKE_SOURCE_DIR}/.clang-tidy)
26+
endif()
27+
28+
set(CMAKE_CXX_CLANG_TIDY
29+
clang-tidy
30+
-config-file=${CLANG_TIDY_CONFIG_FILE})
31+
message(STATUS "clang-tidy enabled: ${CLANG_TIDY_CONFIG_FILE}")
32+
else()
33+
message(WARNING "clang-tidy requested, but only available if clang is selected as compiler")
34+
endif()
35+
endif()
36+
37+
# ----------------------------------------------- library target -------------------------------------------------------
38+
# ======================================================================================================================
39+
if (STATIC_LIB)
40+
add_library(${Target} STATIC)
41+
else ()
42+
add_library(${Target} SHARED)
43+
endif ()
44+
45+
if (INSTAL_LIB)
46+
install(
47+
TARGETS ${Target}
48+
EXPORT ${Target}Targets
49+
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
50+
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
51+
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
52+
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
53+
)
54+
55+
install(
56+
DIRECTORY ${CMAKE_SOURCE_DIR}/include/
57+
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
58+
FILES_MATCHING PATTERN "*.h*"
59+
)
60+
61+
install(
62+
EXPORT ${Target}Targets
63+
FILE ${Target}Targets.cmake
64+
NAMESPACE "${Target}::"
65+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${Target}
66+
)
67+
68+
configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/cmake_files/Config.cmake.in
69+
"${CMAKE_CURRENT_BINARY_DIR}/${Target}Config.cmake"
70+
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${Target}
71+
)
72+
73+
write_basic_package_version_file(
74+
"${CMAKE_CURRENT_BINARY_DIR}/${Target}ConfigVersion.cmake"
75+
VERSION "${version}"
76+
COMPATIBILITY AnyNewerVersion
77+
)
78+
79+
install(FILES
80+
"${CMAKE_CURRENT_BINARY_DIR}/${Target}Config.cmake"
81+
"${CMAKE_CURRENT_BINARY_DIR}/${Target}ConfigVersion.cmake"
82+
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/${Target}
83+
)
84+
endif ()
85+
86+
# ----------------------------------------------- set source and include directory -------------------------------------
87+
# ======================================================================================================================
88+
add_subdirectory(src)
89+
add_subdirectory(include)
90+
target_include_directories(${Target} PUBLIC
91+
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
92+
$<INSTALL_INTERFACE:include> # <prefix>/include
93+
)
94+
95+
# ----------------------------------------------- warnings, compiler definitions and otions ----------------------------
96+
# ======================================================================================================================
97+
include(cmake_files/warnings.cmake)
98+
include(cmake_files/define.cmake)
99+
include(cmake_files/compileropts.cmake)
100+
101+
# force C++ Standard and disable/enable compiler specific extensions
102+
set_target_properties(${Target} PROPERTIES
103+
CXX_STANDARD ${STANDARD}
104+
CXX_STANDARD_REQUIRED ON
105+
CXX_EXTENSIONS ${COMPILER_EXTENSIONS}
106+
)
107+
108+
# enable tests only for standalone project
109+
if (ENABLE_TEST AND STANDALONE_PROJECT)
110+
add_subdirectory(test)
111+
endif ()
112+
113+
# disable compiler warnings if project is not a standalone project
114+
if (NOT STANDALONE_PROJECT)
115+
unset(COMPILER_WARNINGS)
116+
endif ()
117+
118+
set_definitions(${Target})
119+
if (ENABLE_MULTITHREADING AND OPENMP)
120+
set_options(${Target} ON)
121+
else ()
122+
set_options(${Target} OFF)
123+
endif ()
124+
125+
if (COMPILER_WARNINGS)
126+
enable_warnings(${Target})
127+
message(STATUS "Compiler warnings enabled.")
128+
else ()
129+
disable_warnings(${Target})
130+
message(STATUS "Compiler warnings disabled.")
131+
endif ()
132+
133+
if (ENABLE_MULTITHREADING)
134+
# required by threading lib (std::thread)
135+
set(THREADS_PREFER_PTHREAD_FLAG ON)
136+
find_package(Threads REQUIRED)
137+
target_link_libraries(${Target} PRIVATE Threads::Threads)
138+
endif ()
139+
140+
# ----------------------------------------------- doxygen documentation ------------------------------------------------
141+
# ======================================================================================================================
142+
if (BUILD_DOC AND NOT STANDALONE_PROJECT)
143+
# doxygen documentation (https://vicrucann.github.io/tutorials/quick-cmake-doxygen/)
144+
# check if Doxygen is installed
145+
find_package(Doxygen)
146+
if (DOXYGEN_FOUND)
147+
# set input and output files
148+
set(DOXYGEN_IN ${CMAKE_CURRENT_SOURCE_DIR}/Doxyfile.in)
149+
set(DOXYGEN_OUT ${CMAKE_CURRENT_BINARY_DIR}/Doxyfile)
150+
151+
if (EXISTS ${DOXYGEN_IN})
152+
# request to configure the file
153+
configure_file(${DOXYGEN_IN} ${DOXYGEN_OUT} @ONLY)
154+
message(STATUS "Doxygen configured")
155+
156+
# note the option ALL which allows to build the docs together with the application
157+
add_custom_target(doc_doxygen_${Target} ALL
158+
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
159+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
160+
COMMENT "Generating API documentation with Doxygen"
161+
VERBATIM)
162+
message(STATUS "Added target doc_doxygen_${Target}")
163+
164+
if (TARGET doc_doxygen)
165+
add_dependencies(doc_doxygen doc_doxygen_${Target})
166+
else ()
167+
add_custom_target(doc_doxygen DEPENDS doc_doxygen_${Target})
168+
endif ()
169+
else ()
170+
message(WARNING "doxygen documentation requested, but file ${DOXYGEN_IN} does not exist.")
171+
endif ()
172+
else (DOXYGEN_FOUND)
173+
message(WARNING "Doxygen must be installed and accessible to generate the doxygen documentation.")
174+
endif (DOXYGEN_FOUND)
175+
endif ()
176+
177+
# add clang format target
178+
if (CLANG_FORMAT AND NOT STANDALONE_PROJECT)
179+
set(CLANG_FORMAT_FILE ${CMAKE_CURRENT_SOURCE_DIR}/.clang-format)
180+
181+
if (EXISTS ${CLANG_FORMAT_FILE})
182+
include(cmake_files/ClangFormat.cmake)
183+
target_clangformat_setup(${Target})
184+
message(STATUS "Added clang format target(s)")
185+
else ()
186+
message(WARNING "Clang format enabled, but file ${CLANG_FORMAT_FILE} does not exist")
187+
endif ()
188+
endif ()
189+
190+
# generate version_info.cpp
191+
# output is not the acutal generated file --> command is always executed
192+
add_custom_command(
193+
OUTPUT
194+
${CMAKE_SOURCE_DIR}/src/generated/version_info_cpp
195+
196+
COMMAND
197+
bash ${CMAKE_SOURCE_DIR}/scripts/gen_version_info_cpp.sh ${PROJECT_NAME}
198+
199+
WORKING_DIRECTORY
200+
${CMAKE_SOURCE_DIR}
201+
)
202+
203+
execute_process(
204+
COMMAND bash "${CMAKE_SOURCE_DIR}/scripts/gen_version_info_cpp.sh" ${PROJECT_NAME}
205+
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
206+
)
207+
208+
add_custom_target(${Target}_generated_version_info
209+
DEPENDS ${CMAKE_SOURCE_DIR}/src/generated/version_info_cpp
210+
)
211+
212+
add_dependencies(${Target} ${Target}_generated_version_info)

0 commit comments

Comments
 (0)