Skip to content

Commit 0eed292

Browse files
committed
[CMake] Cache the compiler-rt library search results
There's a lot of duplicated calls to find various compiler-rt libraries from build of runtime libraries like libunwind, libc++, libc++abi and compiler-rt. The compiler-rt helper module already implemented caching for results avoid repeated Clang invocations. This change moves the compiler-rt implementation into a shared location and reuses it from other runtimes to reduce duplication and speed up the build. Differential Revision: https://reviews.llvm.org/D88458
1 parent 3be1f4b commit 0eed292

File tree

17 files changed

+130
-264
lines changed

17 files changed

+130
-264
lines changed

cmake/Modules/HandleCompilerRT.cmake

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Check if compile-rt library file path exists.
2+
# If found, cache the path in:
3+
# COMPILER_RT_LIBRARY-<name>-<target>
4+
# If err_flag is true OR path not found, emit a message and set:
5+
# COMPILER_RT_LIBRARY-<name>-<target> to NOTFOUND
6+
function(cache_compiler_rt_library err_flag name target library_file)
7+
if(err_flag OR NOT EXISTS "${library_file}")
8+
message(STATUS "Failed to find compiler-rt ${name} library for ${target}")
9+
set(COMPILER_RT_LIBRARY_${name}_${target} "NOTFOUND" CACHE INTERNAL
10+
"compiler-rt ${name} library for ${target}")
11+
else()
12+
message(STATUS "Found compiler-rt ${name} library: ${library_file}")
13+
set(COMPILER_RT_LIBRARY_${name}_${target} "${library_file}" CACHE INTERNAL
14+
"compiler-rt ${name} library for ${target}")
15+
endif()
16+
endfunction()
17+
18+
function(get_component_name name variable)
19+
if(APPLE)
20+
if(NOT name MATCHES "builtins.*")
21+
set(component_name "${name}_")
22+
endif()
23+
# TODO: Support ios, tvos and watchos as well.
24+
set(component_name "${component_name}osx")
25+
else()
26+
set(component_name "${name}")
27+
endif()
28+
set(${variable} "${component_name}" PARENT_SCOPE)
29+
endfunction()
30+
31+
# Find the path to compiler-rt library `name` (e.g. "builtins") for the
32+
# specified `TARGET` (e.g. "x86_64-linux-gnu") and return it in `variable`.
33+
# This calls cache_compiler_rt_library that caches the path to speed up
34+
# repeated invocations with the same `name` and `target`.
35+
function(find_compiler_rt_library name variable)
36+
cmake_parse_arguments(ARG "" "TARGET" "" ${ARGN})
37+
# While we can use compiler-rt runtimes with other compilers, we need to
38+
# query the compiler for runtime location and thus we require Clang.
39+
if(NOT CMAKE_CXX_COMPILER_ID MATCHES Clang)
40+
set(${variable} "NOTFOUND" PARENT_SCOPE)
41+
return()
42+
endif()
43+
set(target "${ARG_TARGET}")
44+
if(NOT target AND CMAKE_CXX_COMPILER_TARGET)
45+
set(target "${CMAKE_CXX_COMPILER_TARGET}")
46+
endif()
47+
if(NOT DEFINED COMPILER_RT_LIBRARY_builtins_${target})
48+
# If the cache variable is not defined, invoke Clang and then
49+
# set it with cache_compiler_rt_library.
50+
set(clang_command ${CMAKE_CXX_COMPILER} ${CMAKE_REQUIRED_FLAGS})
51+
if(target)
52+
list(APPEND clang_command "--target=${target}")
53+
endif()
54+
get_property(cxx_flags CACHE CMAKE_CXX_FLAGS PROPERTY VALUE)
55+
string(REPLACE " " ";" cxx_flags "${cxx_flags}")
56+
list(APPEND clang_command ${cxx_flags})
57+
execute_process(
58+
COMMAND ${clang_command} "--rtlib=compiler-rt" "-print-libgcc-file-name"
59+
RESULT_VARIABLE had_error
60+
OUTPUT_VARIABLE library_file
61+
)
62+
string(STRIP "${library_file}" library_file)
63+
file(TO_CMAKE_PATH "${library_file}" library_file)
64+
get_filename_component(dirname ${library_file} DIRECTORY)
65+
if(APPLE)
66+
execute_process(
67+
COMMAND ${clang_command} "--print-resource-dir"
68+
RESULT_VARIABLE had_error
69+
OUTPUT_VARIABLE resource_dir
70+
)
71+
string(STRIP "${resource_dir}" resource_dir)
72+
set(dirname "${resource_dir}/lib/darwin")
73+
endif()
74+
get_filename_component(basename ${library_file} NAME)
75+
if(basename MATCHES "libclang_rt\.([a-z0-9_\-]+)\.a")
76+
set(from_name ${CMAKE_MATCH_1})
77+
get_component_name(${CMAKE_MATCH_1} to_name)
78+
string(REPLACE "${from_name}" "${to_name}" basename "${basename}")
79+
set(library_file "${dirname}/${basename}")
80+
cache_compiler_rt_library(${had_error} builtins "${target}" "${library_file}")
81+
endif()
82+
endif()
83+
if(NOT COMPILER_RT_LIBRARY_builtins_${target})
84+
set(${variable} "NOTFOUND" PARENT_SCOPE)
85+
return()
86+
endif()
87+
if(NOT DEFINED COMPILER_RT_LIBRARY_${name}_${target})
88+
# Clang gives only the builtins library path. Other library paths are
89+
# obtained by substituting "builtins" with ${name} in the builtins
90+
# path and then checking if the resultant path exists. The result of
91+
# this check is also cached by cache_compiler_rt_library.
92+
set(library_file "${COMPILER_RT_LIBRARY_builtins_${target}}")
93+
if(library_file MATCHES ".*libclang_rt\.([a-z0-9_\-]+)\.a")
94+
set(from_name ${CMAKE_MATCH_0})
95+
get_component_name(${name} to_name)
96+
string(REPLACE "${from_name}" "${to_name}" library_file "${library_file}")
97+
cache_compiler_rt_library(FALSE "${name}" "${target}" "${library_file}")
98+
endif()
99+
endif()
100+
set(${variable} "${COMPILER_RT_LIBRARY_${name}_${target}}" PARENT_SCOPE)
101+
endfunction()

