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