Skip to content

Commit c4ee135

Browse files
committed
[CMake][Compiler-rt] Compute LLVM_MAIN_SRC_DIR assuming the monorepo
layout. When doing a standalone compiler-rt build we currently rely on getting information from the `llvm-config` binary. Previously we would rely on calling `llvm-config --src-root` to find the LLVM sources. Unfortunately the returned path could easily be wrong if the sources were built on another machine. Now that compiler-rt is part of a monorepo we can easily fix this problem by finding the LLVM source tree next to `compiler-rt` in the monorepo. We do this regardless of whether or not the `llvm-config` binary is available which moves us one step closer to not requiring `llvm-config` to be available. To try avoid anyone breaking anyone who relies on the current behavior, if the path assuming the monorepo layout doesn't exist we invoke `llvm-config --src-root` to get the path. A deprecation warning is emitted if this path is taken because we should remove this path in the future given that other runtimes already assume the monorepo layout. We also now emit a warning if `LLVM_MAIN_SRC_DIR` does not exist. The intention is that this should be a hard error in future but to avoid breaking existing users we'll keep this as a warning for now. rdar://76016632 Differential Revision: https://reviews.llvm.org/D99620 (cherry picked from commit fa818bb)
1 parent 0bf32a0 commit c4ee135

File tree

1 file changed

+89
-1
lines changed

1 file changed

+89
-1
lines changed

compiler-rt/cmake/Modules/CompilerRTUtils.cmake

Lines changed: 89 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,57 @@ macro(detect_target_arch)
209209
endif()
210210
endmacro()
211211

