Skip to content

Commit b0e2ffe

Browse files
committed
[CMake][compiler-rt] Make CRT separately buildable
This is useful when building a complete toolchain to ensure that CRT is built after builtins but before the rest of the compiler-rt. Differential Revision: https://reviews.llvm.org/D120682
1 parent ec2de74 commit b0e2ffe

File tree

9 files changed

+210
-135
lines changed

9 files changed

+210
-135
lines changed

compiler-rt/cmake/Modules/AllSupportedArchDefs.cmake

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@ set(ALL_SANITIZER_COMMON_SUPPORTED_ARCH ${X86} ${X86_64} ${PPC64} ${RISCV64}
2727
${HEXAGON})
2828
set(ALL_ASAN_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${RISCV64}
2929
${MIPS32} ${MIPS64} ${PPC64} ${S390X} ${SPARC} ${SPARCV9} ${HEXAGON})
30-
set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32}
31-
${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON})
3230
set(ALL_DFSAN_SUPPORTED_ARCH ${X86_64} ${MIPS64} ${ARM64})
3331

3432
if(ANDROID)
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
function(check_section_exists section output)
2+
cmake_parse_arguments(ARG "" "" "SOURCE;FLAGS" ${ARGN})
3+
if(NOT ARG_SOURCE)
4+
set(ARG_SOURCE "int main() { return 0; }\n")
5+
endif()
6+
7+
string(RANDOM TARGET_NAME)
8+
set(TARGET_NAME "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cmTC_${TARGET_NAME}.dir")
9+
file(MAKE_DIRECTORY ${TARGET_NAME})
10+
11+
file(WRITE "${TARGET_NAME}/CheckSectionExists.c" "${ARG_SOURCE}\n")
12+
13+
string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions
14+
${CMAKE_C_COMPILE_OBJECT})
15+
16+
set(try_compile_flags "${ARG_FLAGS}")
17+
if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET)
18+
list(APPEND try_compile_flags "-target ${CMAKE_C_COMPILER_TARGET}")
19+
endif()
20+
append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto try_compile_flags)
21+
if(NOT COMPILER_RT_ENABLE_PGO)
22+
if(LLVM_PROFDATA_FILE AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG)
23+
list(APPEND try_compile_flags "-fno-profile-instr-use")
24+
endif()
25+
if(LLVM_BUILD_INSTRUMENTED MATCHES IR AND COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG)
26+
list(APPEND try_compile_flags "-fno-profile-generate")
27+
elseif((LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE) AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG)
28+
list(APPEND try_compile_flags "-fno-profile-instr-generate")
29+
if(LLVM_BUILD_INSTRUMENTED_COVERAGE AND COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG)
30+
list(APPEND try_compile_flags "-fno-coverage-mapping")
31+
endif()
32+
endif()
33+
endif()
34+
35+
string(REPLACE ";" " " extra_flags "${try_compile_flags}")
36+
37+
set(test_compile_command "${CMAKE_C_COMPILE_OBJECT}")
38+
foreach(substitution ${substitutions})
39+
if(substitution STREQUAL "<CMAKE_C_COMPILER>")
40+
string(REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"
41+
test_compile_command ${test_compile_command})
42+
elseif(substitution STREQUAL "<OBJECT>")
43+
string(REPLACE "<OBJECT>" "${TARGET_NAME}/CheckSectionExists.o"
44+
test_compile_command ${test_compile_command})
45+
elseif(substitution STREQUAL "<SOURCE>")
46+
string(REPLACE "<SOURCE>" "${TARGET_NAME}/CheckSectionExists.c"
47+
test_compile_command ${test_compile_command})
48+
elseif(substitution STREQUAL "<FLAGS>")
49+
string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_flags}"
50+
test_compile_command ${test_compile_command})
51+
else()
52+
string(REPLACE "${substitution}" "" test_compile_command
53+
${test_compile_command})
54+
endif()
55+
endforeach()
56+
57+
# Strip quotes from the compile command, as the compiler is not expecting
58+
# quoted arguments (potential quotes added from D62063).
59+
string(REPLACE "\"" "" test_compile_command "${test_compile_command}")
60+
61+
string(REPLACE " " ";" test_compile_command "${test_compile_command}")
62+
63+
execute_process(
64+
COMMAND ${test_compile_command}
65+
RESULT_VARIABLE TEST_RESULT
66+
OUTPUT_VARIABLE TEST_OUTPUT
67+
ERROR_VARIABLE TEST_ERROR
68+
)
69+
70+
# Explicitly throw a fatal error message if test_compile_command fails.
71+
if(TEST_RESULT)
72+
message(FATAL_ERROR "${TEST_ERROR}")
73+
return()
74+
endif()
75+
76+
execute_process(
77+
COMMAND ${CMAKE_OBJDUMP} -h "${TARGET_NAME}/CheckSectionExists.o"
78+
RESULT_VARIABLE CHECK_RESULT
79+
OUTPUT_VARIABLE CHECK_OUTPUT
80+
ERROR_VARIABLE CHECK_ERROR
81+
)
82+
string(FIND "${CHECK_OUTPUT}" "${section}" SECTION_FOUND)
83+
84+
if(NOT SECTION_FOUND EQUAL -1)
85+
set(${output} TRUE PARENT_SCOPE)
86+
else()
87+
set(${output} FALSE PARENT_SCOPE)
88+
endif()
89+
90+
file(REMOVE_RECURSE ${TARGET_NAME})
91+
endfunction()

