Skip to content

Commit fd28517

Browse files
committed
[CMake][Compiler-rt] Make it possible to configure standalone compiler-rt without LLVMConfig.cmake.
Previously it wasn't possible to configure a standalone compiler-rt build if the `LLVMConfig.cmake` file isn't present in a shipped toolchain. This patch adds a fallback behaviour for when `LLVMConfig.cmake` is not available in the toolchain being used for configure. The fallback behaviour mocks out the bare minimum required to make a configure succeed when the host is Darwin. Support for other platforms could be added in future patches. The new code path is taken either in one of the following cases: * `llvm-config` is not available. * `llvm-config` is available but it provides an invalid path for the CMake files. The motivation here is to be able to generate the compiler-rt lit test suites for an arbitrary LLVM toolchain and then run the tests against it. The invocation to do this looks something like. ``` CC=/path/to/cc \ CXX=/path/to/c++ \ cmake \ -G Ninja \ -DLLVM_CONFIG_PATH=/path/to/llvm-config \ -DCOMPILER_RT_INCLUDE_TESTS=ON \ /path/to/llvm-project/compiler-rt # Note we don't compile compiler-rt in this workflow. bin/llvm-lit -v test/path/to/generated/test_suite ``` A possible alternative approach is to configure the `cmake/modules/LLVMConfig.cmake.in` file in the LLVM source tree and then include it. This approach was not taken because it is more complicated. An interesting side benefit of this patch is that it is now possible to configure on Darwin without `llvm-config` being available by configuring with `-DLLVM_CONFIG_PATH=""`. This moves us a step closer to a world where no LLVM build artefacts are required to build compiler-rt. rdar://76016632 Differential Revision: https://reviews.llvm.org/D99621
1 parent fa818bb commit fd28517

File tree

2 files changed

+94
-3
lines changed

2 files changed

+94
-3
lines changed
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
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()

compiler-rt/cmake/Modules/CompilerRTUtils.cmake

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -283,6 +283,7 @@ macro(load_llvm_config)
283283
"You are not using the monorepo layout. This configuration is DEPRECATED.")
284284
endif()
285285

286+
set(FOUND_LLVM_CMAKE_PATH FALSE)
286287
if (LLVM_CONFIG_PATH)
287288
execute_process(
288289
COMMAND ${LLVM_CONFIG_PATH} "--obj-root" "--bindir" "--libdir" "--src-root" "--includedir"
@@ -372,9 +373,15 @@ macro(load_llvm_config)
372373
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
373374
endif()
374375

375-
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
376-
# Get some LLVM variables from LLVMConfig.
377-
include("${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
376+
if (EXISTS "${LLVM_CMAKE_PATH}")
377+
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
378+
# Get some LLVM variables from LLVMConfig.
379+
include("${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
380+
set(FOUND_LLVM_CMAKE_PATH TRUE)
381+
else()
382+
set(FOUND_LLVM_CMAKE_PATH FALSE)
383+
message(WARNING "LLVM CMake path (${LLVM_CMAKE_PATH}) reported by llvm-config does not exist")
384+
endif()
378385

379386
set(LLVM_LIBRARY_OUTPUT_INTDIR
380387
${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
@@ -393,6 +400,15 @@ macro(load_llvm_config)
393400
"the `llvm-project` repo. "
394401
"This will be treated as error in the future.")
395402
endif()
403+
404+
if (NOT FOUND_LLVM_CMAKE_PATH)
405+
# This configuration tries to configure without the prescence of `LLVMConfig.cmake`. It is
406+
# intended for testing purposes (generating the lit test suites) and will likely not support
407+
# a build of the runtimes in compiler-rt.
408+
include(CompilerRTMockLLVMCMakeConfig)
409+
compiler_rt_mock_llvm_cmake_config()
410+
endif()
411+
396412
endmacro()
397413

398414
macro(construct_compiler_rt_default_triple)

0 commit comments

Comments
 (0)