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