-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGateauConfigure.cmake
256 lines (219 loc) · 10.3 KB
/
GateauConfigure.cmake
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
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
# Copyright Pierre-Antoine LACAZE 2018 - 2020.
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE_1_0.txt or copy at
# https://www.boost.org/LICENSE_1_0.txt)
# Initial configuration of a project
include(GateauHelpers)
include(GateauCompilerOptions)
include(GateauParseArguments)
# Setup build type
function(_gateau_setup_build_type)
if (GENERATOR_IS_MULTI_CONFIG)
if (NOT CMAKE_CONFIGURATION_TYPES)
set(CMAKE_CONFIGURATION_TYPES "Release;Debug" CACHE STRING "" FORCE)
endif()
else()
if (NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release CACHE STRING "Choose the type of build." FORCE)
endif()
endif()
endfunction()
# Setup prefix path to include the external prefix containing self installed deps
function(_gateau_setup_prefix_path)
# no external deps: we don't alter the prefix path
gateau_get(NO_BUILD_DEPS no_build_deps)
if (no_build_deps)
return()
endif()
gateau_external_install_prefix(dir)
set(path ${CMAKE_PREFIX_PATH})
if (NOT dir IN_LIST path)
list(PREPEND path "${dir}") # prepend to favor last change
set(CMAKE_PREFIX_PATH "${path}" CACHE STRING "" FORCE)
endif()
# Search paths are restricted in the cross toolchain files,
# however our install prefix is safe to use so we will add it.
set(path ${CMAKE_FIND_ROOT_PATH})
if (NOT dir IN_LIST path)
list(PREPEND path "${dir}") # prepend to favor last change
set(CMAKE_FIND_ROOT_PATH "${path}" PARENT_SCOPE)
endif()
endfunction()
# Setup reasonable defaults for commonly set cmake variables
macro(_gateau_setup_defaults)
# Static or Shared libraries
# If the library type is not provided, we create static libraries in release mode
# and dynamic libraries otherwise (linking is slow in debug, so we minimize it).
if (NOT DEFINED BUILD_SHARED_LIBS)
if (CMAKE_BUILD_TYPE STREQUAL "Release")
set(BUILD_SHARED_LIBS OFF)
else()
set(BUILD_SHARED_LIBS ON)
endif()
endif()
set(CMAKE_POSITION_INDEPENDENT_CODE ON)
# IDE
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
# Misc make options
set(CMAKE_COLOR_MAKEFILE ON)
set(CMAKE_VERBOSE_MAKEFILE ON)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Rpath handling
set(CMAKE_SKIP_BUILD_RPATH OFF)
set(CMAKE_BUILD_WITH_INSTALL_RPATH OFF)
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH ON)
if (APPLE)
set(CMAKE_MACOSX_RPATH ON)
endif()
set(CMAKE_BUILD_RPATH_USE_ORIGIN ON)
set(CMAKE_INSTALL_RPATH "$ORIGIN/../lib:$ORIGIN/../lib64:$ORIGIN")
# config mode should be preferred
set(CMAKE_FIND_PACKAGE_PREFER_CONFIG ON)
# Disable the package registry, which could mislead cmake into looking for
# packages in unexpected derectories
set(CMAKE_EXPORT_NO_PACKAGE_REGISTRY ON)
set(CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY ON)
set(CMAKE_FIND_USE_PACKAGE_REGISTRY OFF)
endmacro()
# Variables that are used internally
function(_gateau_setup_internal_variables)
# The identifier that will be used to prefix many variables, internal as well as user-facing
gateau_to_identifier("${PROJECT_NAME}" ident)
set(${PROJECT_NAME}_IDENT "${ident}" CACHE INTERNAL "")
# Project root dir
gateau_declare_internal(ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}")
# List of paths where package files can be found, extensible with gateau_add_package_module_dir()
gateau_declare_internal(PACKAGE_MODULES_DIRS "${CMAKE_CURRENT_LIST_DIR}/packages")
# Where template files can be found
gateau_declare_internal(TEMPLATES_DIR "${CMAKE_CURRENT_LIST_DIR}/templates")
# Where dependency files are manipulated
gateau_declare_internal(DEP_DIR "${PROJECT_BINARY_DIR}/gateau.cmake/dep")
# List of relative directory paths where headers are expected to be found in
# order to correctly find and compute their install destination.
gateau_declare_internal(RELATIVE_HEADERS_DIRS "src;include;Src;Source;Include")
# How to name generated headers: possible values are CAMEL, SNAKE and HYPHEN
gateau_declare_internal(GENERATED_HEADER_CASE SNAKE)
set_property(CACHE ${ident}_GENERATED_HEADER_CASE PROPERTY STRINGS "CAMEL;SNAKE;HYPHEN")
# generated headers extension
gateau_declare_internal(GENERATED_HEADER_EXT "hpp")
# target alias namespace: Namespace::Target
gateau_declare_internal(NAMESPACE "${PROJECT_NAME}")
# How we want our target files prefixed
gateau_declare_internal(NAME_PREFIX "")
gateau_declare_internal(LIBRARY_NAME_PREFIX "")
gateau_declare_internal(RUNTIME_NAME_PREFIX "")
# A default standard because this is often desired
gateau_declare_internal(C_STANDARD c_std_99)
gateau_declare_internal(CXX_STANDARD cxx_std_17)
# Nicer way of handling 32 or 64 bits
if (CMAKE_CXX_SIZEOF_DATA_PTR EQUAL 8)
gateau_declare_internal(X64 ON)
gateau_declare_internal(X32 OFF)
gateau_declare_internal(ARCH 64)
else()
gateau_declare_internal(X64 OFF)
gateau_declare_internal(X32 ON)
gateau_declare_internal(ARCH 32)
endif()
endfunction()
# Diverses CMake options are defined here and can be used project-wide to alter
# the way the project is set up.
# Those are user-facing options, so we make sure to create nice option names.
function(_gateau_declare_options)
# Options that can be used to build optional stuff
gateau_declare_option(BUILD_EXAMPLES ON "Build optional examples")
gateau_declare_option(BUILD_TESTS ON "Build tests")
gateau_declare_option(BUILD_DOC ON "Build documentation")
gateau_declare_option(BUILD_BENCHMARKS OFF "Build benchmarks")
# options that can alter the compilation
gateau_declare_option(ENABLE_AUTOSELECT_LINKER ON "Select the best available linker")
gateau_declare_option(ENABLE_COMMON_WARNINGS ON "Enable common compiler flags")
gateau_declare_option(ENABLE_WERROR ON "Enable werror for a few important compiler flags")
gateau_declare_option(ENABLE_LIBCXX OFF "Use libc++ instead of gcc standard library")
gateau_declare_option(ENABLE_LTO OFF "Enable link time optimization (release only)")
gateau_declare_option(ENABLE_MANY_WARNINGS OFF "Enable more compiler warnings")
gateau_declare_option(ENABLE_MARCH_NATIVE OFF "Enable optimizations for the host CPU")
gateau_declare_option(ENABLE_PROFILING OFF "Add compile flags to help with profiling")
gateau_declare_option(SPLIT_DEBUG_INFO OFF "Split debug info")
gateau_declare_option(SANITIZE_ADDRESS OFF "Compile with address sanitizer support")
gateau_declare_option(SANITIZE_THREADS OFF "Compile with thread sanitizer support")
gateau_declare_option(SANITIZE_UNDEFINED OFF "Compile with undefined sanitizer support")
gateau_declare_option(KEEP_TEMPS OFF "Keep temporary compiler-generated files for debugging purpose")
gateau_declare_option(USE_CCACHE OFF "Use Ccache to speed-up compilation")
# Allow/Update deps
gateau_declare_option(NO_BUILD_DEPS OFF "Disable external dependency build and installation")
gateau_declare_option(UPDATE_DEPS OFF "Fetch dependency updates each time the project is reconfigured")
# Other options pertaining to output
gateau_declare_var(OUTPUT_DIRECTORY "" "Where to put all target files when built" PATH)
gateau_declare_var(DOCUMENTATION_ROOT "" "Documentation installation root directory" PATH)
# External dependencies handling
gateau_declare_var(EXTERNAL_BUILD_TYPE Release "Build type used to build external packages" STRING)
gateau_declare_var(EXTERNAL_ROOT "" "Root directory where external packages get build" PATH)
gateau_declare_var(EXTERNAL_INSTALL_PREFIX "" "Prefix where to install external packages" PATH)
gateau_declare_var(DOWNLOAD_CACHE "" "Directory to store external packages code archives" PATH)
endfunction()
# Setup CMake with reasonable defaults
macro(gateau_init)
_gateau_setup_internal_variables()
_gateau_declare_options()
_gateau_setup_build_dirs()
_gateau_setup_build_type()
_gateau_setup_defaults()
_gateau_setup_prefix_path()
_gateau_setup_compiler_options()
# Some parts of Gateau may need to know if a parent project has already
# performed an earlier initialization.
set(_GATEAU_INIT_CALLED TRUE)
endmacro()
# Gateau offers a number of optional configuration options.
# This function is the recommended way of overriding those project-wide options from
# inside the main cmake list file. This is meant to be used by the project devs.
# The alternatives are setting the corresponding variables prior to inclusion of
# the main gateau module, or overriding the cache variables after inclusion.
# Users should set those options from the call to cmake at configure time.
function(gateau_configure)
# Offering a single API call seems a more practical solution to setting a bunch of variables.
set(bool_options
NO_BUILD_DEPS
UPDATE_DEPS
)
set(mono_options
C_STANDARD
CXX_STANDARD
GENERATED_HEADER_CASE
GENERATED_HEADER_EXT
OUTPUT_DIRECTORY
DOCUMENTATION_ROOT
DOWNLOAD_CACHE
EXTERNAL_BUILD_TYPE
EXTERNAL_ROOT
EXTERNAL_INSTALL_PREFIX
NAMESPACE
NAME_PREFIX
LIBRARY_NAME_PREFIX
RUNTIME_NAME_PREFIX
)
set(multi_options
RELATIVE_HEADERS_DIRS
)
# All the variables are already defined, using gateau_parse_arguments allows
# to obtain the current value if not set with gateau_configure()
gateau_parse_arguments(_O "${${PROJECT_NAME}_IDENT}" "${bool_options}" "${mono_options}" "${multi_options}" ${ARGN})
if (_O_UNPARSED_ARGUMENTS)
message(FATAL_ERROR "Unrecognized arguments in gateau_configure(): ${_O_UNPARSED_ARGUMENTS}")
endif()
foreach(opt ${bool_options} ${mono_options} ${multi_options})
gateau_set(${opt} "${_O_${opt}}")
endforeach()
# keep prefix path up to date
_gateau_setup_prefix_path()
endfunction()
# Declare other files of the project in a "category" mock target
function(gateau_other_files category)
# We use a custom target because some IDEs can't cope with source_group
if (NOT TARGET ${category})
add_custom_target(${category})
set_target_properties(${category} PROPERTIES PROJECT_LABEL "${category}")
endif()
set_property(TARGET ${category} APPEND PROPERTY SOURCES ${ARGN})
endfunction()