include(AddLLVM) include(ExternalProject) include(LLVMParseArguments) include(CompilerRTUtils) # Tries to add "object library" target for a given architecture # with name "." if architecture can be targeted. # add_compiler_rt_object_library( # SOURCES # CFLAGS # DEFS ) macro(add_compiler_rt_object_library name arch) if(CAN_TARGET_${arch}) parse_arguments(LIB "SOURCES;CFLAGS;DEFS" "" ${ARGN}) add_library(${name}.${arch} OBJECT ${LIB_SOURCES}) set_target_compile_flags(${name}.${arch} ${CMAKE_CXX_FLAGS} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) set_property(TARGET ${name}.${arch} APPEND PROPERTY COMPILE_DEFINITIONS ${LIB_DEFS}) else() message(FATAL_ERROR "Archtecture ${arch} can't be targeted") endif() endmacro() # Same as above, but adds universal osx library for either OSX or iOS simulator # with name "." targeting multiple architectures. # add_compiler_rt_darwin_object_library( ARCH # SOURCES # CFLAGS # DEFS ) macro(add_compiler_rt_darwin_object_library name os) parse_arguments(LIB "ARCH;SOURCES;CFLAGS;DEFS" "" ${ARGN}) set(libname "${name}.${os}") add_library(${libname} OBJECT ${LIB_SOURCES}) set_target_compile_flags(${libname} ${LIB_CFLAGS} ${DARWIN_${os}_CFLAGS}) set_target_properties(${libname} PROPERTIES OSX_ARCHITECTURES "${LIB_ARCH}") set_property(TARGET ${libname} APPEND PROPERTY COMPILE_DEFINITIONS ${LIB_DEFS}) endmacro() # Adds static or shared runtime for a given architecture and puts it in the # proper directory in the build and install trees. # add_compiler_rt_runtime( {STATIC,SHARED} # SOURCES # CFLAGS # DEFS # OUTPUT_NAME ) macro(add_compiler_rt_runtime name arch type) if(CAN_TARGET_${arch}) parse_arguments(LIB "SOURCES;CFLAGS;DEFS;OUTPUT_NAME" "" ${ARGN}) add_library(${name} ${type} ${LIB_SOURCES}) # Setup compile flags and definitions. set_target_compile_flags(${name} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) if (NOT MSVC) # We do not want any custom link flags set on MSVC; especially not the # compiler flags, as with other compilers. set_target_link_flags(${name} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) endif() set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS ${LIB_DEFS}) # Setup correct output directory in the build tree. set_target_properties(${name} PROPERTIES ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR} LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}) if ("${LIB_OUTPUT_NAME}" STREQUAL "") set_target_properties(${name} PROPERTIES OUTPUT_NAME ${name}${COMPILER_RT_OS_SUFFIX}) else() set_target_properties(${name} PROPERTIES OUTPUT_NAME ${LIB_OUTPUT_NAME}) endif() # Add installation command. install(TARGETS ${name} ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR} LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) else() message(FATAL_ERROR "Archtecture ${arch} can't be targeted") endif() endmacro() # Same as add_compiler_rt_runtime(... STATIC), but creates a universal library # for several architectures. # add_compiler_rt_osx_static_runtime( ARCH # SOURCES # CFLAGS # DEFS ) macro(add_compiler_rt_osx_static_runtime name) parse_arguments(LIB "ARCH;SOURCES;CFLAGS;DEFS" "" ${ARGN}) add_library(${name} STATIC ${LIB_SOURCES}) set_target_compile_flags(${name} ${LIB_CFLAGS}) set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS ${LIB_DEFS}) set_target_properties(${name} PROPERTIES OSX_ARCHITECTURES "${LIB_ARCH}" ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}) install(TARGETS ${name} ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) endmacro() # Adds dynamic runtime library on osx/iossim, which supports multiple # architectures. # add_compiler_rt_darwin_dynamic_runtime( # ARCH # SOURCES # CFLAGS # DEFS # LINKFLAGS ) macro(add_compiler_rt_darwin_dynamic_runtime name os) parse_arguments(LIB "ARCH;SOURCES;CFLAGS;DEFS;LINKFLAGS" "" ${ARGN}) add_library(${name} SHARED ${LIB_SOURCES}) set_target_compile_flags(${name} ${LIB_CFLAGS} ${DARWIN_${os}_CFLAGS}) set_target_link_flags(${name} ${LIB_LINKFLAGS} ${DARWIN_${os}_LINKFLAGS}) set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS ${LIB_DEFS}) set_target_properties(${name} PROPERTIES OSX_ARCHITECTURES "${LIB_ARCH}" LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}) install(TARGETS ${name} LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) endmacro() set(COMPILER_RT_TEST_CFLAGS) # Unittests support. set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest) set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc) set(COMPILER_RT_GTEST_CFLAGS -DGTEST_NO_LLVM_RAW_OSTREAM=1 -DGTEST_HAS_RTTI=0 -I${COMPILER_RT_GTEST_PATH}/include -I${COMPILER_RT_GTEST_PATH} ) if(MSVC) # clang doesn't support exceptions on Windows yet. list(APPEND COMPILER_RT_TEST_CFLAGS -D_HAS_EXCEPTIONS=0) # We should teach clang to understand "#pragma intrinsic", see PR19898. list(APPEND COMPILER_RT_TEST_CFLAGS -Wno-undefined-inline) # Clang doesn't support SEH on Windows yet. list(APPEND COMPILER_RT_GTEST_CFLAGS -DGTEST_HAS_SEH=0) # gtest use a lot of stuff marked as deprecated on Windows. list(APPEND COMPILER_RT_GTEST_CFLAGS -Wno-deprecated-declarations) # Visual Studio 2012 only supports up to 8 template parameters in # std::tr1::tuple by default, but gtest requires 10 if(MSVC_VERSION EQUAL 1700) list(APPEND COMPILER_RT_GTEST_CFLAGS -D_VARIADIC_MAX=10) endif() endif() # Link objects into a single executable with COMPILER_RT_TEST_COMPILER, # using specified link flags. Make executable a part of provided # test_suite. # add_compiler_rt_test( # OBJECTS # DEPS # LINK_FLAGS ) macro(add_compiler_rt_test test_suite test_name) parse_arguments(TEST "OBJECTS;DEPS;LINK_FLAGS" "" ${ARGN}) set(output_bin "${CMAKE_CURRENT_BINARY_DIR}/${test_name}") # Use host compiler in a standalone build, and just-built Clang otherwise. if(NOT COMPILER_RT_STANDALONE_BUILD) list(APPEND TEST_DEPS clang) endif() # If we're not on MSVC, include the linker flags from CMAKE but override them # with the provided link flags. This ensures that flags which are required to # link programs at all are included, but the changes needed for the test # trump. With MSVC we can't do that because CMake is set up to run link.exe # when linking, not the compiler. Here, we hack it to use the compiler # because we want to use -fsanitize flags. if(NOT MSVC) set(TEST_LINK_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${TEST_LINK_FLAGS}") separate_arguments(TEST_LINK_FLAGS) endif() add_custom_target(${test_name} COMMAND ${COMPILER_RT_TEST_COMPILER} ${TEST_OBJECTS} -o "${output_bin}" ${TEST_LINK_FLAGS} DEPENDS ${TEST_DEPS}) # Make the test suite depend on the binary. add_dependencies(${test_suite} ${test_name}) endmacro() macro(add_compiler_rt_resource_file target_name file_name) set(src_file "${CMAKE_CURRENT_SOURCE_DIR}/${file_name}") set(dst_file "${COMPILER_RT_OUTPUT_DIR}/${file_name}") add_custom_command(OUTPUT ${dst_file} DEPENDS ${src_file} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src_file} ${dst_file} COMMENT "Copying ${file_name}...") add_custom_target(${target_name} DEPENDS ${dst_file}) # Install in Clang resource directory. install(FILES ${file_name} DESTINATION ${COMPILER_RT_INSTALL_PATH}) endmacro() macro(add_compiler_rt_script name) set(dst ${COMPILER_RT_EXEC_OUTPUT_DIR}/${name}) set(src ${CMAKE_CURRENT_SOURCE_DIR}/${name}) add_custom_command(OUTPUT ${dst} DEPENDS ${src} COMMAND ${CMAKE_COMMAND} -E copy_if_different ${src} ${dst} COMMENT "Copying ${name}...") add_custom_target(${name} DEPENDS ${dst}) install(FILES ${dst} PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE DESTINATION ${COMPILER_RT_INSTALL_PATH}/bin) endmacro(add_compiler_rt_script src name) # Builds custom version of libc++ and installs it in . # Can be used to build sanitized versions of libc++ for running unit tests. # add_custom_libcxx( # DEPS # CFLAGS ) macro(add_custom_libcxx name prefix) if(NOT COMPILER_RT_HAS_LIBCXX_SOURCES) message(FATAL_ERROR "libcxx not found!") endif() parse_arguments(LIBCXX "DEPS;CFLAGS" "" ${ARGN}) foreach(flag ${LIBCXX_CFLAGS}) set(flagstr "${flagstr} ${flag}") endforeach() set(LIBCXX_CFLAGS ${flagstr}) if(NOT COMPILER_RT_STANDALONE_BUILD) list(APPEND LIBCXX_DEPS clang) endif() ExternalProject_Add(${name} PREFIX ${prefix} SOURCE_DIR ${COMPILER_RT_LIBCXX_PATH} CMAKE_ARGS -DCMAKE_C_COMPILER=${COMPILER_RT_TEST_COMPILER} -DCMAKE_CXX_COMPILER=${COMPILER_RT_TEST_COMPILER} -DCMAKE_C_FLAGS=${LIBCXX_CFLAGS} -DCMAKE_CXX_FLAGS=${LIBCXX_CFLAGS} -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX:PATH= LOG_BUILD 1 LOG_CONFIGURE 1 LOG_INSTALL 1 ) ExternalProject_Add_Step(${name} force-reconfigure DEPENDERS configure ALWAYS 1 ) ExternalProject_Add_Step(${name} clobber COMMAND ${CMAKE_COMMAND} -E remove_directory COMMAND ${CMAKE_COMMAND} -E make_directory COMMENT "Clobberring ${name} build directory..." DEPENDERS configure DEPENDS ${LIBCXX_DEPS} ) endmacro()