212+
function(get_compiler_rt_root_source_dir ROOT_DIR_VAR)
213+
# Compute the path to the root of the Compiler-RT source tree
214+
# regardless of how the project was configured.
215+
#
216+
# This function is useful because using `${CMAKE_SOURCE_DIR}`
217+
# is error prone due to the numerous ways Compiler-RT can be
218+
# configured.
219+
#
220+
# `ROOT_DIR_VAR` - the name of the variable to write the result to.
221+
#
222+
# TODO(dliew): When CMake min version is 3.17 or newer use
223+
# `CMAKE_CURRENT_FUNCTION_LIST_DIR` instead.
224+
if ("${ROOT_DIR_VAR}" STREQUAL "")
225+
message(FATAL_ERROR "ROOT_DIR_VAR cannot be empty")
226+
endif()
227+
228+
# Compiler-rt supports different source root paths.
229+
# Handle each case here.
230+
set(PATH_TO_COMPILER_RT_SOURCE_ROOT "")
231+
if (DEFINED CompilerRTBuiltins_SOURCE_DIR)
232+
# Compiler-RT Builtins standalone build.
233+
# `llvm-project/compiler-rt/lib/builtins`
234+
set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CompilerRTBuiltins_SOURCE_DIR}/../../")
235+
elseif(DEFINED CompilerRT_SOURCE_DIR)
236+
# Compiler-RT standalone build.
237+
# `llvm-project/compiler-rt`
238+
set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CompilerRT_SOURCE_DIR}")
239+
elseif (EXISTS "${CMAKE_SOURCE_DIR}/../compiler-rt")
240+
# In tree build with LLVM as the root project.
241+
# See `llvm-project/projects/`.
242+
# Assumes monorepo layout.
243+
set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CMAKE_SOURCE_DIR}/../compiler-rt")
244+
else()
245+
message(FATAL_ERROR "Unhandled Compiler-RT source root configuration.")
246+
endif()
247+
248+
get_filename_component(ROOT_DIR "${PATH_TO_COMPILER_RT_SOURCE_ROOT}" ABSOLUTE)
249+
if (NOT EXISTS "${ROOT_DIR}")
250+
message(FATAL_ERROR "Path \"${ROOT_DIR}\" doesn't exist")
251+
endif()
252+
253+
# Sanity check: Make sure we can locate the current source file via the
254+
# computed path.
255+
set(PATH_TO_CURRENT_FILE "${ROOT_DIR}/cmake/Modules/CompilerRTUtils.cmake")
256+
if (NOT EXISTS "${PATH_TO_CURRENT_FILE}")
257+
message(FATAL_ERROR "Could not find \"${PATH_TO_CURRENT_FILE}\"")
258+
endif()
259+
260+
set("${ROOT_DIR_VAR}" "${ROOT_DIR}" PARENT_SCOPE)
261+
endfunction()
262+
212263
macro(load_llvm_config)
213264
if (NOT LLVM_CONFIG_PATH)
214265
find_program(LLVM_CONFIG_PATH "llvm-config"
@@ -219,6 +270,19 @@ macro(load_llvm_config)
219270
"Reconfigure with -DLLVM_CONFIG_PATH=path/to/llvm-config.")
220271
endif()
221272
endif()
273+
274+
# Compute path to LLVM sources assuming the monorepo layout.
275+
# We don't set `LLVM_MAIN_SRC_DIR` directly to avoid overriding a user provided
276+
# CMake cache value.
277+
get_compiler_rt_root_source_dir(COMPILER_RT_ROOT_SRC_PATH)
278+
get_filename_component(LLVM_MAIN_SRC_DIR_DEFAULT "${COMPILER_RT_ROOT_SRC_PATH}/../llvm" ABSOLUTE)
279+
if (NOT EXISTS "${LLVM_MAIN_SRC_DIR_DEFAULT}")
280+
# TODO(dliew): Remove this legacy fallback path.
281+
message(WARNING
282+
"LLVM source tree not found at \"${LLVM_MAIN_SRC_DIR_DEFAULT}\". "
283+
"You are not using the monorepo layout. This configuration is DEPRECATED.")
284+
endif()
285+
222286
if (LLVM_CONFIG_PATH)
223287
execute_process(
224288
COMMAND ${LLVM_CONFIG_PATH} "--obj-root" "--bindir" "--libdir" "--src-root" "--includedir"
@@ -236,10 +300,20 @@ macro(load_llvm_config)
236300

237301
set(LLVM_BINARY_DIR ${BINARY_DIR} CACHE PATH "Path to LLVM build tree")
238302
set(LLVM_LIBRARY_DIR ${LIBRARY_DIR} CACHE PATH "Path to llvm/lib")
239-
set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
240303
set(LLVM_TOOLS_BINARY_DIR ${TOOLS_BINARY_DIR} CACHE PATH "Path to llvm/bin")
241304
set(LLVM_INCLUDE_DIR ${INCLUDE_DIR} CACHE PATH "Paths to LLVM headers")
242305

306+
if (NOT EXISTS "${LLVM_MAIN_SRC_DIR_DEFAULT}")
307+
# TODO(dliew): Remove this legacy fallback path.
308+
message(WARNING
309+
"Consulting llvm-config for the LLVM source path "
310+
"as a fallback. This behavior will be removed in the future.")
311+
# We don't set `LLVM_MAIN_SRC_DIR` directly to avoid overriding a user
312+
# provided CMake cache value.
313+
set(LLVM_MAIN_SRC_DIR_DEFAULT "${MAIN_SRC_DIR}")
314+
message(STATUS "Using LLVM source path (${LLVM_MAIN_SRC_DIR_DEFAULT}) from llvm-config")
315+
endif()
316+
243317
# Detect if we have the LLVMXRay and TestingSupport library installed and
244318
# available from llvm-config.
245319
execute_process(
@@ -305,6 +379,20 @@ macro(load_llvm_config)
305379
set(LLVM_LIBRARY_OUTPUT_INTDIR
306380
${LLVM_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX})
307381
endif()
382+
383+
# Finally set the cache variable now that `llvm-config` has also had a chance
384+
# to set `LLVM_MAIN_SRC_DIR_DEFAULT`.
385+
set(LLVM_MAIN_SRC_DIR "${LLVM_MAIN_SRC_DIR_DEFAULT}" CACHE PATH "Path to LLVM source tree")
386+
message(STATUS "LLVM_MAIN_SRC_DIR: \"${LLVM_MAIN_SRC_DIR}\"")
387+
if (NOT EXISTS "${LLVM_MAIN_SRC_DIR}")
388+
# TODO(dliew): Make this a hard error
389+
message(WARNING "LLVM_MAIN_SRC_DIR (${LLVM_MAIN_SRC_DIR}) does not exist. "
390+
"You can override the inferred path by adding "
391+
"`-DLLVM_MAIN_SRC_DIR=<path_to_llvm_src>` to your CMake invocation "
392+
"where `<path_to_llvm_src>` is the path to the `llvm` directory in "
393+
"the `llvm-project` repo. "
394+
"This will be treated as error in the future.")
395+
endif()
308396
endmacro()
309397

310398
macro(construct_compiler_rt_default_triple)

0 commit comments

Comments
 (0)