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