File: ranges_flags.cmake

package info (click to toggle)
range-v3 0.12.0-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,620 kB
  • sloc: cpp: 76,839; xml: 226; sh: 89; python: 34; makefile: 16; perl: 15
file content (301 lines) | stat: -rw-r--r-- 12,583 bytes parent folder | download | duplicates (2)
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
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
# Copyright Louis Dionne 2015
# Copyright Gonzalo Brito Gadeschi 2015
# Distributed under the Boost Software License, Version 1.0.
# (See accompanying file LICENSE.md or copy at http://boost.org/LICENSE_1_0.txt)
#
# Setup compiler flags (more can be set on a per-target basis or in
# subdirectories)

# Compilation flags
include(CheckCXXCompilerFlag)
macro(ranges_append_flag testname flag)
  # As -Wno-* flags do not lead to build failure when there are no other
  # diagnostics, we check positive option to determine their applicability.
  # Of course, we set the original flag that is requested in the parameters.
  string(REGEX REPLACE "^-Wno-" "-W" alt ${flag})
  check_cxx_compiler_flag(${alt} ${testname})
  if (${testname})
    add_compile_options(${flag})
  endif()
endmacro()

function(cxx_standard_normalize cxx_standard return_value)
  if("x${cxx_standard}" STREQUAL "x1y")
    set( ${return_value} "14" PARENT_SCOPE )
  elseif("x${cxx_standard}" STREQUAL "x1z")
    set( ${return_value} "17" PARENT_SCOPE )
  elseif("x${cxx_standard}" STREQUAL "xlatest" OR "x${cxx_standard}" STREQUAL "x2a")
    set( ${return_value} "20" PARENT_SCOPE )
  else()
    set( ${return_value} "${cxx_standard}" PARENT_SCOPE )
  endif()
endfunction()

function(cxx_standard_denormalize cxx_standard return_value)
  if("x${cxx_standard}" STREQUAL "x17")
    if (RANGES_CXX_COMPILER_CLANGCL OR RANGES_CXX_COMPILER_MSVC)
      set( ${return_value} 17 PARENT_SCOPE )
    else()
      set( ${return_value} 1z PARENT_SCOPE )
    endif()
  elseif("x${cxx_standard}" STREQUAL "x20")
    if (RANGES_CXX_COMPILER_CLANGCL OR RANGES_CXX_COMPILER_MSVC)
      set( ${return_value} latest PARENT_SCOPE )
    else()
      set( ${return_value} 2a PARENT_SCOPE )
    endif()
  else()
    set( ${return_value} ${cxx_standard} PARENT_SCOPE )
  endif()
endfunction()

if(CMAKE_CXX_STANDARD)
  if(NOT "x${RANGES_CXX_STD}" STREQUAL "xdefault")
    # Normalize RANGES_CXX_STD
    cxx_standard_normalize( ${RANGES_CXX_STD} ranges_cxx_std )
    if(NOT "x${ranges_cxx_std}" STREQUAL "x${CMAKE_CXX_STANDARD}")
      message(FATAL_ERROR "[range-v3]: Cannot specify both CMAKE_CXX_STANDARD and RANGES_CXX_STD, or they must match.")
    endif()
  else()
    cxx_standard_denormalize(${CMAKE_CXX_STANDARD} RANGES_CXX_STD)
  endif()
elseif("x${RANGES_CXX_STD}" STREQUAL "xdefault")
  if (RANGES_CXX_COMPILER_CLANGCL OR RANGES_CXX_COMPILER_MSVC)
    set(RANGES_CXX_STD 17)
  else()
    set(RANGES_CXX_STD 14)
  endif()
endif()

# All compilation flags
# Language flag: version of the C++ standard to use
message(STATUS "[range-v3]: C++ std=${RANGES_CXX_STD}")
if (RANGES_CXX_COMPILER_CLANGCL OR RANGES_CXX_COMPILER_MSVC)
  ranges_append_flag(RANGES_HAS_CXXSTDCOLON "/std:c++${RANGES_CXX_STD}")
  set(RANGES_STD_FLAG "/std:c++${RANGES_CXX_STD}")
  if (RANGES_CXX_COMPILER_CLANGCL)
    # The MSVC STL before VS 2019v16.6 with Clang 10 requires -fms-compatibility in C++17 mode, and
    # doesn't support C++20 mode at all. Let's drop this flag until AppVeyor updates to VS2016v16.6.
    # ranges_append_flag(RANGES_HAS_FNO_MS_COMPATIBIILITY "-fno-ms-compatibility")
    ranges_append_flag(RANGES_HAS_FNO_DELAYED_TEMPLATE_PARSING "-fno-delayed-template-parsing")
  endif()
  # Enable "normal" warnings and make them errors:
  ranges_append_flag(RANGES_HAS_W3 /W3)
  ranges_append_flag(RANGES_HAS_WX /WX)
