Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[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
- Loading branch information
Showing
9 changed files
with
195 additions
and
117 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
function(check_section_exists section output) | ||
cmake_parse_arguments(ARG "" "" "SOURCE;FLAGS" ${ARGN}) | ||
if(NOT ARG_SOURCE) | ||
set(ARG_SOURCE "int main() { return 0; }\n") | ||
endif() | ||
|
||
string(RANDOM TARGET_NAME) | ||
set(TARGET_NAME "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cmTC_${TARGET_NAME}.dir") | ||
file(MAKE_DIRECTORY ${TARGET_NAME}) | ||
|
||
file(WRITE "${TARGET_NAME}/CheckSectionExists.c" "${ARG_SOURCE}\n") | ||
|
||
string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions | ||
${CMAKE_C_COMPILE_OBJECT}) | ||
|
||
set(try_compile_flags "${ARG_FLAGS}") | ||
if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET) | ||
list(APPEND try_compile_flags "-target ${CMAKE_C_COMPILER_TARGET}") | ||
endif() | ||
append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto try_compile_flags) | ||
if(NOT COMPILER_RT_ENABLE_PGO) | ||
if(LLVM_PROFDATA_FILE AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG) | ||
list(APPEND try_compile_flags "-fno-profile-instr-use") | ||
endif() | ||
if(LLVM_BUILD_INSTRUMENTED MATCHES IR AND COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG) | ||
list(APPEND try_compile_flags "-fno-profile-generate") | ||
elseif((LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE) AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG) | ||
list(APPEND try_compile_flags "-fno-profile-instr-generate") | ||
if(LLVM_BUILD_INSTRUMENTED_COVERAGE AND COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG) | ||
list(APPEND try_compile_flags "-fno-coverage-mapping") | ||
endif() | ||
endif() | ||
endif() | ||
|
||
string(REPLACE ";" " " extra_flags "${try_compile_flags}") | ||
|
||
set(test_compile_command "${CMAKE_C_COMPILE_OBJECT}") | ||
foreach(substitution ${substitutions}) | ||
if(substitution STREQUAL "<CMAKE_C_COMPILER>") | ||
string(REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" | ||
test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<OBJECT>") | ||
string(REPLACE "<OBJECT>" "${TARGET_NAME}/CheckSectionExists.o" | ||
test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<SOURCE>") | ||
string(REPLACE "<SOURCE>" "${TARGET_NAME}/CheckSectionExists.c" | ||
test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<FLAGS>") | ||
string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_flags}" | ||
test_compile_command ${test_compile_command}) | ||
else() | ||
string(REPLACE "${substitution}" "" test_compile_command | ||
${test_compile_command}) | ||
endif() | ||
endforeach() | ||
|
||
# Strip quotes from the compile command, as the compiler is not expecting | ||
# quoted arguments (potential quotes added from D62063). | ||
string(REPLACE "\"" "" test_compile_command "${test_compile_command}") | ||
|
||
string(REPLACE " " ";" test_compile_command "${test_compile_command}") | ||
|
||
execute_process( | ||
COMMAND ${test_compile_command} | ||
RESULT_VARIABLE TEST_RESULT | ||
OUTPUT_VARIABLE TEST_OUTPUT | ||
ERROR_VARIABLE TEST_ERROR | ||
) | ||
|
||
# Explicitly throw a fatal error message if test_compile_command fails. | ||
if(TEST_RESULT) | ||
message(FATAL_ERROR "${TEST_ERROR}") | ||
return() | ||
endif() | ||
|
||
execute_process( | ||
COMMAND ${CMAKE_OBJDUMP} -h "${TARGET_NAME}/CheckSectionExists.o" | ||
RESULT_VARIABLE CHECK_RESULT | ||
OUTPUT_VARIABLE CHECK_OUTPUT | ||
ERROR_VARIABLE CHECK_ERROR | ||
) | ||
string(FIND "${CHECK_OUTPUT}" "${section}" SECTION_FOUND) | ||
|
||
if(NOT SECTION_FOUND EQUAL -1) | ||
set(${output} TRUE PARENT_SCOPE) | ||
else() | ||
set(${output} FALSE PARENT_SCOPE) | ||
endif() | ||
|
||
file(REMOVE_RECURSE ${TARGET_NAME}) | ||
endfunction() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
include(BuiltinTests) | ||
include(CheckCSourceCompiles) | ||
|
||
# Make all the tests only check the compiler | ||
set(TEST_COMPILE_ONLY On) | ||
|
||
builtin_check_c_compiler_flag(-fPIC COMPILER_RT_HAS_FPIC_FLAG) | ||
builtin_check_c_compiler_flag(-std=c11 COMPILER_RT_HAS_STD_C11_FLAG) | ||
builtin_check_c_compiler_flag(-Wno-pedantic COMPILER_RT_HAS_WNO_PEDANTIC) | ||
builtin_check_c_compiler_flag(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG) | ||
builtin_check_c_compiler_flag(-fno-profile-generate COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG) | ||
builtin_check_c_compiler_flag(-fno-profile-instr-generate COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG) | ||
builtin_check_c_compiler_flag(-fno-profile-instr-use COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG) | ||
|
||
if(ANDROID) | ||
set(OS_NAME "Android") | ||
else() | ||
set(OS_NAME "${CMAKE_SYSTEM_NAME}") | ||
endif() | ||
|
||
set(ARM64 aarch64) | ||
set(ARM32 arm armhf armv6m armv7m armv7em armv7 armv7s armv7k) | ||
set(X86 i386) | ||
set(X86_64 x86_64) | ||
set(RISCV32 riscv32) | ||
set(RISCV64 riscv64) | ||
set(VE ve) | ||
|
||
set(ALL_CRT_SUPPORTED_ARCH ${X86} ${X86_64} ${ARM32} ${ARM64} ${PPC32} | ||
${PPC64} ${RISCV32} ${RISCV64} ${VE} ${HEXAGON}) | ||
|
||
include(CompilerRTUtils) | ||
|
||
if(NOT APPLE) | ||
if(COMPILER_RT_CRT_STANDALONE_BUILD) | ||
test_targets() | ||
endif() | ||
# Architectures supported by compiler-rt crt library. | ||
filter_available_targets(CRT_SUPPORTED_ARCH ${ALL_CRT_SUPPORTED_ARCH}) | ||
message(STATUS "Supported architectures for crt: ${CRT_SUPPORTED_ARCH}") | ||
endif() | ||
|
||
if (CRT_SUPPORTED_ARCH AND OS_NAME MATCHES "Linux" AND NOT LLVM_USE_SANITIZER) | ||
set(COMPILER_RT_HAS_CRT TRUE) | ||
else() | ||
set(COMPILER_RT_HAS_CRT FALSE) | ||
endif() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,120 +1,63 @@ | ||
add_compiler_rt_component(crt) | ||
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) | ||
cmake_minimum_required(VERSION 3.13.4) | ||
|
||
function(check_cxx_section_exists section output) | ||
cmake_parse_arguments(ARG "" "" "SOURCE;FLAGS" ${ARGN}) | ||
if(NOT ARG_SOURCE) | ||
set(ARG_SOURCE "int main() { return 0; }\n") | ||
endif() | ||
|
||
string(RANDOM TARGET_NAME) | ||
set(TARGET_NAME "${CMAKE_BINARY_DIR}${CMAKE_FILES_DIRECTORY}/cmTC_${TARGET_NAME}.dir") | ||
file(MAKE_DIRECTORY ${TARGET_NAME}) | ||
|
||
file(WRITE "${TARGET_NAME}/CheckSectionExists.c" "${ARG_SOURCE}\n") | ||
set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) | ||
project(CompilerRTCRT C) | ||
set(COMPILER_RT_STANDALONE_BUILD TRUE) | ||
set(COMPILER_RT_CRT_STANDALONE_BUILD TRUE) | ||
|
||
string(REGEX MATCHALL "<[A-Za-z0-9_]*>" substitutions | ||
${CMAKE_C_COMPILE_OBJECT}) | ||
set(COMPILER_RT_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/../..") | ||
|
||
set(try_compile_flags "${ARG_FLAGS}") | ||
if(CMAKE_C_COMPILER_ID MATCHES Clang AND CMAKE_C_COMPILER_TARGET) | ||
list(APPEND try_compile_flags "-target ${CMAKE_C_COMPILER_TARGET}") | ||
endif() | ||
append_list_if(COMPILER_RT_HAS_FNO_LTO_FLAG -fno-lto try_compile_flags) | ||
if(NOT COMPILER_RT_ENABLE_PGO) | ||
if(LLVM_PROFDATA_FILE AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_USE_FLAG) | ||
list(APPEND try_compile_flags "-fno-profile-instr-use") | ||
endif() | ||
if(LLVM_BUILD_INSTRUMENTED MATCHES IR AND COMPILER_RT_HAS_FNO_PROFILE_GENERATE_FLAG) | ||
list(APPEND try_compile_flags "-fno-profile-generate") | ||
elseif((LLVM_BUILD_INSTRUMENTED OR LLVM_BUILD_INSTRUMENTED_COVERAGE) AND COMPILER_RT_HAS_FNO_PROFILE_INSTR_GENERATE_FLAG) | ||
list(APPEND try_compile_flags "-fno-profile-instr-generate") | ||
if(LLVM_BUILD_INSTRUMENTED_COVERAGE AND COMPILER_RT_HAS_FNO_COVERAGE_MAPPING_FLAG) | ||
list(APPEND try_compile_flags "-fno-coverage-mapping") | ||
endif() | ||
endif() | ||
endif() | ||
set(LLVM_COMMON_CMAKE_UTILS "${COMPILER_RT_SOURCE_DIR}/../cmake") | ||
|
||
string(REPLACE ";" " " extra_flags "${try_compile_flags}") | ||
# Add path for custom modules | ||
list(INSERT CMAKE_MODULE_PATH 0 | ||
"${COMPILER_RT_SOURCE_DIR}/cmake" | ||
"${COMPILER_RT_SOURCE_DIR}/cmake/Modules" | ||
"${LLVM_COMMON_CMAKE_UTILS}" | ||
"${LLVM_COMMON_CMAKE_UTILS}/Modules" | ||
) | ||
|
||
set(test_compile_command "${CMAKE_C_COMPILE_OBJECT}") | ||
foreach(substitution ${substitutions}) | ||
if(substitution STREQUAL "<CMAKE_C_COMPILER>") | ||
string(REPLACE "<CMAKE_C_COMPILER>" "${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}" | ||
test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<OBJECT>") | ||
string(REPLACE "<OBJECT>" "${TARGET_NAME}/CheckSectionExists.o" | ||
test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<SOURCE>") | ||
string(REPLACE "<SOURCE>" "${TARGET_NAME}/CheckSectionExists.c" | ||
test_compile_command ${test_compile_command}) | ||
elseif(substitution STREQUAL "<FLAGS>") | ||
string(REPLACE "<FLAGS>" "${CMAKE_C_FLAGS} ${extra_flags}" | ||
test_compile_command ${test_compile_command}) | ||
else() | ||
string(REPLACE "${substitution}" "" test_compile_command | ||
${test_compile_command}) | ||
endif() | ||
endforeach() | ||
include(base-config-ix) | ||
include(CompilerRTUtils) | ||
|
||
# Strip quotes from the compile command, as the compiler is not expecting | ||
# quoted arguments (potential quotes added from D62063). | ||
string(REPLACE "\"" "" test_compile_command "${test_compile_command}") | ||
load_llvm_config() | ||
construct_compiler_rt_default_triple() | ||
|
||
string(REPLACE " " ";" test_compile_command "${test_compile_command}") | ||
include(SetPlatformToolchainTools) | ||
include(AddCompilerRT) | ||
endif() | ||
|
||
execute_process( | ||
COMMAND ${test_compile_command} | ||
RESULT_VARIABLE TEST_RESULT | ||
OUTPUT_VARIABLE TEST_OUTPUT | ||
ERROR_VARIABLE TEST_ERROR | ||
) | ||
include(crt-config-ix) | ||
|
||
# Explicitly throw a fatal error message if test_compile_command fails. | ||
if(TEST_RESULT) | ||
message(FATAL_ERROR "${TEST_ERROR}") | ||
return() | ||
endif() | ||
if(COMPILER_RT_HAS_CRT) | ||
add_compiler_rt_component(crt) | ||
|
||
execute_process( | ||
COMMAND ${CMAKE_OBJDUMP} -h "${TARGET_NAME}/CheckSectionExists.o" | ||
RESULT_VARIABLE CHECK_RESULT | ||
OUTPUT_VARIABLE CHECK_OUTPUT | ||
ERROR_VARIABLE CHECK_ERROR | ||
) | ||
string(FIND "${CHECK_OUTPUT}" "${section}" SECTION_FOUND) | ||
include(CheckSectionExists) | ||
check_section_exists(".init_array" COMPILER_RT_HAS_INITFINI_ARRAY | ||
SOURCE "volatile int x;\n__attribute__((constructor)) void f() {x = 0;}\nint main() { return 0; }\n") | ||
|
||
if(NOT SECTION_FOUND EQUAL -1) | ||
set(${output} TRUE PARENT_SCOPE) | ||
else() | ||
set(${output} FALSE PARENT_SCOPE) | ||
append_list_if(COMPILER_RT_HAS_STD_C11_FLAG -std=c11 CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_HAS_INITFINI_ARRAY -DCRT_HAS_INITFINI_ARRAY CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY -DEH_USE_FRAME_REGISTRY CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_HAS_WNO_PEDANTIC -Wno-pedantic CRT_CFLAGS) | ||
if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG) | ||
append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full CRT_CFLAGS) | ||
endif() | ||
|
||
file(REMOVE_RECURSE ${TARGET_NAME}) | ||
endfunction() | ||
|
||
check_cxx_section_exists(".init_array" COMPILER_RT_HAS_INITFINI_ARRAY | ||
SOURCE "volatile int x;\n__attribute__((constructor)) void f() {x = 0;}\nint main() { return 0; }\n") | ||
|
||
append_list_if(COMPILER_RT_HAS_STD_C11_FLAG -std=c11 CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_HAS_INITFINI_ARRAY -DCRT_HAS_INITFINI_ARRAY CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_CRT_USE_EH_FRAME_REGISTRY -DEH_USE_FRAME_REGISTRY CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC CRT_CFLAGS) | ||
append_list_if(COMPILER_RT_HAS_WNO_PEDANTIC -Wno-pedantic CRT_CFLAGS) | ||
if (COMPILER_RT_HAS_FCF_PROTECTION_FLAG) | ||
append_list_if(COMPILER_RT_ENABLE_CET -fcf-protection=full CRT_CFLAGS) | ||
foreach(arch ${CRT_SUPPORTED_ARCH}) | ||
add_compiler_rt_runtime(clang_rt.crtbegin | ||
OBJECT | ||
ARCHS ${arch} | ||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtbegin.c | ||
CFLAGS ${CRT_CFLAGS} | ||
PARENT_TARGET crt) | ||
add_compiler_rt_runtime(clang_rt.crtend | ||
OBJECT | ||
ARCHS ${arch} | ||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtend.c | ||
CFLAGS ${CRT_CFLAGS} | ||
PARENT_TARGET crt) | ||
endforeach() | ||
endif() | ||
|
||
foreach(arch ${CRT_SUPPORTED_ARCH}) | ||
add_compiler_rt_runtime(clang_rt.crtbegin | ||
OBJECT | ||
ARCHS ${arch} | ||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtbegin.c | ||
CFLAGS ${CRT_CFLAGS} | ||
PARENT_TARGET crt) | ||
add_compiler_rt_runtime(clang_rt.crtend | ||
OBJECT | ||
ARCHS ${arch} | ||
SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/crtend.c | ||
CFLAGS ${CRT_CFLAGS} | ||
PARENT_TARGET crt) | ||
endforeach() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
include(crt-config-ix) | ||
|
||
set(CRT_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) | ||
|
||
set(CRT_TESTSUITES) | ||
|