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