else()
  ranges_append_flag(RANGES_HAS_CXXSTD "-std=c++${RANGES_CXX_STD}")
  set(RANGES_STD_FLAG "-std=c++${RANGES_CXX_STD}")
  # Enable "normal" warnings and make them errors:
  ranges_append_flag(RANGES_HAS_WALL -Wall)
  ranges_append_flag(RANGES_HAS_WEXTRA -Wextra)
  if (RANGES_ENABLE_WERROR)
    ranges_append_flag(RANGES_HAS_WERROR -Werror)
  endif()
endif()

if (RANGES_ENV_LINUX AND RANGES_CXX_COMPILER_CLANG)
  # On linux libc++ re-exports the system math headers. The ones from libstdc++
  # use the GCC __extern_always_inline intrinsic which is not supported by clang
  # versions 3.6, 3.7, 3.8, 3.9, 4.0, and current trunk 5.0 (as of 2017.04.13).
  #
  # This works around it by replacing __extern_always_inline with inline using a
  # macro:
  ranges_append_flag(RANGES_HAS_D__EXTERN_ALWAYS_INLINE -D__extern_always_inline=inline)
endif()

# Deep integration support
if (RANGES_DEEP_STL_INTEGRATION)
  if (RANGES_CXX_COMPILER_MSVC)
    add_compile_options(/I "${PROJECT_SOURCE_DIR}/include/std")
    add_compile_options(/I "${PROJECT_SOURCE_DIR}/include")
  else()
    add_compile_options(-isystem "${PROJECT_SOURCE_DIR}/include/std")
    add_compile_options(-I "${PROJECT_SOURCE_DIR}/include")
  endif()
  add_compile_options(-DRANGES_DEEP_STL_INTEGRATION=1)
endif()

# Template diagnostic flags
ranges_append_flag(RANGES_HAS_FDIAGNOSTIC_SHOW_TEMPLATE_TREE -fdiagnostics-show-template-tree)
ranges_append_flag(RANGES_HAS_FTEMPLATE_BACKTRACE_LIMIT "-ftemplate-backtrace-limit=0")
ranges_append_flag(RANGES_HAS_FMACRO_BACKTRACE_LIMIT "-fmacro-backtrace-limit=1")

# Clang modules support
if (RANGES_MODULES)
  ranges_append_flag(RANGES_HAS_MODULES -fmodules)
  ranges_append_flag(RANGES_HAS_MODULE_MAP_FILE "-fmodule-map-file=${PROJECT_SOURCE_DIR}/include/module.modulemap")
  ranges_append_flag(RANGES_HAS_MODULE_CACHE_PATH "-fmodules-cache-path=${PROJECT_BINARY_DIR}/module.cache")
  if (RANGES_LIBCXX_MODULE)
    ranges_append_flag(RANGES_HAS_LIBCXX_MODULE_MAP_FILE "-fmodule-map-file=${RANGES_LIBCXX_MODULE}")
  endif()
  if (RANGES_ENV_MACOSX)
    ranges_append_flag(RANGES_HAS_NO_IMPLICIT_MODULE_MAPS -fno-implicit-module-maps)
  endif()
  if (RANGES_DEBUG_BUILD)
    ranges_append_flag(RANGES_HAS_GMODULES -gmodules)
  endif()
endif()

# Sanitizer support: detect incompatible sanitizer combinations
if (RANGES_ASAN AND RANGES_MSAN)
  message(FATAL_ERROR "[range-v3 error]: AddressSanitizer and MemorySanitizer are both enabled at the same time!")
endif()

if (RANGES_MSAN AND RANGES_ENV_MACOSX)
  message(FATAL_ERROR "[range-v3 error]: MemorySanitizer is not supported on MacOSX!")
endif()

