1*7c3d14c8STreehugger Robotinclude(ExternalProject) 2*7c3d14c8STreehugger Robotinclude(CompilerRTUtils) 3*7c3d14c8STreehugger Robot 4*7c3d14c8STreehugger Robotfunction(set_target_output_directories target output_dir) 5*7c3d14c8STreehugger Robot # For RUNTIME_OUTPUT_DIRECTORY variable, Multi-configuration generators 6*7c3d14c8STreehugger Robot # append a per-configuration subdirectory to the specified directory. 7*7c3d14c8STreehugger Robot # To avoid the appended folder, the configuration specific variable must be 8*7c3d14c8STreehugger Robot # set 'RUNTIME_OUTPUT_DIRECTORY_${CONF}': 9*7c3d14c8STreehugger Robot # RUNTIME_OUTPUT_DIRECTORY_DEBUG, RUNTIME_OUTPUT_DIRECTORY_RELEASE, ... 10*7c3d14c8STreehugger Robot if(CMAKE_CONFIGURATION_TYPES) 11*7c3d14c8STreehugger Robot foreach(build_mode ${CMAKE_CONFIGURATION_TYPES}) 12*7c3d14c8STreehugger Robot string(TOUPPER "${build_mode}" CONFIG_SUFFIX) 13*7c3d14c8STreehugger Robot set_target_properties("${target}" PROPERTIES 14*7c3d14c8STreehugger Robot "ARCHIVE_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir} 15*7c3d14c8STreehugger Robot "LIBRARY_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir} 16*7c3d14c8STreehugger Robot "RUNTIME_OUTPUT_DIRECTORY_${CONFIG_SUFFIX}" ${output_dir}) 17*7c3d14c8STreehugger Robot endforeach() 18*7c3d14c8STreehugger Robot else() 19*7c3d14c8STreehugger Robot set_target_properties("${target}" PROPERTIES 20*7c3d14c8STreehugger Robot ARCHIVE_OUTPUT_DIRECTORY ${output_dir} 21*7c3d14c8STreehugger Robot LIBRARY_OUTPUT_DIRECTORY ${output_dir} 22*7c3d14c8STreehugger Robot RUNTIME_OUTPUT_DIRECTORY ${output_dir}) 23*7c3d14c8STreehugger Robot endif() 24*7c3d14c8STreehugger Robotendfunction() 25*7c3d14c8STreehugger Robot 26*7c3d14c8STreehugger Robot# Tries to add an "object library" target for a given list of OSs and/or 27*7c3d14c8STreehugger Robot# architectures with name "<name>.<arch>" for non-Darwin platforms if 28*7c3d14c8STreehugger Robot# architecture can be targeted, and "<name>.<os>" for Darwin platforms. 29*7c3d14c8STreehugger Robot# add_compiler_rt_object_libraries(<name> 30*7c3d14c8STreehugger Robot# OS <os names> 31*7c3d14c8STreehugger Robot# ARCHS <architectures> 32*7c3d14c8STreehugger Robot# SOURCES <source files> 33*7c3d14c8STreehugger Robot# CFLAGS <compile flags> 34*7c3d14c8STreehugger Robot# DEFS <compile definitions>) 35*7c3d14c8STreehugger Robotfunction(add_compiler_rt_object_libraries name) 36*7c3d14c8STreehugger Robot cmake_parse_arguments(LIB "" "" "OS;ARCHS;SOURCES;CFLAGS;DEFS" ${ARGN}) 37*7c3d14c8STreehugger Robot set(libnames) 38*7c3d14c8STreehugger Robot if(APPLE) 39*7c3d14c8STreehugger Robot foreach(os ${LIB_OS}) 40*7c3d14c8STreehugger Robot set(libname "${name}.${os}") 41*7c3d14c8STreehugger Robot set(libnames ${libnames} ${libname}) 42*7c3d14c8STreehugger Robot set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS}) 43*7c3d14c8STreehugger Robot list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS) 44*7c3d14c8STreehugger Robot endforeach() 45*7c3d14c8STreehugger Robot else() 46*7c3d14c8STreehugger Robot foreach(arch ${LIB_ARCHS}) 47*7c3d14c8STreehugger Robot set(libname "${name}.${arch}") 48*7c3d14c8STreehugger Robot set(libnames ${libnames} ${libname}) 49*7c3d14c8STreehugger Robot set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS}) 50*7c3d14c8STreehugger Robot if(NOT CAN_TARGET_${arch}) 51*7c3d14c8STreehugger Robot message(FATAL_ERROR "Architecture ${arch} can't be targeted") 52*7c3d14c8STreehugger Robot return() 53*7c3d14c8STreehugger Robot endif() 54*7c3d14c8STreehugger Robot endforeach() 55*7c3d14c8STreehugger Robot endif() 56*7c3d14c8STreehugger Robot 57*7c3d14c8STreehugger Robot foreach(libname ${libnames}) 58*7c3d14c8STreehugger Robot add_library(${libname} OBJECT ${LIB_SOURCES}) 59*7c3d14c8STreehugger Robot set_target_compile_flags(${libname} 60*7c3d14c8STreehugger Robot ${CMAKE_CXX_FLAGS} ${extra_cflags_${libname}} ${LIB_CFLAGS}) 61*7c3d14c8STreehugger Robot set_property(TARGET ${libname} APPEND PROPERTY 62*7c3d14c8STreehugger Robot COMPILE_DEFINITIONS ${LIB_DEFS}) 63*7c3d14c8STreehugger Robot set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Libraries") 64*7c3d14c8STreehugger Robot if(APPLE) 65*7c3d14c8STreehugger Robot set_target_properties(${libname} PROPERTIES 66*7c3d14c8STreehugger Robot OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}") 67*7c3d14c8STreehugger Robot endif() 68*7c3d14c8STreehugger Robot endforeach() 69*7c3d14c8STreehugger Robotendfunction() 70*7c3d14c8STreehugger Robot 71*7c3d14c8STreehugger Robot# Takes a list of object library targets, and a suffix and appends the proper 72*7c3d14c8STreehugger Robot# TARGET_OBJECTS string to the output variable. 73*7c3d14c8STreehugger Robot# format_object_libs(<output> <suffix> ...) 74*7c3d14c8STreehugger Robotmacro(format_object_libs output suffix) 75*7c3d14c8STreehugger Robot foreach(lib ${ARGN}) 76*7c3d14c8STreehugger Robot list(APPEND ${output} $<TARGET_OBJECTS:${lib}.${suffix}>) 77*7c3d14c8STreehugger Robot endforeach() 78*7c3d14c8STreehugger Robotendmacro() 79*7c3d14c8STreehugger Robot 80*7c3d14c8STreehugger Robot# Adds static or shared runtime for a list of architectures and operating 81*7c3d14c8STreehugger Robot# systems and puts it in the proper directory in the build and install trees. 82*7c3d14c8STreehugger Robot# add_compiler_rt_runtime(<name> 83*7c3d14c8STreehugger Robot# {STATIC|SHARED} 84*7c3d14c8STreehugger Robot# ARCHS <architectures> 85*7c3d14c8STreehugger Robot# OS <os list> 86*7c3d14c8STreehugger Robot# SOURCES <source files> 87*7c3d14c8STreehugger Robot# CFLAGS <compile flags> 88*7c3d14c8STreehugger Robot# LINKFLAGS <linker flags> 89*7c3d14c8STreehugger Robot# DEFS <compile definitions> 90*7c3d14c8STreehugger Robot# LINK_LIBS <linked libraries> (only for shared library) 91*7c3d14c8STreehugger Robot# OBJECT_LIBS <object libraries to use as sources> 92*7c3d14c8STreehugger Robot# PARENT_TARGET <convenience parent target>) 93*7c3d14c8STreehugger Robotfunction(add_compiler_rt_runtime name type) 94*7c3d14c8STreehugger Robot if(NOT type MATCHES "^(STATIC|SHARED)$") 95*7c3d14c8STreehugger Robot message(FATAL_ERROR "type argument must be STATIC or SHARED") 96*7c3d14c8STreehugger Robot return() 97*7c3d14c8STreehugger Robot endif() 98*7c3d14c8STreehugger Robot cmake_parse_arguments(LIB 99*7c3d14c8STreehugger Robot "" 100*7c3d14c8STreehugger Robot "PARENT_TARGET" 101*7c3d14c8STreehugger Robot "OS;ARCHS;SOURCES;CFLAGS;LINKFLAGS;DEFS;LINK_LIBS;OBJECT_LIBS" 102*7c3d14c8STreehugger Robot ${ARGN}) 103*7c3d14c8STreehugger Robot set(libnames) 104*7c3d14c8STreehugger Robot if(APPLE) 105*7c3d14c8STreehugger Robot foreach(os ${LIB_OS}) 106*7c3d14c8STreehugger Robot if(type STREQUAL "STATIC") 107*7c3d14c8STreehugger Robot set(libname "${name}_${os}") 108*7c3d14c8STreehugger Robot else() 109*7c3d14c8STreehugger Robot set(libname "${name}_${os}_dynamic") 110*7c3d14c8STreehugger Robot set(extra_linkflags_${libname} ${DARWIN_${os}_LINKFLAGS} ${LIB_LINKFLAGS}) 111*7c3d14c8STreehugger Robot endif() 112*7c3d14c8STreehugger Robot list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS) 113*7c3d14c8STreehugger Robot if(LIB_ARCHS_${libname}) 114*7c3d14c8STreehugger Robot list(APPEND libnames ${libname}) 115*7c3d14c8STreehugger Robot set(extra_cflags_${libname} ${DARWIN_${os}_CFLAGS} ${LIB_CFLAGS}) 116*7c3d14c8STreehugger Robot set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX}) 117*7c3d14c8STreehugger Robot set(sources_${libname} ${LIB_SOURCES}) 118*7c3d14c8STreehugger Robot format_object_libs(sources_${libname} ${os} ${LIB_OBJECT_LIBS}) 119*7c3d14c8STreehugger Robot endif() 120*7c3d14c8STreehugger Robot endforeach() 121*7c3d14c8STreehugger Robot else() 122*7c3d14c8STreehugger Robot foreach(arch ${LIB_ARCHS}) 123*7c3d14c8STreehugger Robot if(NOT CAN_TARGET_${arch}) 124*7c3d14c8STreehugger Robot message(FATAL_ERROR "Architecture ${arch} can't be targeted") 125*7c3d14c8STreehugger Robot return() 126*7c3d14c8STreehugger Robot endif() 127*7c3d14c8STreehugger Robot if(type STREQUAL "STATIC") 128*7c3d14c8STreehugger Robot set(libname "${name}-${arch}") 129*7c3d14c8STreehugger Robot set(output_name_${libname} ${libname}${COMPILER_RT_OS_SUFFIX}) 130*7c3d14c8STreehugger Robot else() 131*7c3d14c8STreehugger Robot set(libname "${name}-dynamic-${arch}") 132*7c3d14c8STreehugger Robot set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) 133*7c3d14c8STreehugger Robot set(extra_linkflags_${libname} ${TARGET_${arch}_LINKFLAGS} ${LIB_LINKFLAGS}) 134*7c3d14c8STreehugger Robot if(WIN32) 135*7c3d14c8STreehugger Robot set(output_name_${libname} ${name}_dynamic-${arch}${COMPILER_RT_OS_SUFFIX}) 136*7c3d14c8STreehugger Robot else() 137*7c3d14c8STreehugger Robot set(output_name_${libname} ${name}-${arch}${COMPILER_RT_OS_SUFFIX}) 138*7c3d14c8STreehugger Robot endif() 139*7c3d14c8STreehugger Robot endif() 140*7c3d14c8STreehugger Robot set(sources_${libname} ${LIB_SOURCES}) 141*7c3d14c8STreehugger Robot format_object_libs(sources_${libname} ${arch} ${LIB_OBJECT_LIBS}) 142*7c3d14c8STreehugger Robot set(libnames ${libnames} ${libname}) 143*7c3d14c8STreehugger Robot set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) 144*7c3d14c8STreehugger Robot endforeach() 145*7c3d14c8STreehugger Robot endif() 146*7c3d14c8STreehugger Robot 147*7c3d14c8STreehugger Robot if(NOT libnames) 148*7c3d14c8STreehugger Robot return() 149*7c3d14c8STreehugger Robot endif() 150*7c3d14c8STreehugger Robot 151*7c3d14c8STreehugger Robot if(LIB_PARENT_TARGET) 152*7c3d14c8STreehugger Robot # If the parent targets aren't created we should create them 153*7c3d14c8STreehugger Robot if(NOT TARGET ${LIB_PARENT_TARGET}) 154*7c3d14c8STreehugger Robot add_custom_target(${LIB_PARENT_TARGET}) 155*7c3d14c8STreehugger Robot endif() 156*7c3d14c8STreehugger Robot if(NOT TARGET install-${LIB_PARENT_TARGET}) 157*7c3d14c8STreehugger Robot # The parent install target specifies the parent component to scrape up 158*7c3d14c8STreehugger Robot # anything not installed by the individual install targets, and to handle 159*7c3d14c8STreehugger Robot # installation when running the multi-configuration generators. 160*7c3d14c8STreehugger Robot add_custom_target(install-${LIB_PARENT_TARGET} 161*7c3d14c8STreehugger Robot DEPENDS ${LIB_PARENT_TARGET} 162*7c3d14c8STreehugger Robot COMMAND "${CMAKE_COMMAND}" 163*7c3d14c8STreehugger Robot -DCMAKE_INSTALL_COMPONENT=${LIB_PARENT_TARGET} 164*7c3d14c8STreehugger Robot -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 165*7c3d14c8STreehugger Robot set_target_properties(install-${LIB_PARENT_TARGET} PROPERTIES 166*7c3d14c8STreehugger Robot FOLDER "Compiler-RT Misc") 167*7c3d14c8STreehugger Robot endif() 168*7c3d14c8STreehugger Robot endif() 169*7c3d14c8STreehugger Robot 170*7c3d14c8STreehugger Robot foreach(libname ${libnames}) 171*7c3d14c8STreehugger Robot # If you are using a multi-configuration generator we don't generate 172*7c3d14c8STreehugger Robot # per-library install rules, so we fall back to the parent target COMPONENT 173*7c3d14c8STreehugger Robot if(CMAKE_CONFIGURATION_TYPES AND LIB_PARENT_TARGET) 174*7c3d14c8STreehugger Robot set(COMPONENT_OPTION COMPONENT ${LIB_PARENT_TARGET}) 175*7c3d14c8STreehugger Robot else() 176*7c3d14c8STreehugger Robot set(COMPONENT_OPTION COMPONENT ${libname}) 177*7c3d14c8STreehugger Robot endif() 178*7c3d14c8STreehugger Robot 179*7c3d14c8STreehugger Robot add_library(${libname} ${type} ${sources_${libname}}) 180*7c3d14c8STreehugger Robot set_target_compile_flags(${libname} ${extra_cflags_${libname}}) 181*7c3d14c8STreehugger Robot set_target_link_flags(${libname} ${extra_linkflags_${libname}}) 182*7c3d14c8STreehugger Robot set_property(TARGET ${libname} APPEND PROPERTY 183*7c3d14c8STreehugger Robot COMPILE_DEFINITIONS ${LIB_DEFS}) 184*7c3d14c8STreehugger Robot set_target_output_directories(${libname} ${COMPILER_RT_LIBRARY_OUTPUT_DIR}) 185*7c3d14c8STreehugger Robot set_target_properties(${libname} PROPERTIES 186*7c3d14c8STreehugger Robot OUTPUT_NAME ${output_name_${libname}}) 187*7c3d14c8STreehugger Robot set_target_properties(${libname} PROPERTIES FOLDER "Compiler-RT Runtime") 188*7c3d14c8STreehugger Robot if(LIB_LINK_LIBS AND ${type} STREQUAL "SHARED") 189*7c3d14c8STreehugger Robot target_link_libraries(${libname} ${LIB_LINK_LIBS}) 190*7c3d14c8STreehugger Robot endif() 191*7c3d14c8STreehugger Robot install(TARGETS ${libname} 192*7c3d14c8STreehugger Robot ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR} 193*7c3d14c8STreehugger Robot ${COMPONENT_OPTION} 194*7c3d14c8STreehugger Robot LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR} 195*7c3d14c8STreehugger Robot ${COMPONENT_OPTION} 196*7c3d14c8STreehugger Robot RUNTIME DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR} 197*7c3d14c8STreehugger Robot ${COMPONENT_OPTION}) 198*7c3d14c8STreehugger Robot 199*7c3d14c8STreehugger Robot # We only want to generate per-library install targets if you aren't using 200*7c3d14c8STreehugger Robot # an IDE because the extra targets get cluttered in IDEs. 201*7c3d14c8STreehugger Robot if(NOT CMAKE_CONFIGURATION_TYPES) 202*7c3d14c8STreehugger Robot add_custom_target(install-${libname} 203*7c3d14c8STreehugger Robot DEPENDS ${libname} 204*7c3d14c8STreehugger Robot COMMAND "${CMAKE_COMMAND}" 205*7c3d14c8STreehugger Robot -DCMAKE_INSTALL_COMPONENT=${libname} 206*7c3d14c8STreehugger Robot -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") 207*7c3d14c8STreehugger Robot # If you have a parent target specified, we bind the new install target 208*7c3d14c8STreehugger Robot # to the parent install target. 209*7c3d14c8STreehugger Robot if(LIB_PARENT_TARGET) 210*7c3d14c8STreehugger Robot add_dependencies(install-${LIB_PARENT_TARGET} install-${libname}) 211*7c3d14c8STreehugger Robot endif() 212*7c3d14c8STreehugger Robot endif() 213*7c3d14c8STreehugger Robot if(APPLE) 214*7c3d14c8STreehugger Robot set_target_properties(${libname} PROPERTIES 215*7c3d14c8STreehugger Robot OSX_ARCHITECTURES "${LIB_ARCHS_${libname}}") 216*7c3d14c8STreehugger Robot endif() 217*7c3d14c8STreehugger Robot 218*7c3d14c8STreehugger Robot if(type STREQUAL "SHARED") 219*7c3d14c8STreehugger Robot rt_externalize_debuginfo(${libname}) 220*7c3d14c8STreehugger Robot endif() 221*7c3d14c8STreehugger Robot endforeach() 222*7c3d14c8STreehugger Robot if(LIB_PARENT_TARGET) 223*7c3d14c8STreehugger Robot add_dependencies(${LIB_PARENT_TARGET} ${libnames}) 224*7c3d14c8STreehugger Robot endif() 225*7c3d14c8STreehugger Robotendfunction() 226*7c3d14c8STreehugger Robot 227*7c3d14c8STreehugger Robot# when cross compiling, COMPILER_RT_TEST_COMPILER_CFLAGS help 228*7c3d14c8STreehugger Robot# in compilation and linking of unittests. 229*7c3d14c8STreehugger Robotstring(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}") 230*7c3d14c8STreehugger Robotset(COMPILER_RT_UNITTEST_LINKFLAGS ${COMPILER_RT_UNITTEST_CFLAGS}) 231*7c3d14c8STreehugger Robot 232*7c3d14c8STreehugger Robot# Unittests support. 233*7c3d14c8STreehugger Robotset(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest) 234*7c3d14c8STreehugger Robotset(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc) 235*7c3d14c8STreehugger Robotset(COMPILER_RT_GTEST_CFLAGS 236*7c3d14c8STreehugger Robot -DGTEST_NO_LLVM_RAW_OSTREAM=1 237*7c3d14c8STreehugger Robot -DGTEST_HAS_RTTI=0 238*7c3d14c8STreehugger Robot -I${COMPILER_RT_GTEST_PATH}/include 239*7c3d14c8STreehugger Robot -I${COMPILER_RT_GTEST_PATH} 240*7c3d14c8STreehugger Robot) 241*7c3d14c8STreehugger Robot 242*7c3d14c8STreehugger Robotappend_list_if(COMPILER_RT_DEBUG -DSANITIZER_DEBUG=1 COMPILER_RT_UNITTEST_CFLAGS) 243*7c3d14c8STreehugger Robot 244*7c3d14c8STreehugger Robotif(MSVC) 245*7c3d14c8STreehugger Robot # clang doesn't support exceptions on Windows yet. 246*7c3d14c8STreehugger Robot list(APPEND COMPILER_RT_UNITTEST_CFLAGS -D_HAS_EXCEPTIONS=0) 247*7c3d14c8STreehugger Robot 248*7c3d14c8STreehugger Robot # We should teach clang to understand "#pragma intrinsic", see PR19898. 249*7c3d14c8STreehugger Robot list(APPEND COMPILER_RT_UNITTEST_CFLAGS -Wno-undefined-inline) 250*7c3d14c8STreehugger Robot 251*7c3d14c8STreehugger Robot # Clang doesn't support SEH on Windows yet. 252*7c3d14c8STreehugger Robot list(APPEND COMPILER_RT_GTEST_CFLAGS -DGTEST_HAS_SEH=0) 253*7c3d14c8STreehugger Robot 254*7c3d14c8STreehugger Robot # gtest use a lot of stuff marked as deprecated on Windows. 255*7c3d14c8STreehugger Robot list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations) 256*7c3d14c8STreehugger Robot 257*7c3d14c8STreehugger Robot # Visual Studio 2012 only supports up to 8 template parameters in 258*7c3d14c8STreehugger Robot # std::tr1::tuple by default, but gtest requires 10 259*7c3d14c8STreehugger Robot if(MSVC_VERSION EQUAL 1700) 260*7c3d14c8STreehugger Robot list(APPEND COMPILER_RT_GTEST_CFLAGS -D_VARIADIC_MAX=10) 261*7c3d14c8STreehugger Robot endif() 262*7c3d14c8STreehugger Robotendif() 263*7c3d14c8STreehugger Robot 264*7c3d14c8STreehugger Robot# Link objects into a single executable with COMPILER_RT_TEST_COMPILER, 265*7c3d14c8STreehugger Robot# using specified link flags. Make executable a part of provided 266*7c3d14c8STreehugger Robot# test_suite. 267*7c3d14c8STreehugger Robot# add_compiler_rt_test(<test_suite> <test_name> 268*7c3d14c8STreehugger Robot# SUBDIR <subdirectory for binary> 269*7c3d14c8STreehugger Robot# OBJECTS <object files> 270*7c3d14c8STreehugger Robot# DEPS <deps (e.g. runtime libs)> 271*7c3d14c8STreehugger Robot# LINK_FLAGS <link flags>) 272*7c3d14c8STreehugger Robotmacro(add_compiler_rt_test test_suite test_name) 273*7c3d14c8STreehugger Robot cmake_parse_arguments(TEST "" "SUBDIR" "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN}) 274*7c3d14c8STreehugger Robot set(output_bin ${CMAKE_CURRENT_BINARY_DIR}) 275*7c3d14c8STreehugger Robot if(TEST_SUBDIR) 276*7c3d14c8STreehugger Robot set(output_bin "${output_bin}/${TEST_SUBDIR}") 277*7c3d14c8STreehugger Robot endif() 278*7c3d14c8STreehugger Robot if(CMAKE_CONFIGURATION_TYPES) 279*7c3d14c8STreehugger Robot set(output_bin "${output_bin}/${CMAKE_CFG_INTDIR}") 280*7c3d14c8STreehugger Robot endif() 281*7c3d14c8STreehugger Robot set(output_bin "${output_bin}/${test_name}") 282*7c3d14c8STreehugger Robot if(MSVC) 283*7c3d14c8STreehugger Robot set(output_bin "${output_bin}.exe") 284*7c3d14c8STreehugger Robot endif() 285*7c3d14c8STreehugger Robot 286*7c3d14c8STreehugger Robot # Use host compiler in a standalone build, and just-built Clang otherwise. 287*7c3d14c8STreehugger Robot if(NOT COMPILER_RT_STANDALONE_BUILD) 288*7c3d14c8STreehugger Robot list(APPEND TEST_DEPS clang) 289*7c3d14c8STreehugger Robot endif() 290*7c3d14c8STreehugger Robot # If we're not on MSVC, include the linker flags from CMAKE but override them 291*7c3d14c8STreehugger Robot # with the provided link flags. This ensures that flags which are required to 292*7c3d14c8STreehugger Robot # link programs at all are included, but the changes needed for the test 293*7c3d14c8STreehugger Robot # trump. With MSVC we can't do that because CMake is set up to run link.exe 294*7c3d14c8STreehugger Robot # when linking, not the compiler. Here, we hack it to use the compiler 295*7c3d14c8STreehugger Robot # because we want to use -fsanitize flags. 296*7c3d14c8STreehugger Robot if(NOT MSVC) 297*7c3d14c8STreehugger Robot set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}") 298*7c3d14c8STreehugger Robot separate_arguments(TEST_LINK_FLAGS) 299*7c3d14c8STreehugger Robot endif() 300*7c3d14c8STreehugger Robot add_custom_target(${test_name} 301*7c3d14c8STreehugger Robot COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS} 302*7c3d14c8STreehugger Robot -o "${output_bin}" 303*7c3d14c8STreehugger Robot ${TEST_LINK_FLAGS} 304*7c3d14c8STreehugger Robot DEPENDS ${TEST_DEPS}) 305*7c3d14c8STreehugger Robot set_target_properties(${test_name} PROPERTIES FOLDER "Compiler-RT Tests") 306*7c3d14c8STreehugger Robot 307*7c3d14c8STreehugger Robot # Make the test suite depend on the binary. 308*7c3d14c8STreehugger Robot add_dependencies(${test_suite} ${test_name}) 309*7c3d14c8STreehugger Robotendmacro() 310*7c3d14c8STreehugger Robot 311*7c3d14c8STreehugger Robotmacro(add_compiler_rt_resource_file target_name file_name component) 312*7c3d14c8STreehugger Robot set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}") 313*7c3d14c8STreehugger Robot set(dst_file "${COMPILER_RT_OUTPUT_DIR}/${file_name}") 314*7c3d14c8STreehugger Robot add_custom_command(OUTPUT ${dst_file} 315*7c3d14c8STreehugger Robot DEPENDS ${src_file} 316*7c3d14c8STreehugger Robot COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file} 317*7c3d14c8STreehugger Robot COMMENT "Copying ${file_name}...") 318*7c3d14c8STreehugger Robot add_custom_target(${target_name} DEPENDS ${dst_file}) 319*7c3d14c8STreehugger Robot # Install in Clang resource directory. 320*7c3d14c8STreehugger Robot install(FILES ${file_name} 321*7c3d14c8STreehugger Robot DESTINATION ${COMPILER_RT_INSTALL_PATH} 322*7c3d14c8STreehugger Robot COMPONENT ${component}) 323*7c3d14c8STreehugger Robot add_dependencies(${component} ${target_name}) 324*7c3d14c8STreehugger Robot 325*7c3d14c8STreehugger Robot set_target_properties(${target_name} PROPERTIES FOLDER "Compiler-RT Misc") 326*7c3d14c8STreehugger Robotendmacro() 327*7c3d14c8STreehugger Robot 328*7c3d14c8STreehugger Robotmacro(add_compiler_rt_script name) 329*7c3d14c8STreehugger Robot set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name}) 330*7c3d14c8STreehugger Robot set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name}) 331*7c3d14c8STreehugger Robot add_custom_command(OUTPUT ${dst} 332*7c3d14c8STreehugger Robot DEPENDS ${src} 333*7c3d14c8STreehugger Robot COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} 334*7c3d14c8STreehugger Robot COMMENT "Copying ${name}...") 335*7c3d14c8STreehugger Robot add_custom_target(${name} DEPENDS ${dst}) 336*7c3d14c8STreehugger Robot install(FILES ${dst} 337*7c3d14c8STreehugger Robot PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE 338*7c3d14c8STreehugger Robot DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin) 339*7c3d14c8STreehugger Robotendmacro(add_compiler_rt_script src name) 340*7c3d14c8STreehugger Robot 341*7c3d14c8STreehugger Robot# Builds custom version of libc++ and installs it in <prefix>. 342*7c3d14c8STreehugger Robot# Can be used to build sanitized versions of libc++ for running unit tests. 343*7c3d14c8STreehugger Robot# add_custom_libcxx(<name> <prefix> 344*7c3d14c8STreehugger Robot# DEPS <list of build deps> 345*7c3d14c8STreehugger Robot# CFLAGS <list of compile flags>) 346*7c3d14c8STreehugger Robotmacro(add_custom_libcxx name prefix) 347*7c3d14c8STreehugger Robot if(NOT COMPILER_RT_HAS_LIBCXX_SOURCES) 348*7c3d14c8STreehugger Robot message(FATAL_ERROR "libcxx not found!") 349*7c3d14c8STreehugger Robot endif() 350*7c3d14c8STreehugger Robot 351*7c3d14c8STreehugger Robot cmake_parse_arguments(LIBCXX "" "" "DEPS;CFLAGS" ${ARGN}) 352*7c3d14c8STreehugger Robot foreach(flag ${LIBCXX_CFLAGS}) 353*7c3d14c8STreehugger Robot set(flagstr "${flagstr} ${flag}") 354*7c3d14c8STreehugger Robot endforeach() 355*7c3d14c8STreehugger Robot set(LIBCXX_CFLAGS ${flagstr}) 356*7c3d14c8STreehugger Robot 357*7c3d14c8STreehugger Robot if(NOT COMPILER_RT_STANDALONE_BUILD) 358*7c3d14c8STreehugger Robot list(APPEND LIBCXX_DEPS clang) 359*7c3d14c8STreehugger Robot endif() 360*7c3d14c8STreehugger Robot 361*7c3d14c8STreehugger Robot ExternalProject_Add(${name} 362*7c3d14c8STreehugger Robot PREFIX ${prefix} 363*7c3d14c8STreehugger Robot SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH} 364*7c3d14c8STreehugger Robot CMAKE_ARGS -DCMAKE_MAKE_PROGRAM:STRING=${CMAKE_MAKE_PROGRAM} 365*7c3d14c8STreehugger Robot -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER} 366*7c3d14c8STreehugger Robot -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_CXX_COMPILER} 367*7c3d14c8STreehugger Robot -DCMAKE_C_FLAGS=${LIBCXX_CFLAGS} 368*7c3d14c8STreehugger Robot -DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS} 369*7c3d14c8STreehugger Robot -DCMAKE_BUILD_TYPE=Release 370*7c3d14c8STreehugger Robot -DCMAKE_INSTALL_PREFIX:PATH=<INSTALL_DIR> 371*7c3d14c8STreehugger Robot -DLLVM_PATH=${LLVM_MAIN_SRC_DIR} 372*7c3d14c8STreehugger Robot LOG_BUILD 1 373*7c3d14c8STreehugger Robot LOG_CONFIGURE 1 374*7c3d14c8STreehugger Robot LOG_INSTALL 1 375*7c3d14c8STreehugger Robot ) 376*7c3d14c8STreehugger Robot set_target_properties(${name} PROPERTIES EXCLUDE_FROM_ALL TRUE) 377*7c3d14c8STreehugger Robot 378*7c3d14c8STreehugger Robot ExternalProject_Add_Step(${name} force-reconfigure 379*7c3d14c8STreehugger Robot DEPENDERS configure 380*7c3d14c8STreehugger Robot ALWAYS 1 381*7c3d14c8STreehugger Robot ) 382*7c3d14c8STreehugger Robot 383*7c3d14c8STreehugger Robot ExternalProject_Add_Step(${name} clobber 384*7c3d14c8STreehugger Robot COMMAND ${CMAKE_COMMAND} -E remove_directory <BINARY_DIR> 385*7c3d14c8STreehugger Robot COMMAND ${CMAKE_COMMAND} -E make_directory <BINARY_DIR> 386*7c3d14c8STreehugger Robot COMMENT "Clobberring ${name} build directory..." 387*7c3d14c8STreehugger Robot DEPENDERS configure 388*7c3d14c8STreehugger Robot DEPENDS ${LIBCXX_DEPS} 389*7c3d14c8STreehugger Robot ) 390*7c3d14c8STreehugger Robotendmacro() 391*7c3d14c8STreehugger Robot 392*7c3d14c8STreehugger Robotfunction(rt_externalize_debuginfo name) 393*7c3d14c8STreehugger Robot if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO) 394*7c3d14c8STreehugger Robot return() 395*7c3d14c8STreehugger Robot endif() 396*7c3d14c8STreehugger Robot 397*7c3d14c8STreehugger Robot if(NOT COMPILER_RT_EXTERNALIZE_DEBUGINFO_SKIP_STRIP) 398*7c3d14c8STreehugger Robot set(strip_command COMMAND xcrun strip -Sl $<TARGET_FILE:${name}>) 399*7c3d14c8STreehugger Robot endif() 400*7c3d14c8STreehugger Robot 401*7c3d14c8STreehugger Robot if(APPLE) 402*7c3d14c8STreehugger Robot if(CMAKE_CXX_FLAGS MATCHES "-flto" 403*7c3d14c8STreehugger Robot OR CMAKE_CXX_FLAGS_${uppercase_CMAKE_BUILD_TYPE} MATCHES "-flto") 404*7c3d14c8STreehugger Robot 405*7c3d14c8STreehugger Robot set(lto_object ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_CFG_INTDIR}/${name}-lto.o) 406*7c3d14c8STreehugger Robot set_property(TARGET ${name} APPEND_STRING PROPERTY 407*7c3d14c8STreehugger Robot LINK_FLAGS " -Wl,-object_path_lto -Wl,${lto_object}") 408*7c3d14c8STreehugger Robot endif() 409*7c3d14c8STreehugger Robot add_custom_command(TARGET ${name} POST_BUILD 410*7c3d14c8STreehugger Robot COMMAND xcrun dsymutil $<TARGET_FILE:${name}> 411*7c3d14c8STreehugger Robot ${strip_command}) 412*7c3d14c8STreehugger Robot else() 413*7c3d14c8STreehugger Robot message(FATAL_ERROR "COMPILER_RT_EXTERNALIZE_DEBUGINFO isn't implemented for non-darwin platforms!") 414*7c3d14c8STreehugger Robot endif() 415*7c3d14c8STreehugger Robotendfunction() 416