compiler-rt/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ endif()
1616
list(INSERT CMAKE_MODULE_PATH 0
1717
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
1818
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
19+
"${CMAKE_CURRENT_SOURCE_DIR}/../cmake"
20+
"${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules"
1921
)
2022

2123
if(CMAKE_CONFIGURATION_TYPES)

compiler-rt/cmake/Modules/AddCompilerRT.cmake

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ function(add_compiler_rt_runtime name type)
254254
if(COMPILER_RT_USE_BUILTINS_LIBRARY AND NOT type STREQUAL "OBJECT" AND
255255
NOT name STREQUAL "clang_rt.builtins")
256256
get_compiler_rt_target(${arch} target)
257-
find_compiler_rt_library(builtins ${target} builtins_${libname})
257+
find_compiler_rt_library(builtins builtins_${libname} TARGET ${target})
258258
if(builtins_${libname} STREQUAL "NOTFOUND")
259259
message(FATAL_ERROR "Cannot find builtins library for the target architecture")
260260
endif()

compiler-rt/cmake/Modules/HandleCompilerRT.cmake

Lines changed: 0 additions & 65 deletions
This file was deleted.

compiler-rt/cmake/config-ix.cmake

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ endfunction()
1616
check_library_exists(c fopen "" COMPILER_RT_HAS_LIBC)
1717
if (COMPILER_RT_USE_BUILTINS_LIBRARY)
1818
include(HandleCompilerRT)
19-
find_compiler_rt_library(builtins "" COMPILER_RT_BUILTINS_LIBRARY)
19+
cmake_push_check_state()
20+
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${SANITIZER_COMMON_FLAGS}")
21+
find_compiler_rt_library(builtins COMPILER_RT_BUILTINS_LIBRARY)
22+
cmake_pop_check_state()
2023
# TODO(PR51389): We should check COMPILER_RT_BUILTINS_LIBRARY and report an
2124
# error if the value is NOTFOUND rather than silenty continuing but we first
2225
# need to fix find_compiler_rt_library on Darwin.

compiler-rt/lib/builtins/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,9 @@ if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
1111
set(COMPILER_RT_BUILTINS_STANDALONE_BUILD TRUE)
1212
list(INSERT CMAKE_MODULE_PATH 0
1313
"${CMAKE_SOURCE_DIR}/../../cmake"
14-
"${CMAKE_SOURCE_DIR}/../../cmake/Modules")
14+
"${CMAKE_SOURCE_DIR}/../../cmake/Modules"
15+
"${CMAKE_SOURCE_DIR}/../../../cmake"
16+
"${CMAKE_SOURCE_DIR}/../../../cmake/Modules")
1517
include(base-config-ix)
1618
include(CompilerRTUtils)
1719

libcxx/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ cmake_minimum_required(VERSION 3.13.4)
1414
set(CMAKE_MODULE_PATH
1515
"${CMAKE_CURRENT_SOURCE_DIR}/cmake"
1616
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
17+
"${CMAKE_CURRENT_SOURCE_DIR}/../cmake"
18+
"${CMAKE_CURRENT_SOURCE_DIR}/../cmake/Modules"
1719
${CMAKE_MODULE_PATH}
1820
)
1921

libcxx/cmake/Modules/HandleCompilerRT.cmake

Lines changed: 0 additions & 64 deletions
This file was deleted.

libcxx/cmake/config-ix.cmake

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,10 @@ if (LIBCXX_SUPPORTS_NOSTDLIBXX_FLAG OR LIBCXX_SUPPORTS_NODEFAULTLIBS_FLAG)
4848
list(APPEND CMAKE_REQUIRED_LIBRARIES c)
4949
endif ()
5050
if (LIBCXX_USE_COMPILER_RT)
51-
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -rtlib=compiler-rt")
51+
cmake_push_check_state()
52+
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} ${LIBCXX_COMPILE_FLAGS}")
5253
find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
54+
cmake_pop_check_state()
5355
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBCXX_BUILTINS_LIBRARY}")
5456
elseif (LIBCXX_HAS_GCC_LIB)
5557
list(APPEND CMAKE_REQUIRED_LIBRARIES gcc)

libcxx/src/CMakeLists.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,8 @@ if (APPLE AND LLVM_USE_SANITIZER)
163163
message(WARNING "LLVM_USE_SANITIZER=${LLVM_USE_SANITIZER} is not supported on OS X")
164164
endif()
165165
if (LIBFILE)
166-
find_compiler_rt_dir(LIBDIR)
166+
find_compiler_rt_library(builtins LIBCXX_BUILTINS_LIBRARY)
167+
get_filename_component(LIBDIR "${LIBCXX_BUILTINS_LIBRARY}" DIRECTORY)
167168
if (NOT IS_DIRECTORY "${LIBDIR}")
168169
message(FATAL_ERROR "Cannot find compiler-rt directory on OS X required for LLVM_USE_SANITIZER")
169170
endif()

0 commit comments

Comments
 (0)