# AddressSanitizer support
if (RANGES_ASAN)
  # This policy enables passing the linker flags to the linker when trying to
  # test the features, which is required to successfully link ASan binaries
  cmake_policy(SET CMP0056 NEW)
  set (ASAN_FLAGS "")
  if (RANGES_ENV_MACOSX) # LeakSanitizer not supported on MacOSX
    set (ASAN_FLAGS "-fsanitize=address,signed-integer-overflow,shift,integer-divide-by-zero,implicit-signed-integer-truncation,implicit-integer-sign-change,undefined,nullability")
  else()
    if (RANGES_CXX_COMPILER_CLANG AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS "4.0")
      set (ASAN_FLAGS "-fsanitize=address")
    else()
      set (ASAN_FLAGS "-fsanitize=address,signed-integer-overflow,shift,integer-divide-by-zero,implicit-signed-integer-truncation,implicit-integer-sign-change,leak,nullability")
    endif()
  endif()
  ranges_append_flag(RANGES_HAS_ASAN "${ASAN_FLAGS}")
  if (RANGES_HAS_ASAN) #ASAN flags must be passed to the linker:
    set(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${ASAN_FLAGS}")
  endif()
  ranges_append_flag(RANGES_HAS_SANITIZE_NO_RECOVER "-fno-sanitize-recover=all")
  ranges_append_flag(RANGES_HAS_NO_OMIT_FRAME_POINTER -fno-omit-frame-pointer)
endif()

# MemorySanitizer support
if (RANGES_MSAN)
  # This policy enables passing the linker flags to the linker when trying to
  # compile the examples, which is required to successfully link MSan binaries
  cmake_policy(SET CMP0056 NEW)
  ranges_append_flag(RANGES_HAS_MSAN "-fsanitize=memory")
  ranges_append_flag(RANGES_HAS_MSAN_TRACK_ORIGINS -fsanitize-memory-track-origins)
  ranges_append_flag(RANGES_HAS_SANITIZE_RECOVER_ALL "-fno-sanitize-recover=all")
  ranges_append_flag(RANGES_HAS_NO_OMIT_FRAME_POINTER -fno-omit-frame-pointer)
endif()

# Build types:
if (RANGES_DEBUG_BUILD AND RANGES_RELEASE_BUILD)
  message(FATAL_ERROR "[range-v3 error] Cannot simultaneously generate debug and release builds!")
endif()

if (RANGES_DEBUG_BUILD)
  ranges_append_flag(RANGES_HAS_NO_INLINE -fno-inline)
  ranges_append_flag(RANGES_HAS_STACK_PROTECTOR_ALL -fstack-protector-all)
  ranges_append_flag(RANGES_HAS_G3 -g3)
  # Clang can generate debug info tuned for LLDB or GDB
  if (RANGES_CXX_COMPILER_CLANG)
    if (RANGES_ENV_MACOSX)
      ranges_append_flag(RANGES_HAS_GLLDB -glldb)
    elseif(RANGES_ENV_LINUX OR RANGES_ENV_OPENBSD)
      ranges_append_flag(RANGES_HAS_GGDB -ggdb)
    endif()
  endif()
endif()

if (RANGES_RELEASE_BUILD)
  if (NOT RANGES_ASSERTIONS)
    ranges_append_flag(RANGES_HAS_DNDEBUG -DNDEBUG)
  endif()
  if (NOT RANGES_ASAN AND NOT RANGES_MSAN)
    # The quality of ASan and MSan error messages suffers if we disable the
    # frame pointer, so leave it enabled when compiling with either of them:
    ranges_append_flag(RANGES_HAS_OMIT_FRAME_POINTER -fomit-frame-pointer)
  endif()

  ranges_append_flag(RANGES_HAS_OFAST -Ofast)
  if (NOT RANGES_HAS_OFAST)
    ranges_append_flag(RANGES_HAS_O2 -O2)
  endif()
  ranges_append_flag(RANGES_HAS_STRICT_ALIASING -fstrict-aliasing)
  ranges_append_flag(RANGES_HAS_STRICT_VTABLE_POINTERS -fstrict-vtable-pointers)
  ranges_append_flag(RANGES_HAS_FAST_MATH -ffast-math)
  ranges_append_flag(RANGES_HAS_VECTORIZE -fvectorize)

  if (NOT RANGES_ENV_MACOSX)
    # Sized deallocation is not available in MacOSX:
    ranges_append_flag(RANGES_HAS_SIZED_DEALLOCATION -fsized-deallocation)
  endif()

  if (RANGES_LLVM_POLLY)
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -polly -mllvm -polly-vectorizer=stripmine")
  endif()

  if (RANGES_CXX_COMPILER_CLANG AND (NOT (RANGES_INLINE_THRESHOLD EQUAL -1)))
    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mllvm -inline-threshold=${RANGES_INLINE_THRESHOLD}")
  endif()
endif()

if (RANGES_NATIVE)
  ranges_append_flag(RANGES_HAS_MARCH_NATIVE "-march=native")
  ranges_append_flag(RANGES_HAS_MTUNE_NATIVE "-mtune=native")
endif()

include(CheckCXXSourceCompiles)

set(CMAKE_REQUIRED_FLAGS ${RANGES_STD_FLAG})
# Probe for library and compiler support for aligned new
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/aligned_new_probe.cpp" RANGE_V3_PROBE_CODE)
check_cxx_source_compiles("${RANGE_V3_PROBE_CODE}" RANGE_V3_ALIGNED_NEW_PROBE)
unset(RANGE_V3_PROBE_CODE)
unset(CMAKE_REQUIRED_FLAGS)
if (NOT RANGE_V3_ALIGNED_NEW_PROBE)
  add_compile_options("-DRANGES_CXX_ALIGNED_NEW=0")
endif()

# Probe for coroutine TS support
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/coro_test_code.cpp" RANGE_V3_PROBE_CODE)
if(RANGES_CXX_COMPILER_MSVC)
  set(CMAKE_REQUIRED_FLAGS "/await")
  check_cxx_source_compiles("${RANGE_V3_PROBE_CODE}" RANGES_HAS_AWAIT)
  if(RANGES_HAS_AWAIT)
    set(RANGE_V3_COROUTINE_FLAGS "/await")
  endif()
elseif(RANGES_CXX_COMPILER_CLANG)
  set(CMAKE_REQUIRED_FLAGS "-fcoroutines-ts ${RANGES_STD_FLAG}")
  check_cxx_source_compiles("${RANGE_V3_PROBE_CODE}" RANGES_HAS_FCOROUTINES_TS)
  if(RANGES_HAS_FCOROUTINES_TS)
    set(RANGE_V3_COROUTINE_FLAGS "-fcoroutines-ts")
  endif()
endif()
unset(CMAKE_REQUIRED_FLAGS)
unset(RANGE_V3_PROBE_CODE)
if (RANGE_V3_COROUTINE_FLAGS)
  add_compile_options(${RANGE_V3_COROUTINE_FLAGS})
endif()

# Test for concepts support
file(READ "${CMAKE_CURRENT_SOURCE_DIR}/cmake/concepts_test_code.cpp" RANGE_V3_PROBE_CODE)
if(RANGES_CXX_COMPILER_GCC OR RANGES_CXX_COMPILER_CLANG)
  set(CMAKE_REQUIRED_FLAGS "-fconcepts ${RANGES_STD_FLAG}")
  check_cxx_source_compiles("${RANGE_V3_PROBE_CODE}" RANGE_V3_HAS_FCONCEPTS)
  if(RANGE_V3_HAS_FCONCEPTS)
    set(RANGE_V3_CONCEPTS_FLAGS "-fconcepts")
  endif()
endif()
unset(CMAKE_REQUIRED_FLAGS)
unset(RANGE_V3_PROBE_CODE)
if (RANGE_V3_CONCEPTS_FLAGS AND RANGES_PREFER_REAL_CONCEPTS)
  add_compile_options(${RANGE_V3_CONCEPTS_FLAGS})
endif()

if (RANGES_VERBOSE_BUILD)
  get_directory_property(RANGES_COMPILE_OPTIONS COMPILE_OPTIONS)
  message(STATUS "[range-v3]: C++ flags: ${CMAKE_CXX_FLAGS}")
  message(STATUS "[range-v3]: C++ debug flags: ${CMAKE_CXX_FLAGS_DEBUG}")
  message(STATUS "[range-v3]: C++ Release Flags: ${CMAKE_CXX_FLAGS_RELEASE}")
  message(STATUS "[range-v3]: C++ Compile Flags: ${CMAKE_CXX_COMPILE_FLAGS}")
  message(STATUS "[range-v3]: Compile options: ${RANGES_COMPILE_OPTIONS}")
  message(STATUS "[range-v3]: C Flags: ${CMAKE_C_FLAGS}")
  message(STATUS "[range-v3]: C Compile Flags: ${CMAKE_C_COMPILE_FLAGS}")
  message(STATUS "[range-v3]: EXE Linker flags: ${CMAKE_EXE_LINKER_FLAGS}")
  message(STATUS "[range-v3]: C++ Linker flags: ${CMAKE_CXX_LINK_FLAGS}")
  message(STATUS "[range-v3]: MODULE Linker flags: ${CMAKE_MODULE_LINKER_FLAGS}")
  get_directory_property(CMakeCompDirDefs COMPILE_DEFINITIONS)
  message(STATUS "[range-v3]: Compile Definitions: ${CmakeCompDirDefs}")
endif()