]> git.proxmox.com Git - rustc.git/blame - src/compiler-rt/cmake/Modules/AddCompilerRT.cmake
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / compiler-rt / cmake / Modules / AddCompilerRT.cmake
CommitLineData
1a4d82fc 1include(AddLLVM)
92a42be0 2include(ExternalProject)
1a4d82fc
JJ
3include(CompilerRTUtils)
4
92a42be0
SL
5# Tries to add an "object library" target for a given list of OSs and/or
6# architectures with name "<name>.<arch>" for non-Darwin platforms if
7# architecture can be targeted, and "<name>.<os>" for Darwin platforms.
8# add_compiler_rt_object_libraries(<name>
9# OS <os names>
10# ARCHS <architectures>
11# SOURCES <source files>
12# CFLAGS <compile flags>
13# DEFS <compile definitions>)
14function(add_compiler_rt_object_libraries name)
15 cmake_parse_arguments(LIB "" "" "OS;ARCHS;SOURCES;CFLAGS;DEFS" ${ARGN})
16 set(libnames)
17 if(APPLE)
18 foreach(os ${LIB_OS})
19 set(libname "${name}.${os}")
20 set(libnames ${libnames} ${libname})
21 set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS})
22 list_union(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
23 endforeach()
1a4d82fc 24 else()
92a42be0
SL
25 foreach(arch ${LIB_ARCHS})
26 set(libname "${name}.${arch}")
27 set(libnames ${libnames} ${libname})
28 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS})
29 if(NOT CAN_TARGET_${arch})
30 message(FATAL_ERROR "Architecture ${arch} can't be targeted")
31 return()
32 endif()
33 endforeach()
1a4d82fc 34 endif()
92a42be0
SL
35
36 foreach(libname ${libnames})
37 add_library(${libname} OBJECT ${LIB_SOURCES})
38 set_target_compile_flags(${libname}
39 ${CMAKE_CXX_FLAGS} ${extra_cflags_${libname}} ${LIB_CFLAGS})
40 set_property(TARGET ${libname} APPEND PROPERTY
41 COMPILE_DEFINITIONS ${LIB_DEFS})
42 if(APPLE)
43 set_target_properties(${libname} PROPERTIES
44 OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
45 endif()
46 endforeach()
47endfunction()
1a4d82fc 48
92a42be0
SL
49# Takes a list of object library targets, and a suffix and appends the proper
50# TARGET_OBJECTS string to the output variable.
51# format_object_libs(<output> <suffix> ...)
52macro(format_object_libs output suffix)
53 foreach(lib ${ARGN})
54 list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>)
55 endforeach()
1a4d82fc
JJ
56endmacro()
57
92a42be0
SL
58# Adds static or shared runtime for a list of architectures and operating
59# systems and puts it in the proper directory in the build and install trees.
60# add_compiler_rt_runtime(<name>
61# {STATIC|SHARED}
62# ARCHS <architectures>
63# OS <os list>
1a4d82fc
JJ
64# SOURCES <source files>
65# CFLAGS <compile flags>
92a42be0
SL
66# LINKFLAGS <linker flags>
67# DEFS <compile definitions>
68# LINK_LIBS <linked libraries> (only for shared library)
69# OBJECT_LIBS <object libraries to use as sources>
70# PARENT_TARGET <convenience parent target>)
71function(add_compiler_rt_runtime name type)
72 if(NOT type MATCHES "^(STATIC|SHARED)$")
73 message(FATAL_ERROR "type argument must be STATIC or SHARED")
74 return()
75 endif()
76 cmake_parse_arguments(LIB
77 ""
78 "PARENT_TARGET"
79 "OS;ARCHS;SOURCES;CFLAGS;LINKFLAGS;DEFS;LINK_LIBS;OBJECT_LIBS"
80 ${ARGN})
81 set(libnames)
82 if(APPLE)
83 foreach(os ${LIB_OS})
84 if(type STREQUAL "STATIC")
85 set(libname "${name}_${os}")
86 else()
87 set(libname "${name}_${os}_dynamic")
88 set(extra_linkflags_${libname} ${DARWIN_${os}_LINKFLAGS} ${LIB_LINKFLAGS})
89 endif()
90 list_union(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
91 if(LIB_ARCHS_${libname})
92 list(APPEND libnames ${libname})
93 set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${LIB_CFLAGS})
94 set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})
95 set(sources_${libname} ${LIB_SOURCES})
96 format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS})
97 endif()
98 endforeach()
1a4d82fc 99 else()
92a42be0
SL
100 foreach(arch ${LIB_ARCHS})
101 if(NOT CAN_TARGET_${arch})
102 message(FATAL_ERROR "Architecture ${arch} can't be targeted")
103 return()
104 endif()
105 if(type STREQUAL "STATIC")
106 set(libname "${name}-${arch}")
107 set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX})
108 else()
109 set(libname "${name}-dynamic-${arch}")
110 set(extra_linkflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS} ${LIB_LINKFLAGS})
111 if(WIN32)
112 set(output_name_${libname} ${name}_dynamic-${arch}${COMPILER_RT_OS_SUFFIX})
113 else()
114 set(output_name_${libname} ${name}-${arch}${COMPILER_RT_OS_SUFFIX})
115 endif()
116 endif()
117 set(sources_${libname} ${LIB_SOURCES})
118 format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS})
119 set(libnames ${libnames} ${libname})
120 set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
121 endforeach()
1a4d82fc 122 endif()
1a4d82fc 123
92a42be0
SL
124 if(NOT libnames)
125 return()
126 endif()
1a4d82fc 127
92a42be0
SL
128 if(LIB_PARENT_TARGET)
129 set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET})
130 endif()
131
132 foreach(libname ${libnames})
133 add_library(${libname} ${type} ${sources_${libname}})
134 set_target_compile_flags(${libname} ${extra_cflags_${libname}})
135 set_target_link_flags(${libname} ${extra_linkflags_${libname}})
136 set_property(TARGET ${libname} APPEND PROPERTY
137 COMPILE_DEFINITIONS ${LIB_DEFS})
138 set_target_properties(${libname} PROPERTIES
139 ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}
140 LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}
141 RUNTIME_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
142 set_target_properties(${libname} PROPERTIES
143 OUTPUT_NAME ${output_name_${libname}})
144 if(LIB_LINK_LIBS AND ${type} STREQUAL "SHARED")
145 target_link_libraries(${libname} ${LIB_LINK_LIBS})
146 endif()
147 install(TARGETS ${libname}
148 ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
149 ${COMPONENT_OPTION}
150 LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
151 ${COMPONENT_OPTION}
152 RUNTIME DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}
153 ${COMPONENT_OPTION})
154 if(APPLE)
155 set_target_properties(${libname} PROPERTIES
156 OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}")
157 endif()
158 endforeach()
159 if(LIB_PARENT_TARGET)
160 add_dependencies(${LIB_PARENT_TARGET} ${libnames})
161 endif()
162endfunction()
163
164set(COMPILER_RT_TEST_CFLAGS)
1a4d82fc
JJ
165
166# Unittests support.
167set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest)
168set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc)
169set(COMPILER_RT_GTEST_CFLAGS
170 -DGTEST_NO_LLVM_RAW_OSTREAM=1
92a42be0 171 -DGTEST_HAS_RTTI=0
1a4d82fc
JJ
172 -I${COMPILER_RT_GTEST_PATH}/include
173 -I${COMPILER_RT_GTEST_PATH}
174)
175
92a42be0
SL
176append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_TEST_CFLAGS)
177
178if(MSVC)
179 # clang doesn't support exceptions on Windows yet.
180 list(APPEND COMPILER_RT_TEST_CFLAGS -D_HAS_EXCEPTIONS=0)
181
182 # We should teach clang to understand "#pragma intrinsic", see PR19898.
183 list(APPEND COMPILER_RT_TEST_CFLAGS -Wno-undefined-inline)
184
185 # Clang doesn't support SEH on Windows yet.
186 list(APPEND COMPILER_RT_GTEST_CFLAGS -DGTEST_HAS_SEH=0)
187
188 # gtest use a lot of stuff marked as deprecated on Windows.
189 list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations)
190
191 # Visual Studio 2012 only supports up to 8 template parameters in
192 # std::tr1::tuple by default, but gtest requires 10
193 if(MSVC_VERSION EQUAL 1700)
194 list(APPEND COMPILER_RT_GTEST_CFLAGS -D_VARIADIC_MAX=10)
195 endif()
196endif()
197
1a4d82fc
JJ
198# Link objects into a single executable with COMPILER_RT_TEST_COMPILER,
199# using specified link flags. Make executable a part of provided
200# test_suite.
201# add_compiler_rt_test(<test_suite> <test_name>
92a42be0 202# SUBDIR <subdirectory for binary>
1a4d82fc
JJ
203# OBJECTS <object files>
204# DEPS <deps (e.g. runtime libs)>
205# LINK_FLAGS <link flags>)
206macro(add_compiler_rt_test test_suite test_name)
92a42be0
SL
207 cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN})
208 if(TEST_SUBDIR)
209 set(output_bin "${CMAKE_CURRENT_BINARY_DIR}/${TEST_SUBDIR}/${test_name}")
210 else()
211 set(output_bin "${CMAKE_CURRENT_BINARY_DIR}/${test_name}")
212 endif()
213 if(MSVC)
214 set(output_bin "${output_bin}.exe")
215 endif()
1a4d82fc
JJ
216 # Use host compiler in a standalone build, and just-built Clang otherwise.
217 if(NOT COMPILER_RT_STANDALONE_BUILD)
218 list(APPEND TEST_DEPS clang)
219 endif()
92a42be0
SL
220 # If we're not on MSVC, include the linker flags from CMAKE but override them
221 # with the provided link flags. This ensures that flags which are required to
222 # link programs at all are included, but the changes needed for the test
223 # trump. With MSVC we can't do that because CMake is set up to run link.exe
224 # when linking, not the compiler. Here, we hack it to use the compiler
225 # because we want to use -fsanitize flags.
226 if(NOT MSVC)
227 set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}")
228 separate_arguments(TEST_LINK_FLAGS)
229 endif()
1a4d82fc 230 add_custom_target(${test_name}
92a42be0
SL
231 COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS}
232 -o "${output_bin}"
1a4d82fc
JJ
233 ${TEST_LINK_FLAGS}
234 DEPENDS ${TEST_DEPS})
235 # Make the test suite depend on the binary.
236 add_dependencies(${test_suite} ${test_name})
237endmacro()
238
239macro(add_compiler_rt_resource_file target_name file_name)
240 set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}")
241 set(dst_file "${COMPILER_RT_OUTPUT_DIR}/${file_name}")
242 add_custom_command(OUTPUT ${dst_file}
243 DEPENDS ${src_file}
244 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file}
245 COMMENT "Copying ${file_name}...")
246 add_custom_target(${target_name} DEPENDS ${dst_file})
247 # Install in Clang resource directory.
248 install(FILES ${file_name} DESTINATION ${COMPILER_RT_INSTALL_PATH})
249endmacro()
250
251macro(add_compiler_rt_script name)
252 set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name})
253 set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name})
254 add_custom_command(OUTPUT ${dst}
255 DEPENDS ${src}
256 COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst}
257 COMMENT "Copying ${name}...")
258 add_custom_target(${name} DEPENDS ${dst})
259 install(FILES ${dst}
260 PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE
261 DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin)
262endmacro(add_compiler_rt_script src name)
92a42be0
SL
263
264# Builds custom version of libc++ and installs it in <prefix>.
265# Can be used to build sanitized versions of libc++ for running unit tests.
266# add_custom_libcxx(<name> <prefix>
267# DEPS <list of build deps>
268# CFLAGS <list of compile flags>)
269macro(add_custom_libcxx name prefix)
270 if(NOT COMPILER_RT_HAS_LIBCXX_SOURCES)
271 message(FATAL_ERROR "libcxx not found!")
272 endif()
273
274 cmake_parse_arguments(LIBCXX "" "" "DEPS;CFLAGS" ${ARGN})
275 foreach(flag ${LIBCXX_CFLAGS})
276 set(flagstr "${flagstr} ${flag}")
277 endforeach()
278 set(LIBCXX_CFLAGS ${flagstr})
279
280 if(NOT COMPILER_RT_STANDALONE_BUILD)
281 list(APPEND LIBCXX_DEPS clang)
282 endif()
283
284 ExternalProject_Add(${name}
285 PREFIX ${prefix}
286 SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH}
287 CMAKE_ARGS -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER}
288 -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_COMPILER}
289 -DCMAKE_C_FLAGS=${LIBCXX_CFLAGS}
290 -DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS}
291 -DCMAKE_BUILD_TYPE=Release
292 -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR>
293 LOG_BUILD 1
294 LOG_CONFIGURE 1
295 LOG_INSTALL 1
296 )
297 set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL TRUE)
298
299 ExternalProject_Add_Step(${name} force-reconfigure
300 DEPENDERS configure
301 ALWAYS 1
302 )
303
304 ExternalProject_Add_Step(${name} clobber
305 COMMAND ${CMAKE_COMMAND} -E remove_directory <BINARY_DIR>
306 COMMAND ${CMAKE_COMMAND} -E make_directory <BINARY_DIR>
307 COMMENT "Clobberring ${name} build directory..."
308 DEPENDERS configure
309 DEPENDS ${LIBCXX_DEPS}
310 )
311endmacro()