]> git.proxmox.com Git - rustc.git/blob - src/compiler-rt/cmake/Modules/AddCompilerRT.cmake
Imported Upstream version 1.6.0+dfsg1
[rustc.git] / src / compiler-rt / cmake / Modules / AddCompilerRT.cmake
1 include(AddLLVM)
2 include(ExternalProject)
3 include(CompilerRTUtils)
4
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>)
14 function(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()
24 else()
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()
34 endif()
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()
47 endfunction()
48
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> ...)
52 macro(format_object_libs output suffix)
53 foreach(lib ${ARGN})
54 list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>)
55 endforeach()
56 endmacro()
57
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>
64 # SOURCES <source files>
65 # CFLAGS <compile flags>
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>)
71 function(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()
99 else()
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()
122 endif()
123
124 if(NOT libnames)
125 return()
126 endif()
127
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()
162 endfunction()
163
164 set(COMPILER_RT_TEST_CFLAGS)
165
166 # Unittests support.
167 set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest)
168 set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc)
169 set(COMPILER_RT_GTEST_CFLAGS
170 -DGTEST_NO_LLVM_RAW_OSTREAM=1
171 -DGTEST_HAS_RTTI=0
172 -I${COMPILER_RT_GTEST_PATH}/include
173 -I${COMPILER_RT_GTEST_PATH}
174 )
175
176 append_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_TEST_CFLAGS)
177
178 if(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()
196 endif()
197
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>
202 # SUBDIR <subdirectory for binary>
203 # OBJECTS <object files>
204 # DEPS <deps (e.g. runtime libs)>
205 # LINK_FLAGS <link flags>)
206 macro(add_compiler_rt_test test_suite test_name)
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()
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()
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()
230 add_custom_target(${test_name}
231 COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS}
232 -o "${output_bin}"
233 ${TEST_LINK_FLAGS}
234 DEPENDS ${TEST_DEPS})
235 # Make the test suite depend on the binary.
236 add_dependencies(${test_suite} ${test_name})
237 endmacro()
238
239 macro(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})
249 endmacro()
250
251 macro(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)
262 endmacro(add_compiler_rt_script src name)
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>)
269 macro(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 )
311 endmacro()