-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCMakeLists.txt
222 lines (190 loc) · 9.71 KB
/
CMakeLists.txt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
cmake_minimum_required(VERSION 3.15.0)
project(cieutils LANGUAGES CXX VERSION 0.0.0)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
string(TOUPPER ${PROJECT_NAME} PROJECT_NAME_UPPER)
# Declare all CMake settings
set(${PROJECT_NAME_UPPER}_BUILD_SHARED_LIBRARY ON CACHE BOOL "build shared libraries instead of static ones")
set(${PROJECT_NAME_UPPER}_BUILD_PYTHON_MODULE ON CACHE BOOL "build python bindings for ${PROJECT_NAME}")
set(${PROJECT_NAME_UPPER}_BUILD_TESTS ON CACHE BOOL "build testrunner for ${PROJECT_NAME}")
set(${PROJECT_NAME_UPPER}_ENABLE_MPI OFF CACHE BOOL "Build with MPI support")
set(${PROJECT_NAME_UPPER}_ENABLE_PROFILING OFF CACHE BOOL "Enable profiling macros.")
set(${PROJECT_NAME_UPPER}_ENABLE_OUT_OF_RANGE_CHECKS OFF CACHE BOOL "Enable macros for checking out-of-range errors.")
set(${PROJECT_NAME_UPPER}_ENABLE_DIVISION_BY_ZERO_CHECKS OFF CACHE BOOL "Enable macros for checking division by zero errors.")
# Static paths
if(UNIX)
set(${PROJECT_NAME_UPPER}_INSTALL_DATA_DIR "${CMAKE_INSTALL_PREFIX}/cie/data" CACHE STRING "")
set(${PROJECT_NAME_UPPER}_OUTPUT_DIR "." CACHE STRING "")
elseif(APPLE)
set(${PROJECT_NAME_UPPER}_INSTALL_DATA_DIR "${CMAKE_INSTALL_PREFIX}/cie/data" CACHE STRING "")
set(${PROJECT_NAME_UPPER}_OUTPUT_DIR "." CACHE STRING "")
elseif(WIN32)
message(FATAL_ERROR "Unsupported OS")
else()
message(FATAL_ERROR "Unsupported OS")
endif()
# Language server
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Collect dependencies
find_package(nlohmann_json REQUIRED)
# Get the current commit hash
find_package(Git)
if (${Git_FOUND})
execute_process(COMMAND
"${GIT_EXECUTABLE}" rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE ${PROJECT_NAME_UPPER}_BRANCH_NAME
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND
"${GIT_EXECUTABLE}" rev-parse HEAD
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}"
OUTPUT_VARIABLE ${PROJECT_NAME_UPPER}_COMMIT_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
set(${PROJECT_NAME_UPPER}_BRANCH_NAME "unavailable")
set(${PROJECT_NAME_UPPER}_COMMIT_HASH "unavailable")
endif()
# Generate sources from source templates
file(GLOB source_templates "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp.in")
foreach(source_template ${source_templates})
# Configure and output to intermediate file (read-write permissions)
get_filename_component(source_template_name "${source_template}" NAME_WE)
configure_file("${source_template}" "${CMAKE_CURRENT_SOURCE_DIR}/src/${source_template_name}.cpp")
# Withdraw write permission from the generated file
file(CHMOD
"${CMAKE_CURRENT_SOURCE_DIR}/src/${source_template_name}.cpp"
FILE_PERMISSIONS OWNER_READ GROUP_READ WORLD_READ)
endforeach()
# Compile definitions
if(${PROJECT_NAME_UPPER}_ENABLE_PROFILING)
add_compile_definitions(CIE_ENABLE_PROFILING=1)
endif()
if(${PROJECT_NAME_UPPER}_ENABLE_OUT_OF_RANGE_CHECKS)
add_compile_definitions(CIE_ENABLE_OUT_OF_RANGE_CHECKS=1)
endif()
if(${PROJECT_NAME_UPPER}_ENABLE_DIVISION_BY_ZERO_CHECKS)
add_compile_definitions(CIE_ENABLE_DIVISION_BY_ZERO_CHECKS=1)
endif()
add_compile_options(-Wall -Wpedantic -Wextra -Wno-dangling-reference -Werror)
# Build main library
file(GLOB_RECURSE sources "${CMAKE_CURRENT_SOURCE_DIR}/packages/*/src/*.cpp" "${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp")
if (${${PROJECT_NAME_UPPER}_BUILD_SHARED_LIBRARY} OR ${${PROJECT_NAME_UPPER}_BUILD_PYTHON_MODULE})
add_library(${PROJECT_NAME} SHARED ${sources})
set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE 1)
else()
add_library(${PROJECT_NAME} STATIC ${sources})
endif()
target_link_libraries(${PROJECT_NAME} PRIVATE nlohmann_json)
target_include_directories(${PROJECT_NAME}
PRIVATE "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/tessil/include>"
INTERFACE "$<INSTALL_INTERFACE:cie/include>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/inc>"
"$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/external/tessil/include>")
set_target_properties(${PROJECT_NAME} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
INSTALL_RPATH "$ORIGIN")
# MPI support
if (${PROJECT_NAME_UPPER}_ENABLE_MPI)
find_package(MPI REQUIRED)
target_include_directories(${PROJECT_NAME} PRIVATE "${MPI_INCLUDE_PATH}")
target_compile_definitions(${PROJECT_NAME} PUBLIC "${PROJECT_NAME_UPPER}_COMPILE_MPI")
target_link_libraries(${PROJECT_NAME} PUBLIC MPI::MPI_CXX)
endif()
# Build test executable
if (${PROJECT_NAME_UPPER}_BUILD_TESTS)
file(GLOB_RECURSE test_sources "${CMAKE_CURRENT_SOURCE_DIR}/packages/*/test/*.cpp")
list(INSERT test_sources 0 "${CMAKE_CURRENT_SOURCE_DIR}/test/${PROJECT_NAME}_testrunner.cpp")
find_package(Catch2 REQUIRED)
add_executable(${PROJECT_NAME}_testrunner ${test_sources})
target_link_libraries(${PROJECT_NAME}_testrunner PRIVATE ${PROJECT_NAME} Catch2::Catch2)
set_target_properties(${PROJECT_NAME}_testrunner PROPERTIES
RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
endif()
# Build python module
if (${PROJECT_NAME_UPPER}_BUILD_PYTHON_MODULE)
set_property(TARGET ${PROJECT_NAME} PROPERTY POSITION_INDEPENDENT_CODE 1)
find_package(pybind11 REQUIRED)
file(GLOB_RECURSE python_module_sources "${CMAKE_CURRENT_SOURCE_DIR}/python/bindings/*.cpp")
pybind11_add_module(${PROJECT_NAME}_python_bindings MODULE ${python_module_sources})
target_link_libraries(${PROJECT_NAME}_python_bindings PRIVATE ${PROJECT_NAME})
set_target_properties(${PROJECT_NAME}_python_bindings PROPERTIES
LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/lib"
INSTALL_RPATH "$ORIGIN")
# Each subdirectory in modules is assumed to be a python module
# and is installed as-is
file(GLOB children "${CMAKE_CURRENT_SOURCE_DIR}/python/modules/*")
foreach(child ${children})
if (IS_DIRECTORY "${child}")
get_filename_component(module_name "${child}" NAME)
install(DIRECTORY "${child}"
DESTINATION "cie")
endif()
endforeach()
# Install bindings
install(TARGETS ${PROJECT_NAME}_python_bindings
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION "cie/lib")
# Main CiE module __init__
install(FILES "${CMAKE_CURRENT_SOURCE_DIR}/python/modules/__init__.py" DESTINATION "cie")
endif()
# Package
include(InstallRequiredSystemLibraries)
set(CPACK_PACKAGE_VENDOR "")
set(CPACK_PACKAGE_DESCRIPTION_SUMMARY "")
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/license")
set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/readme")
set(CPACK_SOURCE_GENERATOR "TGZ;ZIP")
set(CPACK_SOURCE_IGNORE_FILES
/.git
/build
*.gitignore)
include(CPack)
# Generate CMake config
include(CMakePackageConfigHelpers)
configure_package_config_file("${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
INSTALL_DESTINATION "lib/cmake/${PROJECT_NAME}"
NO_SET_AND_CHECK_MACRO
NO_CHECK_REQUIRED_COMPONENTS_MACRO)
write_basic_package_version_file("${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
VERSION "${${PROJECT_NAME}_VERSION_MAJOR}.${${PROJECT_NAME}_VERSION_MINOR}"
COMPATIBILITY AnyNewerVersion)
# Install targets
install(TARGETS ${PROJECT_NAME}
EXPORT ${PROJECT_NAME}Targets
LIBRARY DESTINATION "cie/lib"
ARCHIVE DESTINATION "cie/lib"
RUNTIME DESTINATION "cie/bin"
INCLUDES DESTINATION "cie/include")
install(EXPORT ${PROJECT_NAME}Targets
FILE ${PROJECT_NAME}Targets.cmake
NAMESPACE cie::
DESTINATION "cie/lib/cmake/${PROJECT_NAME}")
# Install headers
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/packages"
DESTINATION "cie/include"
FILES_MATCHING PATTERN "*.hpp")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/inc"
DESTINATION "cie/include"
FILES_MATCHING PATTERN "*.hpp")
install(DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}/external"
DESTINATION "cie/include"
FILES_MATCHING PATTERN "*.h*")
# Install CMake config
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}Config.cmake"
"${CMAKE_CURRENT_BINARY_DIR}/${PROJECT_NAME}ConfigVersion.cmake"
DESTINATION "cie/lib/cmake/${PROJECT_NAME}")
# Export
set(CMAKE_EXPORT_PACKAGE_REGISTRY ON)
export(TARGETS ${PROJECT_NAME}
NAMESPACE cie::
FILE ${PROJECT_NAME}Targets.cmake)
export(PACKAGE ${PROJECT_NAME})