|
| 1 | +# This macro mocks enough of the changes `LLVMConfig.cmake` makes so that |
| 2 | +# compiler-rt can successfully configure itself when a LLVM toolchain is |
| 3 | +# available but the corresponding CMake build files are not. |
| 4 | +# |
| 5 | +# The motivation for this is to be able to generate the compiler-rt |
| 6 | +# lit tests suites and run them against an arbitrary LLVM toolchain |
| 7 | +# which doesn't ship the LLVM CMake build files. |
| 8 | +macro(compiler_rt_mock_llvm_cmake_config) |
| 9 | + message(STATUS "Attempting to mock the changes made by LLVMConfig.cmake") |
| 10 | + compiler_rt_mock_llvm_cmake_config_set_cmake_path() |
| 11 | + compiler_rt_mock_llvm_cmake_config_set_target_triple() |
| 12 | + compiler_rt_mock_llvm_cmake_config_include_cmake_files() |
| 13 | +endmacro() |
| 14 | + |
| 15 | +macro(compiler_rt_mock_llvm_cmake_config_set_cmake_path) |
| 16 | + # Point `LLVM_CMAKE_PATH` at the source tree in the monorepo. |
| 17 | + set(LLVM_CMAKE_PATH "${LLVM_MAIN_SRC_DIR}/cmake/modules") |
| 18 | + if (NOT EXISTS "${LLVM_CMAKE_PATH}") |
| 19 | + message(FATAL_ERROR "LLVM_CMAKE_PATH (${LLVM_CMAKE_PATH}) does not exist") |
| 20 | + endif() |
| 21 | + list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}") |
| 22 | + message(STATUS "LLVM_CMAKE_PATH: \"${LLVM_CMAKE_PATH}\"") |
| 23 | +endmacro() |
| 24 | + |
| 25 | +function(compiler_rt_mock_llvm_cmake_config_set_target_triple) |
| 26 | + # Various bits of compiler-rt depend on the `TARGET_TRIPLE`variable being |
| 27 | + # defined. This function tries to set a sensible value for the variable. |
| 28 | + # This is a function rather than a macro to avoid polluting the variable |
| 29 | + # namespace. |
| 30 | + set(COMPILER_OUTPUT "") |
| 31 | + |
| 32 | + # If the user provides `COMPILER_RT_DEFAULT_TARGET_ONLY` and `CMAKE_C_COMPILER_TARGET` |
| 33 | + # (see `construct_compiler_rt_default_triple`) then prefer that to examining the |
| 34 | + # compiler. |
| 35 | + if (COMPILER_RT_DEFAULT_TARGET_ONLY) |
| 36 | + if (NOT "${CMAKE_C_COMPILER_TARGET}" STREQUAL "") |
| 37 | + message(STATUS |
| 38 | + "Using CMAKE_C_COMPILER_TARGET (${CMAKE_C_COMPILER_TARGET}) as TARGET_TRIPLE") |
| 39 | + endif() |
| 40 | + set(COMPILER_OUTPUT "${CMAKE_C_COMPILER_TARGET}") |
| 41 | + endif() |
| 42 | + |
| 43 | + # Try asking the compiler for its default target triple. |
| 44 | + set(HAD_ERROR FALSE) |
| 45 | + if ("${COMPILER_OUTPUT}" STREQUAL "") |
| 46 | + if ("${CMAKE_C_COMPILER_ID}" MATCHES "Clang|GNU") |
| 47 | + # Note: Clang also supports `-print-target-triple` but gcc doesn't |
| 48 | + # support this flag. |
| 49 | + execute_process( |
| 50 | + COMMAND "${CMAKE_C_COMPILER}" -dumpmachine |
| 51 | + RESULT_VARIABLE HAD_ERROR |
| 52 | + OUTPUT_VARIABLE COMPILER_OUTPUT |
| 53 | + OUTPUT_STRIP_TRAILING_WHITESPACE) |
| 54 | + else() |
| 55 | + message(FATAL_ERROR |
| 56 | + "Fetching target triple from compiler \"${CMAKE_C_COMPILER_ID}\" " |
| 57 | + "is not implemented.") |
| 58 | + endif() |
| 59 | + endif() |
| 60 | + |
| 61 | + if (HAD_ERROR) |
| 62 | + message(FATAL_ERROR "Fetching target triple from compiler failed") |
| 63 | + endif() |
| 64 | + set(TARGET_TRIPLE "${COMPILER_OUTPUT}") |
| 65 | + message(STATUS "TARGET_TRIPLE: \"${TARGET_TRIPLE}\"") |
| 66 | + if ("${TARGET_TRIPLE}" STREQUAL "") |
| 67 | + message(FATAL_ERROR "TARGET_TRIPLE cannot be empty") |
| 68 | + endif() |
| 69 | + set(TARGET_TRIPLE "${TARGET_TRIPLE}" PARENT_SCOPE) |
| 70 | +endfunction() |
| 71 | + |
| 72 | +macro(compiler_rt_mock_llvm_cmake_config_include_cmake_files) |
| 73 | + # Some compiler-rt CMake code needs to call code in this file. |
| 74 | + include("${LLVM_CMAKE_PATH}/AddLLVM.cmake") |
| 75 | +endmacro() |
0 commit comments