]> git.proxmox.com Git - rustc.git/blame - src/compiler-rt/cmake/Modules/AddCompilerRT.cmake
New upstream version 1.19.0+dfsg3
[rustc.git] / src / compiler-rt / cmake / Modules / AddCompilerRT.cmake
CommitLineData
92a42be0 1include(ExternalProject)
1a4d82fc
JJ
2include(CompilerRTUtils)
3
5bcae85e
SL
4function(set_target_output_directories target output_dir)
5 # For RUNTIME_OUTPUT_DIRECTORY variable, Multi-configuration generators
6 # append a per-configuration subdirectory to the specified directory.
7 # To avoid the appended folder, the configuration specific variable must be
8 # set 'RUNTIME_OUTPUT_DIRECTORY_${CONF}':
9 # RUNTIME_OUTPUT_DIRECTORY_DEBUG, RUNTIME_OUTPUT_DIRECTORY_RELEASE, ...
10 if(CMAKE_CONFIGURATION_TYPES)
11 foreach(build_mode ${CMAKE_CONFIGURATION_TYPES})
12 string(TOUPPER "${build_mode}" CONFIG_SUFFIX)
13 set_target_properties("${target}" PROPERTIES
14 "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}
15 "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}
16 "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir})
17 endforeach()
18 else()
19 set_target_properties("${target}" PROPERTIES
20 ARCHIVE_OUTPUT_DIRECTORY ${output_dir}
21 LIBRARY_OUTPUT_DIRECTORY ${output_dir}
22 RUNTIME_OUTPUT_DIRECTORY ${output_dir})
23 endif()
24endfunction()
25
92a42be0
SL
26# Tries to add an "object library" target for a given list of OSs and/or
27# architectures with name "<name>.<arch>" for non-Darwin platforms if
28# architecture can be targeted, and "<name>.<os>" for Darwin platforms.
29# add_compiler_rt_object_libraries(<name>
30# OS <os names>
31# ARCHS <architectures>
32# SOURCES <source files>
33# CFLAGS <compile flags>
34# DEFS <compile definitions>)
35function(add_compiler_rt_object_libraries name)
36 cmake_parse_arguments(LIB "" "" "OS;ARCHS;SOURCES;CFLAGS;DEFS" ${ARGN})
37 set(libnames)
38 if(APPLE)
39 foreach(os ${LIB_OS})
40 set(libname "${name}.${os}")
41 set(libnames ${libnames} ${libname})
42 set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS})
3157f602 43 list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
92a42be0 44 endforeach()
1a4d82fc 45 else()
92a42be0
SL
46 foreach(arch ${LIB_ARCHS})
47 set(libname "${name}.${arch}")
48 set(libnames ${libnames} ${libname})
49 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS})
50 if(NOT CAN_TARGET_${arch})
51 message(FATAL_ERROR "Architecture ${arch} can't be targeted")
52 return()
53 endif()
54 endforeach()
1a4d82fc 55 endif()
5bcae85e 56
92a42be0
SL
57 foreach(libname ${libnames})
58 add_library(${libname} OBJECT ${LIB_SOURCES})
59 set_target_compile_flags(${libname}
60 ${CMAKE_CXX_FLAGS} ${extra_cflags_${libname}} ${LIB_CFLAGS})
61 set_property(TARGET ${libname} APPEND PROPERTY
62 COMPILE_DEFINITIONS ${LIB_DEFS})
5bcae85e 63 set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries")
92a42be0
SL
64 if(APPLE)
65 set_target_properties(${libname} PROPERTIES
66 OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
67 endif()
68 endforeach()
69endfunction()
1a4d82fc 70
92a42be0
SL
71# Takes a list of object library targets, and a suffix and appends the proper
72# TARGET_OBJECTS string to the output variable.
73# format_object_libs(<output> <suffix> ...)
74macro(format_object_libs output suffix)
75 foreach(lib ${ARGN})
76 list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>)
77 endforeach()
1a4d82fc
JJ
78endmacro()
79
7cac9316
XL
80function(add_compiler_rt_component name)
81 add_custom_target(${name})
82 set_target_properties(${name} PROPERTIES FOLDER "Compiler-RT Misc")
83 if(COMMAND runtime_register_component)
84 runtime_register_component(${name})
85 endif()
86 add_dependencies(compiler-rt ${name})
87endfunction()
88
92a42be0
SL
89# Adds static or shared runtime for a list of architectures and operating
90# systems and puts it in the proper directory in the build and install trees.
91# add_compiler_rt_runtime(<name>
92# {STATIC|SHARED}
93# ARCHS <architectures>
94# OS <os list>
1a4d82fc
JJ
95# SOURCES <source files>
96# CFLAGS <compile flags>
7cac9316 97# LINK_FLAGS <linker flags>
92a42be0
SL
98# DEFS <compile definitions>
99# LINK_LIBS <linked libraries> (only for shared library)
100# OBJECT_LIBS <object libraries to use as sources>
101# PARENT_TARGET <convenience parent target>)
102function(add_compiler_rt_runtime name type)
103 if(NOT type MATCHES "^(STATIC|SHARED)$")
104 message(FATAL_ERROR "type argument must be STATIC or SHARED")
105 return()
106 endif()
107 cmake_parse_arguments(LIB
108 ""
109 "PARENT_TARGET"
7cac9316 110 "OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;LINK_LIBS;OBJECT_LIBS"
92a42be0
SL
111 ${ARGN})
112 set(libnames)
113 if(APPLE)
114 foreach(os ${LIB_OS})
115 if(type STREQUAL "STATIC")
116 set(libname "${name}_${os}")
117 else()
118 set(libname "${name}_${os}_dynamic")
7cac9316 119 set(extra_link_flags_${libname} ${DARWIN_${os}_LINK_FLAGS} ${LIB_LINK_FLAGS})
92a42be0 120 endif()
3157f602 121 list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
92a42be0
SL
122 if(LIB_ARCHS_${libname})
123 list(APPEND libnames ${libname})
124 set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${LIB_CFLAGS})
125 set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})
126 set(sources_${libname} ${LIB_SOURCES})
127 format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS})
128 endif()
129 endforeach()
1a4d82fc 130 else()
92a42be0
SL
131 foreach(arch ${LIB_ARCHS})
132 if(NOT CAN_TARGET_${arch})
133 message(FATAL_ERROR "Architecture ${arch} can't be targeted")
134 return()
135 endif()
136 if(type STREQUAL "STATIC")
137 set(libname "${name}-${arch}")
138 set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})
139 else()
140 set(libname "${name}-dynamic-${arch}")
5bcae85e 141 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
7cac9316 142 set(extra_link_flags_${libname} ${TARGET_${arch}_LINK_FLAGS} ${LIB_LINK_FLAGS})
92a42be0
SL
143 if(WIN32)
144 set(output_name_${libname} ${name}_dynamic-${arch}${COMPILER_RT_OS_SUFFIX})
145 else()
146 set(output_name_${libname} ${name}-${arch}${COMPILER_RT_OS_SUFFIX})
147 endif()
148 endif()
149 set(sources_${libname} ${LIB_SOURCES})
150 format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS})
151 set(libnames ${libnames} ${libname})
152 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
153 endforeach()
1a4d82fc 154 endif()
1a4d82fc 155
92a42be0
SL
156 if(NOT libnames)
157 return()
158 endif()
1a4d82fc 159
92a42be0 160 if(LIB_PARENT_TARGET)
5bcae85e
SL
161 # If the parent targets aren't created we should create them
162 if(NOT TARGET ${LIB_PARENT_TARGET})
163 add_custom_target(${LIB_PARENT_TARGET})
164 endif()
165 if(NOT TARGET install-${LIB_PARENT_TARGET})
166 # The parent install target specifies the parent component to scrape up
167 # anything not installed by the individual install targets, and to handle
168 # installation when running the multi-configuration generators.
169 add_custom_target(install-${LIB_PARENT_TARGET}
170 DEPENDS ${LIB_PARENT_TARGET}
171 COMMAND "${CMAKE_COMMAND}"
172 -DCMAKE_INSTALL_COMPONENT=${LIB_PARENT_TARGET}
173 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
174 set_target_properties(install-${LIB_PARENT_TARGET} PROPERTIES
175 FOLDER "Compiler-RT Misc")
7cac9316 176 add_dependencies(install-compiler-rt install-${LIB_PARENT_TARGET})
5bcae85e 177 endif()
92a42be0
SL
178 endif()
179
180 foreach(libname ${libnames})
5bcae85e
SL
181 # If you are using a multi-configuration generator we don't generate
182 # per-library install rules, so we fall back to the parent target COMPONENT
183 if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET)
184 set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET})
185 else()
186 set(COMPONENT_OPTION COMPONENT ${libname})
187 endif()
188
92a42be0
SL
189 add_library(${libname} ${type} ${sources_${libname}})
190 set_target_compile_flags(${libname} ${extra_cflags_${libname}})
7cac9316 191 set_target_link_flags(${libname} ${extra_link_flags_${libname}})
5bcae85e 192 set_property(TARGET ${libname} APPEND PROPERTY
92a42be0 193 COMPILE_DEFINITIONS ${LIB_DEFS})
5bcae85e 194 set_target_output_directories(${libname} ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
92a42be0
SL
195 set_target_properties(${libname} PROPERTIES
196 OUTPUT_NAME ${output_name_${libname}})
5bcae85e 197 set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime")
7cac9316
XL
198 if(${type} STREQUAL "SHARED")
199 if(LIB_LINK_LIBS)
200 target_link_libraries(${libname} ${LIB_LINK_LIBS})
201 endif()
202 if(WIN32 AND NOT CYGWIN AND NOT MINGW)
203 set_target_properties(${libname} PROPERTIES IMPORT_PREFIX "")
204 set_target_properties(${libname} PROPERTIES IMPORT_SUFFIX ".lib")
205 endif()
92a42be0
SL
206 endif()
207 install(TARGETS ${libname}
208 ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
209 ${COMPONENT_OPTION}
210 LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
211 ${COMPONENT_OPTION}
212 RUNTIME DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
213 ${COMPONENT_OPTION})
5bcae85e
SL
214
215 # We only want to generate per-library install targets if you aren't using
216 # an IDE because the extra targets get cluttered in IDEs.
217 if(NOT CMAKE_CONFIGURATION_TYPES)
218 add_custom_target(install-${libname}
219 DEPENDS ${libname}
220 COMMAND "${CMAKE_COMMAND}"
221 -DCMAKE_INSTALL_COMPONENT=${libname}
222 -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
223 # If you have a parent target specified, we bind the new install target
224 # to the parent install target.
225 if(LIB_PARENT_TARGET)
226 add_dependencies(install-${LIB_PARENT_TARGET} install-${libname})
227 endif()
228 endif()
92a42be0
SL
229 if(APPLE)
230 set_target_properties(${libname} PROPERTIES
231 OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
232 endif()
3157f602
XL
233
234 if(type STREQUAL "SHARED")
235 rt_externalize_debuginfo(${libname})
236 endif()
92a42be0
SL
237 endforeach()
238 if(LIB_PARENT_TARGET)
239 add_dependencies(${LIB_PARENT_TARGET} ${libnames})
240 endif()
241endfunction()
242
5bcae85e
SL
243# when cross compiling, COMPILER_RT_TEST_COMPILER_CFLAGS help
244# in compilation and linking of unittests.
245string(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}")
7cac9316 246set(COMPILER_RT_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_CFLAGS})
1a4d82fc
JJ
247
248# Unittests support.
249set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest)
250set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc)
251set(COMPILER_RT_GTEST_CFLAGS
252 -DGTEST_NO_LLVM_RAW_OSTREAM=1
92a42be0 253 -DGTEST_HAS_RTTI=0
1a4d82fc
JJ
254 -I${COMPILER_RT_GTEST_PATH}/include
255 -I${COMPILER_RT_GTEST_PATH}
256)
257
5bcae85e 258append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS)
7cac9316 259append_list_if(COMPILER_RT_HAS_WCOVERED_SWITCH_DEFAULT_FLAG -Wno-covered-switch-default COMPILER_RT_UNITTEST_CFLAGS)
92a42be0
SL
260
261if(MSVC)
262 # clang doesn't support exceptions on Windows yet.
5bcae85e 263 list(APPEND COMPILER_RT_UNITTEST_CFLAGS -D_HAS_EXCEPTIONS=0)
92a42be0
SL
264
265 # We should teach clang to understand "#pragma intrinsic", see PR19898.
5bcae85e 266 list(APPEND COMPILER_RT_UNITTEST_CFLAGS -Wno-undefined-inline)
92a42be0
SL
267
268 # Clang doesn't support SEH on Windows yet.
269 list(APPEND COMPILER_RT_GTEST_CFLAGS -DGTEST_HAS_SEH=0)
270
271 # gtest use a lot of stuff marked as deprecated on Windows.
272 list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations)
92a42be0
SL
273endif()
274
1a4d82fc
JJ
275# Link objects into a single executable with COMPILER_RT_TEST_COMPILER,
276# using specified link flags. Make executable a part of provided
277# test_suite.
278# add_compiler_rt_test(<test_suite> <test_name>
92a42be0 279# SUBDIR <subdirectory for binary>
1a4d82fc
JJ
280# OBJECTS <object files>
281# DEPS <deps (e.g. runtime libs)>
282# LINK_FLAGS <link flags>)
283macro(add_compiler_rt_test test_suite test_name)
92a42be0 284 cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN})
5bcae85e 285 set(output_bin ${CMAKE_CURRENT_BINARY_DIR})
92a42be0 286 if(TEST_SUBDIR)
5bcae85e
SL
287 set(output_bin "${output_bin}/${TEST_SUBDIR}")
288 endif()
289 if(CMAKE_CONFIGURATION_TYPES)
290 set(output_bin "${output_bin}/${CMAKE_CFG_INTDIR}")
92a42be0 291 endif()
5bcae85e 292 set(output_bin "${output_bin}/${test_name}")
92a42be0
SL
293 if(MSVC)
294 set(output_bin "${output_bin}.exe")
295 endif()
5bcae85e 296
1a4d82fc
JJ
297 # Use host compiler in a standalone build, and just-built Clang otherwise.
298 if(NOT COMPILER_RT_STANDALONE_BUILD)
299 list(APPEND TEST_DEPS clang)
300 endif()
92a42be0
SL
301 # If we're not on MSVC, include the linker flags from CMAKE but override them
302 # with the provided link flags. This ensures that flags which are required to
303 # link programs at all are included, but the changes needed for the test
304 # trump. With MSVC we can't do that because CMake is set up to run link.exe
305 # when linking, not the compiler. Here, we hack it to use the compiler
306 # because we want to use -fsanitize flags.
307 if(NOT MSVC)
308 set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}")
309 separate_arguments(TEST_LINK_FLAGS)
310 endif()
1a4d82fc 311 add_custom_target(${test_name}
92a42be0
SL
312 COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS}
313 -o "${output_bin}"
1a4d82fc
JJ
314 ${TEST_LINK_FLAGS}
315 DEPENDS ${TEST_DEPS})
5bcae85e
SL
316 set_target_properties(${test_name} PROPERTIES FOLDER "Compiler-RT Tests")
317
1a4d82fc
JJ
318 # Make the test suite depend on the binary.
319 add_dependencies(${test_suite} ${test_name})
320endmacro()
321
5bcae85e 322macro(add_compiler_rt_resource_file target_name file_name component)
1a4d82fc
JJ
323 set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}")
324 set(dst_file "${COMPILER_RT_OUTPUT_DIR}/${file_name}")
325 add_custom_command(OUTPUT ${dst_file}
326 DEPENDS ${src_file}
327 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file}
328 COMMENT "Copying ${file_name}...")
329 add_custom_target(${target_name} DEPENDS ${dst_file})
330 # Install in Clang resource directory.
5bcae85e
SL
331 install(FILES ${file_name}
332 DESTINATION ${COMPILER_RT_INSTALL_PATH}
333 COMPONENT ${component})
334 add_dependencies(${component} ${target_name})
335
336 set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc")
1a4d82fc
JJ
337endmacro()
338
339macro(add_compiler_rt_script name)
340 set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name})
341 set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name})
342 add_custom_command(OUTPUT ${dst}
343 DEPENDS ${src}
344 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
345 COMMENT "Copying ${name}...")
346 add_custom_target(${name} DEPENDS ${dst})
347 install(FILES ${dst}
348 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
349 DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin)
350endmacro(add_compiler_rt_script src name)
92a42be0
SL
351
352# Builds custom version of libc++ and installs it in <prefix>.
353# Can be used to build sanitized versions of libc++ for running unit tests.
354# add_custom_libcxx(<name> <prefix>
355# DEPS <list of build deps>
356# CFLAGS <list of compile flags>)
357macro(add_custom_libcxx name prefix)
358 if(NOT COMPILER_RT_HAS_LIBCXX_SOURCES)
359 message(FATAL_ERROR "libcxx not found!")
360 endif()
361
362 cmake_parse_arguments(LIBCXX "" "" "DEPS;CFLAGS" ${ARGN})
363 foreach(flag ${LIBCXX_CFLAGS})
364 set(flagstr "${flagstr} ${flag}")
365 endforeach()
366 set(LIBCXX_CFLAGS ${flagstr})
367
368 if(NOT COMPILER_RT_STANDALONE_BUILD)
369 list(APPEND LIBCXX_DEPS clang)
370 endif()
371
372 ExternalProject_Add(${name}
373 PREFIX ${prefix}
374 SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH}
3157f602
XL
375 CMAKE_ARGS -DCMAKE_MAKE_PROGRAM:STRING=${CMAKE_MAKE_PROGRAM}
376 -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}
377 -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER}
92a42be0
SL
378 -DCMAKE_C_FLAGS=${LIBCXX_CFLAGS}
379 -DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS}
380 -DCMAKE_BUILD_TYPE=Release
381 -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
3157f602 382 -DLLVM_PATH=${LLVM_MAIN_SRC_DIR}
92a42be0
SL
383 LOG_BUILD 1
384 LOG_CONFIGURE 1
385 LOG_INSTALL 1
386 )
387 set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
388
389 ExternalProject_Add_Step(${name} force-reconfigure
390 DEPENDERS configure
391 ALWAYS 1
392 )
393
394 ExternalProject_Add_Step(${name} clobber
395 COMMAND ${CMAKE_COMMAND} -E remove_directory <BINARY_DIR>
396 COMMAND ${CMAKE_COMMAND} -E make_directory <BINARY_DIR>
397 COMMENT "Clobberring ${name} build directory..."
398 DEPENDERS configure
399 DEPENDS ${LIBCXX_DEPS}
400 )
401endmacro()
3157f602
XL
402
403function(rt_externalize_debuginfo name)
404 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO)
405 return()
406 endif()
407
5bcae85e
SL
408 if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP)
409 set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>)
410 endif()
411
3157f602
XL
412 if(APPLE)
413 if(CMAKE_CXX_FLAGS MATCHES "-flto"
414 OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto")
415
416 set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o)
417 set_property(TARGET ${name} APPEND_STRING PROPERTY
418 LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}")
419 endif()
420 add_custom_command(TARGET ${name} POST_BUILD
421 COMMAND xcrun dsymutil $<TARGET_FILE:${name}>
5bcae85e 422 ${strip_command})
3157f602
XL
423 else()
424 message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!")
425 endif()
426endfunction()