1*7c3d14c8STreehugger Robot# On Windows, CMAKE_*_FLAGS are built for MSVC but we use the GCC clang.exe, 2*7c3d14c8STreehugger Robot# which uses completely different flags. Translate some common flag types, and 3*7c3d14c8STreehugger Robot# drop the rest. 4*7c3d14c8STreehugger Robotfunction(translate_msvc_cflags out_flags msvc_flags) 5*7c3d14c8STreehugger Robot # Insert an empty string in the list to simplify processing. 6*7c3d14c8STreehugger Robot set(msvc_flags ";${msvc_flags}") 7*7c3d14c8STreehugger Robot 8*7c3d14c8STreehugger Robot # Canonicalize /flag to -flag. 9*7c3d14c8STreehugger Robot string(REPLACE ";/" ";-" msvc_flags "${msvc_flags}") 10*7c3d14c8STreehugger Robot 11*7c3d14c8STreehugger Robot # Make space separated -D and -U flags into joined flags. 12*7c3d14c8STreehugger Robot string(REGEX REPLACE ";-\([DU]\);" ";-\\1" msvc_flags "${msvc_flags}") 13*7c3d14c8STreehugger Robot 14*7c3d14c8STreehugger Robot set(clang_flags "") 15*7c3d14c8STreehugger Robot foreach(flag ${msvc_flags}) 16*7c3d14c8STreehugger Robot if ("${flag}" MATCHES "^-[DU]") 17*7c3d14c8STreehugger Robot # Pass through basic command line macro definitions (-DNDEBUG). 18*7c3d14c8STreehugger Robot list(APPEND clang_flags "${flag}") 19*7c3d14c8STreehugger Robot elseif ("${flag}" MATCHES "^-O[2x]") 20*7c3d14c8STreehugger Robot # Canonicalize normal optimization flags to -O2. 21*7c3d14c8STreehugger Robot list(APPEND clang_flags "-O2") 22*7c3d14c8STreehugger Robot endif() 23*7c3d14c8STreehugger Robot endforeach() 24*7c3d14c8STreehugger Robot set(${out_flags} "${clang_flags}" PARENT_SCOPE) 25*7c3d14c8STreehugger Robotendfunction() 26*7c3d14c8STreehugger Robot 27*7c3d14c8STreehugger Robot# Compile a source into an object file with COMPILER_RT_TEST_COMPILER using 28*7c3d14c8STreehugger Robot# a provided compile flags and dependenices. 29*7c3d14c8STreehugger Robot# clang_compile(<object> <source> 30*7c3d14c8STreehugger Robot# CFLAGS <list of compile flags> 31*7c3d14c8STreehugger Robot# DEPS <list of dependencies>) 32*7c3d14c8STreehugger Robotmacro(clang_compile object_file source) 33*7c3d14c8STreehugger Robot cmake_parse_arguments(SOURCE "" "" "CFLAGS;DEPS" ${ARGN}) 34*7c3d14c8STreehugger Robot get_filename_component(source_rpath ${source} REALPATH) 35*7c3d14c8STreehugger Robot if(NOT COMPILER_RT_STANDALONE_BUILD) 36*7c3d14c8STreehugger Robot list(APPEND SOURCE_DEPS clang compiler-rt-headers) 37*7c3d14c8STreehugger Robot endif() 38*7c3d14c8STreehugger Robot if (TARGET CompilerRTUnitTestCheckCxx) 39*7c3d14c8STreehugger Robot list(APPEND SOURCE_DEPS CompilerRTUnitTestCheckCxx) 40*7c3d14c8STreehugger Robot endif() 41*7c3d14c8STreehugger Robot string(REGEX MATCH "[.](cc|cpp)$" is_cxx ${source_rpath}) 42*7c3d14c8STreehugger Robot if(is_cxx) 43*7c3d14c8STreehugger Robot string(REPLACE " " ";" global_flags "${CMAKE_CXX_FLAGS}") 44*7c3d14c8STreehugger Robot else() 45*7c3d14c8STreehugger Robot string(REPLACE " " ";" global_flags "${CMAKE_C_FLAGS}") 46*7c3d14c8STreehugger Robot endif() 47*7c3d14c8STreehugger Robot 48*7c3d14c8STreehugger Robot if (MSVC) 49*7c3d14c8STreehugger Robot translate_msvc_cflags(global_flags "${global_flags}") 50*7c3d14c8STreehugger Robot endif() 51*7c3d14c8STreehugger Robot 52*7c3d14c8STreehugger Robot if (APPLE) 53*7c3d14c8STreehugger Robot set(global_flags ${OSX_SYSROOT_FLAG} ${global_flags}) 54*7c3d14c8STreehugger Robot endif() 55*7c3d14c8STreehugger Robot 56*7c3d14c8STreehugger Robot # Ignore unknown warnings. CMAKE_CXX_FLAGS may contain GCC-specific options 57*7c3d14c8STreehugger Robot # which are not supported by Clang. 58*7c3d14c8STreehugger Robot list(APPEND global_flags -Wno-unknown-warning-option) 59*7c3d14c8STreehugger Robot set(compile_flags ${global_flags} ${SOURCE_CFLAGS}) 60*7c3d14c8STreehugger Robot add_custom_command( 61*7c3d14c8STreehugger Robot OUTPUT ${object_file} 62*7c3d14c8STreehugger Robot COMMAND ${COMPILER_RT_TEST_COMPILER} ${compile_flags} -c 63*7c3d14c8STreehugger Robot -o "${object_file}" 64*7c3d14c8STreehugger Robot ${source_rpath} 65*7c3d14c8STreehugger Robot MAIN_DEPENDENCY ${source} 66*7c3d14c8STreehugger Robot DEPENDS ${SOURCE_DEPS}) 67*7c3d14c8STreehugger Robotendmacro() 68*7c3d14c8STreehugger Robot 69*7c3d14c8STreehugger Robot# On Darwin, there are no system-wide C++ headers and the just-built clang is 70*7c3d14c8STreehugger Robot# therefore not able to compile C++ files unless they are copied/symlinked into 71*7c3d14c8STreehugger Robot# ${LLVM_BINARY_DIR}/include/c++ 72*7c3d14c8STreehugger Robot# The just-built clang is used to build compiler-rt unit tests. Let's detect 73*7c3d14c8STreehugger Robot# this before we try to build the tests and print out a suggestion how to fix 74*7c3d14c8STreehugger Robot# it. 75*7c3d14c8STreehugger Robot# On other platforms, this is currently not an issue. 76*7c3d14c8STreehugger Robotmacro(clang_compiler_add_cxx_check) 77*7c3d14c8STreehugger Robot if (APPLE) 78*7c3d14c8STreehugger Robot set(CMD 79*7c3d14c8STreehugger Robot "echo '#include <iostream>' | ${COMPILER_RT_TEST_COMPILER} ${OSX_SYSROOT_FLAG} -E -x c++ - > /dev/null" 80*7c3d14c8STreehugger Robot "if [ $? != 0 ] " 81*7c3d14c8STreehugger Robot " then echo" 82*7c3d14c8STreehugger Robot " echo 'Your just-built clang cannot find C++ headers, which are needed to build and run compiler-rt tests.'" 83*7c3d14c8STreehugger Robot " echo 'You should copy or symlink your system C++ headers into ${LLVM_BINARY_DIR}/include/c++'" 84*7c3d14c8STreehugger Robot " if [ -d $(dirname $(dirname $(xcrun -f clang)))/include/c++ ]" 85*7c3d14c8STreehugger Robot " then echo 'e.g. with:'" 86*7c3d14c8STreehugger Robot " echo ' cp -r' $(dirname $(dirname $(xcrun -f clang)))/include/c++ '${LLVM_BINARY_DIR}/include/'" 87*7c3d14c8STreehugger Robot " elif [ -d $(dirname $(dirname $(xcrun -f clang)))/lib/c++ ]" 88*7c3d14c8STreehugger Robot " then echo 'e.g. with:'" 89*7c3d14c8STreehugger Robot " echo ' cp -r' $(dirname $(dirname $(xcrun -f clang)))/lib/c++ '${LLVM_BINARY_DIR}/include/'" 90*7c3d14c8STreehugger Robot " fi" 91*7c3d14c8STreehugger Robot " echo 'This can also be fixed by checking out the libcxx project from llvm.org and installing the headers'" 92*7c3d14c8STreehugger Robot " echo 'into your build directory:'" 93*7c3d14c8STreehugger Robot " echo ' cd ${LLVM_MAIN_SRC_DIR}/projects && svn co http://llvm.org/svn/llvm-project/libcxx/trunk libcxx'" 94*7c3d14c8STreehugger Robot " echo ' cd ${LLVM_BINARY_DIR} && make -C ${LLVM_MAIN_SRC_DIR}/projects/libcxx installheaders HEADER_DIR=${LLVM_BINARY_DIR}/include'" 95*7c3d14c8STreehugger Robot " echo" 96*7c3d14c8STreehugger Robot " false" 97*7c3d14c8STreehugger Robot "fi" 98*7c3d14c8STreehugger Robot ) 99*7c3d14c8STreehugger Robot add_custom_target(CompilerRTUnitTestCheckCxx 100*7c3d14c8STreehugger Robot COMMAND bash -c "${CMD}" 101*7c3d14c8STreehugger Robot COMMENT "Checking that just-built clang can find C++ headers..." 102*7c3d14c8STreehugger Robot VERBATIM) 103*7c3d14c8STreehugger Robot if (TARGET clang) 104*7c3d14c8STreehugger Robot ADD_DEPENDENCIES(CompilerRTUnitTestCheckCxx clang) 105*7c3d14c8STreehugger Robot endif() 106*7c3d14c8STreehugger Robot endif() 107*7c3d14c8STreehugger Robotendmacro() 108