compiler-rt/cmake/Modules/CompilerRTUtils.cmake

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,10 @@ function(get_compiler_rt_root_source_dir ROOT_DIR_VAR)
238238
# Compiler-RT Builtins standalone build.
239239
# `llvm-project/compiler-rt/lib/builtins`
240240
set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CompilerRTBuiltins_SOURCE_DIR}/../../")
241+
elseif (DEFINED CompilerRTCRT_SOURCE_DIR)
242+
# Compiler-RT CRT standalone build.
243+
# `llvm-project/compiler-rt/lib/crt`
244+
set(PATH_TO_COMPILER_RT_SOURCE_ROOT "${CompilerRTCRT_SOURCE_DIR}/../../")
241245
elseif(DEFINED CompilerRT_SOURCE_DIR)
242246
# Compiler-RT standalone build.
243247
# `llvm-project/compiler-rt`

compiler-rt/cmake/config-ix.cmake

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -612,7 +612,6 @@ if(APPLE)
612612
SANITIZER_COMMON_SUPPORTED_ARCH)
613613

614614
else()
615-
filter_available_targets(CRT_SUPPORTED_ARCH ${ALL_CRT_SUPPORTED_ARCH})
616615
# Architectures supported by compiler-rt libraries.
617616
filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH
618617
${ALL_SANITIZER_COMMON_SUPPORTED_ARCH})
@@ -709,12 +708,6 @@ endif()
709708

710709
# TODO: Add builtins support.
711710

712-
if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER)
713-
set(COMPILER_RT_HAS_CRT TRUE)
714-
else()
715-
set(COMPILER_RT_HAS_CRT FALSE)
716-
endif()
717-
718711
if (COMPILER_RT_HAS_SANITIZER_COMMON AND DFSAN_SUPPORTED_ARCH AND
719712
OS_NAME MATCHES "Linux")
720713
set(COMPILER_RT_HAS_DFSAN TRUE)

