xref: /openbsd-src/gnu/llvm/libcxx/cmake/Modules/HandleLibcxxFlags.cmake (revision 4bdff4bed0e3d54e55670334c7d0077db4170f86)
1# HandleLibcxxFlags - A set of macros used to setup the flags used to compile
2# and link libc++. These macros add flags to the following CMake variables.
3# - LIBCXX_COMPILE_FLAGS: flags used to compile libc++
4# - LIBCXX_LINK_FLAGS: flags used to link libc++
5# - LIBCXX_LIBRARIES: libraries to link libc++ to.
6
7include(CheckCXXCompilerFlag)
8
9unset(add_flag_if_supported)
10
11# Mangle the name of a compiler flag into a valid CMake identifier.
12# Ex: --std=c++11 -> STD_EQ_CXX11
13macro(mangle_name str output)
14  string(STRIP "${str}" strippedStr)
15  string(REGEX REPLACE "^/" "" strippedStr "${strippedStr}")
16  string(REGEX REPLACE "^-+" "" strippedStr "${strippedStr}")
17  string(REGEX REPLACE "-+$" "" strippedStr "${strippedStr}")
18  string(REPLACE "-" "_" strippedStr "${strippedStr}")
19  string(REPLACE ":" "_COLON_" strippedStr "${strippedStr}")
20  string(REPLACE "=" "_EQ_" strippedStr "${strippedStr}")
21  string(REPLACE "+" "X" strippedStr "${strippedStr}")
22  string(TOUPPER "${strippedStr}" ${output})
23endmacro()
24
25# Remove a list of flags from all CMake variables that affect compile flags.
26# This can be used to remove unwanted flags specified on the command line
27# or added in other parts of LLVM's cmake configuration.
28macro(remove_flags)
29  foreach(var ${ARGN})
30    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG}")
31    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_MINSIZEREL "${CMAKE_CXX_FLAGS_MINSIZEREL}")
32    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE}")
33    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS_RELWITHDEBINFO "${CMAKE_CXX_FLAGS_RELWITHDEBINFO}")
34    string(REPLACE "${var}" "" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
35    string(REPLACE "${var}" "" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}")
36    string(REPLACE "${var}" "" CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS}")
37    string(REPLACE "${var}" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}")
38    string(REPLACE "${var}" "" CMAKE_SHARED_MODULE_FLAGS "${CMAKE_SHARED_MODULE_FLAGS}")
39    remove_definitions(${var})
40  endforeach()
41endmacro(remove_flags)
42
43macro(check_flag_supported flag)
44    mangle_name("${flag}" flagname)
45    check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
46endmacro()
47
48macro(append_flags DEST)
49  foreach(value ${ARGN})
50    list(APPEND ${DEST} ${value})
51    list(APPEND ${DEST} ${value})
52  endforeach()
53endmacro()
54
55# If the specified 'condition' is true then append the specified list of flags to DEST
56macro(append_flags_if condition DEST)
57  if (${condition})
58    list(APPEND ${DEST} ${ARGN})
59  endif()
60endmacro()
61
62# Add each flag in the list specified by DEST if that flag is supported by the current compiler.
63macro(append_flags_if_supported DEST)
64  foreach(flag ${ARGN})
65    mangle_name("${flag}" flagname)
66    check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
67    append_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${DEST} ${flag})
68  endforeach()
69endmacro()
70
71# Add a macro definition if condition is true.
72macro(define_if condition def)
73  if (${condition})
74    add_definitions(${def})
75  endif()
76endmacro()
77
78# Add a macro definition if condition is not true.
79macro(define_if_not condition def)
80  if (NOT ${condition})
81    add_definitions(${def})
82  endif()
83endmacro()
84
85# Add a macro definition to the __config_site file if the specified condition
86# is 'true'. Note that '-D${def}' is not added. Instead it is expected that
87# the build include the '__config_site' header.
88macro(config_define_if condition def)
89  if (${condition})
90    set(${def} ON)
91  endif()
92endmacro()
93
94macro(config_define_if_not condition def)
95  if (NOT ${condition})
96    set(${def} ON)
97  endif()
98endmacro()
99
100macro(config_define value def)
101  set(${def} ${value})
102endmacro()
103
104# Add a list of flags to all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS',
105# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'.
106macro(add_target_flags)
107  foreach(value ${ARGN})
108    set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${value}")
109    set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${value}")
110    list(APPEND LIBCXX_COMPILE_FLAGS ${value})
111    list(APPEND LIBCXX_LINK_FLAGS ${value})
112  endforeach()
113endmacro()
114
115# If the specified 'condition' is true then add a list of flags to
116# all of 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXX_COMPILE_FLAGS'
117# and 'LIBCXX_LINK_FLAGS'.
118macro(add_target_flags_if condition)
119  if (${condition})
120    add_target_flags(${ARGN})
121  endif()
122endmacro()
123
124# Add all the flags supported by the compiler to all of
125# 'CMAKE_CXX_FLAGS', 'CMAKE_C_FLAGS', 'LIBCXX_COMPILE_FLAGS'
126# and 'LIBCXX_LINK_FLAGS'.
127macro(add_target_flags_if_supported)
128  foreach(flag ${ARGN})
129    mangle_name("${flag}" flagname)
130    check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
131    add_target_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag})
132  endforeach()
133endmacro()
134
135# Add a specified list of flags to both 'LIBCXX_COMPILE_FLAGS' and
136# 'LIBCXX_LINK_FLAGS'.
137macro(add_flags)
138  foreach(value ${ARGN})
139    list(APPEND LIBCXX_COMPILE_FLAGS ${value})
140    list(APPEND LIBCXX_LINK_FLAGS ${value})
141  endforeach()
142endmacro()
143
144# If the specified 'condition' is true then add a list of flags to both
145# 'LIBCXX_COMPILE_FLAGS' and 'LIBCXX_LINK_FLAGS'.
146macro(add_flags_if condition)
147  if (${condition})
148    add_flags(${ARGN})
149  endif()
150endmacro()
151
152# Add each flag in the list to LIBCXX_COMPILE_FLAGS and LIBCXX_LINK_FLAGS
153# if that flag is supported by the current compiler.
154macro(add_flags_if_supported)
155  foreach(flag ${ARGN})
156      mangle_name("${flag}" flagname)
157      check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
158      add_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag})
159  endforeach()
160endmacro()
161
162# Add a list of flags to 'LIBCXX_COMPILE_FLAGS'.
163macro(add_compile_flags)
164  foreach(f ${ARGN})
165    list(APPEND LIBCXX_COMPILE_FLAGS ${f})
166  endforeach()
167endmacro()
168
169# If 'condition' is true then add the specified list of flags to
170# 'LIBCXX_COMPILE_FLAGS'
171macro(add_compile_flags_if condition)
172  if (${condition})
173    add_compile_flags(${ARGN})
174  endif()
175endmacro()
176
177# For each specified flag, add that flag to 'LIBCXX_COMPILE_FLAGS' if the
178# flag is supported by the C++ compiler.
179macro(add_compile_flags_if_supported)
180  foreach(flag ${ARGN})
181      mangle_name("${flag}" flagname)
182      check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
183      add_compile_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag})
184  endforeach()
185endmacro()
186
187# Add a list of flags to 'LIBCXX_LINK_FLAGS'.
188macro(add_link_flags)
189  foreach(f ${ARGN})
190    list(APPEND LIBCXX_LINK_FLAGS ${f})
191  endforeach()
192endmacro()
193
194# If 'condition' is true then add the specified list of flags to
195# 'LIBCXX_LINK_FLAGS'
196macro(add_link_flags_if condition)
197  if (${condition})
198    add_link_flags(${ARGN})
199  endif()
200endmacro()
201
202# For each specified flag, add that flag to 'LIBCXX_LINK_FLAGS' if the
203# flag is supported by the C++ compiler.
204macro(add_link_flags_if_supported)
205  foreach(flag ${ARGN})
206    mangle_name("${flag}" flagname)
207    check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
208    add_link_flags_if(CXX_SUPPORTS_${flagname}_FLAG ${flag})
209  endforeach()
210endmacro()
211
212# Add a list of libraries or link flags to 'LIBCXX_LIBRARIES'.
213macro(add_library_flags)
214  foreach(lib ${ARGN})
215    list(APPEND LIBCXX_LIBRARIES ${lib})
216  endforeach()
217endmacro()
218
219# if 'condition' is true then add the specified list of libraries and flags
220# to 'LIBCXX_LIBRARIES'.
221macro(add_library_flags_if condition)
222  if(${condition})
223    add_library_flags(${ARGN})
224  endif()
225endmacro()
226
227# Turn a comma separated CMake list into a space separated string.
228macro(split_list listname)
229  string(REPLACE ";" " " ${listname} "${${listname}}")
230endmacro()
231
232# For each specified flag, add that link flag to the provided target.
233# The flags are added with the given visibility, i.e. PUBLIC|PRIVATE|INTERFACE.
234function(target_add_link_flags_if_supported target visibility)
235  foreach(flag ${ARGN})
236    mangle_name("${flag}" flagname)
237    check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
238    if (CXX_SUPPORTS_${flagname}_FLAG)
239      target_link_libraries(${target} ${visibility} ${flag})
240    endif()
241  endforeach()
242endfunction()
243
244# For each specified flag, add that compile flag to the provided target.
245# The flags are added with the given visibility, i.e. PUBLIC|PRIVATE|INTERFACE.
246function(target_add_compile_flags_if_supported target visibility)
247  foreach(flag ${ARGN})
248    mangle_name("${flag}" flagname)
249    check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
250    if (CXX_SUPPORTS_${flagname}_FLAG)
251      target_compile_options(${target} ${visibility} ${flag})
252    endif()
253  endforeach()
254endfunction()
255