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