compiler-rt/cmake/crt-config-ix.cmake

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
include(BuiltinTests)
2+
include(CheckCSourceCompiles)
3+
4+
# Make all the tests only check the compiler
5+
set(TEST_COMPILE_ONLY On)
6+
7+
builtin_check_c_compiler_flag(-fPIC COMPILER_RT_HAS_FPIC_FLAG)
8+
builtin_check_c_compiler_flag(-std=c11 COMPILER_RT_HAS_STD_C11_FLAG)
9+
builtin_check_c_compiler_flag(-Wno-pedantic COMPILER_RT_HAS_WNO_PEDANTIC)
10+
builtin_check_c_compiler_flag(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG)
11+
builtin_check_c_compiler_flag(-fno-profile-generate COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG)
12+
builtin_check_c_compiler_flag(-fno-profile-instr-generate COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG)
13+
builtin_check_c_compiler_flag(-fno-profile-instr-use COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG)
14+
15+
if(ANDROID)
16+
set(OS_NAME "Android")
17+
else()
18+
set(OS_NAME "${CMAKE_SYSTEM_NAME}")
19+
endif()
20+
21+
set(ARM64 aarch64)
22+
set(ARM32 arm armhf armv6m armv7m armv7em armv7 armv7s armv7k)
23+
set(X86 i386)
24+
set(X86_64 x86_64)
25+
set(RISCV32 riscv32)
26+
set(RISCV64 riscv64)
27+
set(VE ve)
28+
29+
set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32}
30+
${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON})
31+
32+
include(CompilerRTUtils)
33+
34+
if(NOT APPLE)
35+
if(COMPILER_RT_CRT_STANDALONE_BUILD)
36+
test_targets()
37+
endif()
38+
# Architectures supported by compiler-rt crt library.
39+
filter_available_targets(CRT_SUPPORTED_ARCH ${ALL_CRT_SUPPORTED_ARCH})
40+
message(STATUS "Supported architectures for crt: ${CRT_SUPPORTED_ARCH}")
41+
endif()
42+
43+
if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER)
44+
set(COMPILER_RT_HAS_CRT TRUE)
45+
else()
46+
set(COMPILER_RT_HAS_CRT FALSE)
47+
endif()

compiler-rt/lib/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ if(COMPILER_RT_BUILD_BUILTINS)
1717
add_subdirectory(builtins)
1818
endif()
1919

20-
if(COMPILER_RT_BUILD_CRT AND COMPILER_RT_HAS_CRT)
20+
if(COMPILER_RT_BUILD_CRT)
2121
add_subdirectory(crt)
2222
endif()
2323

compiler-rt/lib/crt/CMakeLists.txt

Lines changed: 49 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -1,120 +1,63 @@
1-
add_compiler_rt_component(crt)
1+
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
2+
cmake_minimum_required(VERSION 3.13.4)
23

3-
function(check_cxx_section_exists section output)
4-
cmake_parse_arguments(ARG "" "" "SOURCE;FLAGS" ${ARGN})
5-
if(NOT ARG_SOURCE)
6-
set(ARG_SOURCE "int main() { return 0; }\n")
7-
endif()
8-
9-
string(RANDOM TARGET_NAME)
10-
set(TARGET_NAME "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cmTC_${TARGET_NAME}.dir")
11-
file(MAKE_DIRECTORY ${TARGET_NAME})
12-
13-
file(WRITE "${TARGET_NAME}/CheckSectionExists.c" "${ARG_SOURCE}\n")
4+
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY)
5+
project(CompilerRTCRT C)
6+
set(COMPILER_RT_STANDALONE_BUILD TRUE)
7+
set(COMPILER_RT_CRT_STANDALONE_BUILD TRUE)
148

15-
string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions
16-
${CMAKE_C_COMPILE_OBJECT})
9+
set(COMPILER_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..")
1710

18-
set(try_compile_flags "${ARG_FLAGS}")
19-
if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET)
20-
list(APPEND try_compile_flags "-target ${CMAKE_C_COMPILER_TARGET}")
21-
endif()
22-
append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto try_compile_flags)
23-
if(NOT COMPILER_RT_ENABLE_PGO)
24-
if(LLVM_PROFDATA_FILE AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG)
25-
list(APPEND try_compile_flags "-fno-profile-instr-use")
26-
endif()
27-
if(LLVM_BUILD_INSTRUMENTED MATCHES IR AND COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG)
28-
list(APPEND try_compile_flags "-fno-profile-generate")
29-
elseif((LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE) AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG)
30-
list(APPEND try_compile_flags "-fno-profile-instr-generate")
31-
if(LLVM_BUILD_INSTRUMENTED_COVERAGE AND COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG)
32-
list(APPEND try_compile_flags "-fno-coverage-mapping")
33-
endif()
34-
endif()
35-
endif()
11+
set(LLVM_COMMON_CMAKE_UTILS "${COMPILER_RT_SOURCE_DIR}/../cmake")
3612

37-
string(REPLACE ";" " " extra_flags "${try_compile_flags}")
13+
# Add path for custom modules
14+
list(INSERT CMAKE_MODULE_PATH 0
15+
"${COMPILER_RT_SOURCE_DIR}/cmake"
16+
"${COMPILER_RT_SOURCE_DIR}/cmake/Modules"
17+
"${LLVM_COMMON_CMAKE_UTILS}"
18+
"${LLVM_COMMON_CMAKE_UTILS}/Modules"
19+
)
3820

39-
set(test_compile_command "${CMAKE_C_COMPILE_OBJECT}")
40-
foreach(substitution ${substitutions})
41-
if(substitution STREQUAL "<CMAKE_C_COMPILER>")
42-
string(REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"
43-
test_compile_command ${test_compile_command})
44-
elseif(substitution STREQUAL "<OBJECT>")
45-
string(REPLACE "<OBJECT>" "${TARGET_NAME}/CheckSectionExists.o"
46-
test_compile_command ${test_compile_command})
47-
elseif(substitution STREQUAL "<SOURCE>")
48-
string(REPLACE "<SOURCE>" "${TARGET_NAME}/CheckSectionExists.c"
49-
test_compile_command ${test_compile_command})
50-
elseif(substitution STREQUAL "<FLAGS>")
51-
string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_flags}"
52-
test_compile_command ${test_compile_command})
53-
else()
54-
string(REPLACE "${substitution}" "" test_compile_command
55-
${test_compile_command})
56-
endif()
57-
endforeach()
21+
include(base-config-ix)
22+
include(CompilerRTUtils)
5823

59-
# Strip quotes from the compile command, as the compiler is not expecting
60-
# quoted arguments (potential quotes added from D62063).
61-
string(REPLACE "\"" "" test_compile_command "${test_compile_command}")
24+
load_llvm_config()
25+
construct_compiler_rt_default_triple()
6226

63-
string(REPLACE " " ";" test_compile_command "${test_compile_command}")
27+
include(SetPlatformToolchainTools)
28+
include(AddCompilerRT)
29+
endif()
6430

65-
execute_process(
66-
COMMAND ${test_compile_command}
67-
RESULT_VARIABLE TEST_RESULT
68-
OUTPUT_VARIABLE TEST_OUTPUT
69-
ERROR_VARIABLE TEST_ERROR
70-
)
31+
include(crt-config-ix)
7132

72-
# Explicitly throw a fatal error message if test_compile_command fails.
73-
if(TEST_RESULT)
74-
message(FATAL_ERROR "${TEST_ERROR}")
75-
return()
76-
endif()
33+
if(COMPILER_RT_HAS_CRT)
34+
add_compiler_rt_component(crt)
7735

78-
execute_process(
79-
COMMAND ${CMAKE_OBJDUMP} -h "${TARGET_NAME}/CheckSectionExists.o"
80-
RESULT_VARIABLE CHECK_RESULT
81-
OUTPUT_VARIABLE CHECK_OUTPUT
82-
ERROR_VARIABLE CHECK_ERROR
83-
)
84-
string(FIND "${CHECK_OUTPUT}" "${section}" SECTION_FOUND)
36+
include(CheckSectionExists)
37+
check_section_exists(".init_array" COMPILER_RT_HAS_INITFINI_ARRAY
38+
SOURCE "volatile int x;\n__attribute__((constructor)) void f() {x = 0;}\nint main() { return 0; }\n")
8539

86-
if(NOT SECTION_FOUND EQUAL -1)
87-
set(${output} TRUE PARENT_SCOPE)
88-
else()
89-
set(${output} FALSE PARENT_SCOPE)
40+
append_list_if(COMPILER_RT_HAS_STD_C11_FLAG -std=c11 CRT_CFLAGS)
41+
append_list_if(COMPILER_RT_HAS_INITFINI_ARRAY -DCRT_HAS_INITFINI_ARRAY CRT_CFLAGS)
42+
append_list_if(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY -DEH_USE_FRAME_REGISTRY CRT_CFLAGS)
43+
append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC CRT_CFLAGS)
44+
append_list_if(COMPILER_RT_HAS_WNO_PEDANTIC -Wno-pedantic CRT_CFLAGS)
45+
if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG)
46+
append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full CRT_CFLAGS)
9047
endif()
9148

92-
file(REMOVE_RECURSE ${TARGET_NAME})
93-
endfunction()
94-
95-
check_cxx_section_exists(".init_array" COMPILER_RT_HAS_INITFINI_ARRAY
96-
SOURCE "volatile int x;\n__attribute__((constructor)) void f() {x = 0;}\nint main() { return 0; }\n")
97-
98-
append_list_if(COMPILER_RT_HAS_STD_C11_FLAG -std=c11 CRT_CFLAGS)
99-
append_list_if(COMPILER_RT_HAS_INITFINI_ARRAY -DCRT_HAS_INITFINI_ARRAY CRT_CFLAGS)
100-
append_list_if(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY -DEH_USE_FRAME_REGISTRY CRT_CFLAGS)
101-
append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC CRT_CFLAGS)
102-
append_list_if(COMPILER_RT_HAS_WNO_PEDANTIC -Wno-pedantic CRT_CFLAGS)
103-
if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG)
104-
append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full CRT_CFLAGS)
49+
foreach(arch ${CRT_SUPPORTED_ARCH})
50+
add_compiler_rt_runtime(clang_rt.crtbegin
51+
OBJECT
52+
ARCHS ${arch}
53+
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtbegin.c
54+
CFLAGS ${CRT_CFLAGS}
55+
PARENT_TARGET crt)
56+
add_compiler_rt_runtime(clang_rt.crtend
57+
OBJECT
58+
ARCHS ${arch}
59+
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtend.c
60+
CFLAGS ${CRT_CFLAGS}
61+
PARENT_TARGET crt)
62+
endforeach()
10563
endif()
106-
107-
foreach(arch ${CRT_SUPPORTED_ARCH})
108-
add_compiler_rt_runtime(clang_rt.crtbegin
109-
OBJECT
110-
ARCHS ${arch}
111-
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtbegin.c
112-
CFLAGS ${CRT_CFLAGS}
113-
PARENT_TARGET crt)
114-
add_compiler_rt_runtime(clang_rt.crtend
115-
OBJECT
116-
ARCHS ${arch}
117-
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtend.c
118-
CFLAGS ${CRT_CFLAGS}
119-
PARENT_TARGET crt)
120-
endforeach()

compiler-rt/test/CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ if(COMPILER_RT_CAN_EXECUTE_TESTS)
9292
if(COMPILER_RT_BUILD_ORC)
9393
compiler_rt_Test_runtime(orc)
9494
endif()
95-
if(COMPILER_RT_BUILD_CRT AND COMPILER_RT_HAS_CRT)
95+
if(COMPILER_RT_BUILD_CRT)
9696
add_subdirectory(crt)
9797
endif()
9898
# ShadowCallStack does not yet provide a runtime with compiler-rt, the tests

0 commit comments

Comments
 (0)