2019-05-30 13:38:06 +08:00
|
|
|
include(CMakePushCheckState)
|
2015-04-25 09:46:35 +08:00
|
|
|
include(CheckCCompilerFlag)
|
|
|
|
include(CheckCXXCompilerFlag)
|
|
|
|
include(CheckLibraryExists)
|
[cmake] Partially deduplicate `{llvm,compiler_rt}_check_linker_flag` for runtime libs and llvm
We previously had a few varied definitions of this floating around.
I had tried to make the one installed with LLVM handle all the cases, and then made the others use it, but this ran into issues with `HandleOutOfTreeLLVM` not working for compiler-rt, and also `CMAKE_EXE_LINKER_FLAGS` not working right without `CMP0056` set to the new behavior.
My compromise solution is this:
- No not completely deduplicate: the runtime libs will instead use a version that still exists as part of the internal and not installed common shared CMake utilities. This avoids `HandleOutOfTreeLLVM` or a workaround for compiler-rt.
- Continue to use `CMAKE_REQUIRED_FLAGS`, which effects compilation and linking. Maybe this is unnecessary, but it's safer to leave that as a future change. Also means we can avoid `CMP0056` for now, to try out later, which is good incrementality too.
- Call it `llvm_check_compiler_linker_flag` since it, in fact is about both per its implementation (before and after this patch), so there is no name collision.
In the future, we might still enable CMP0056 and make compiler-rt work with HandleOutOfTreeLLVM, which case we delete `llvm_check_compiler_flag` and go back to the old way (as these are, in fact, linking related flags), but that I leave for someone else as future work.
The original issue was reported to me in https://reviews.llvm.org/D116521#3248117 as
D116521 made clang and LLVM use the common cmake utils.
Reviewed By: sebastian-ne, phosek, #libunwind, #libc, #libc_abi, ldionne
Differential Revision: https://reviews.llvm.org/D117537
2022-01-22 08:21:19 +08:00
|
|
|
include(LLVMCheckCompilerLinkerFlag)
|
2019-12-06 22:26:35 +08:00
|
|
|
include(CheckSymbolExists)
|
2019-05-30 12:40:21 +08:00
|
|
|
include(CheckCSourceCompiles)
|
2015-04-25 09:46:35 +08:00
|
|
|
|
2021-09-11 03:14:48 +08:00
|
|
|
# The compiler driver may be implicitly trying to link against libunwind, which
|
|
|
|
# might not work if libunwind doesn't exist yet. Try to check if
|
|
|
|
# --unwindlib=none is supported, and use that if possible.
|
2022-03-10 17:47:09 +08:00
|
|
|
llvm_check_compiler_linker_flag(C "--unwindlib=none" CXX_SUPPORTS_UNWINDLIB_EQ_NONE_FLAG)
|
2021-09-11 03:14:48 +08:00
|
|
|
|
2019-01-29 03:26:41 +08:00
|
|
|
check_library_exists(c fopen "" LIBUNWIND_HAS_C_LIB)
|
2017-04-12 10:28:07 +08:00
|
|
|
|
|
|
|
if (NOT LIBUNWIND_USE_COMPILER_RT)
|
2020-04-24 12:19:11 +08:00
|
|
|
if (ANDROID)
|
|
|
|
check_library_exists(gcc __gcc_personality_v0 "" LIBUNWIND_HAS_GCC_LIB)
|
|
|
|
else ()
|
|
|
|
check_library_exists(gcc_s __gcc_personality_v0 "" LIBUNWIND_HAS_GCC_S_LIB)
|
|
|
|
check_library_exists(gcc __absvdi2 "" LIBUNWIND_HAS_GCC_LIB)
|
|
|
|
endif ()
|
2017-04-12 10:28:07 +08:00
|
|
|
endif()
|
|
|
|
|
2021-02-17 02:02:22 +08:00
|
|
|
# libunwind is using -nostdlib++ at the link step when available,
|
|
|
|
# otherwise -nodefaultlibs is used. We want all our checks to also
|
|
|
|
# use one of these options, otherwise we may end up with an inconsistency between
|
2017-04-12 10:28:07 +08:00
|
|
|
# the flags we think we require during configuration (if the checks are
|
2021-02-17 02:02:22 +08:00
|
|
|
# performed without one of those options) and the flags that are actually
|
|
|
|
# required during compilation (which has the -nostdlib++ or -nodefaultlibs). libc is
|
2017-04-12 10:28:07 +08:00
|
|
|
# required for the link to go through. We remove sanitizers from the
|
|
|
|
# configuration checks to avoid spurious link errors.
|
2021-02-17 02:02:22 +08:00
|
|
|
|
2022-03-10 17:47:09 +08:00
|
|
|
llvm_check_compiler_linker_flag(C "-nostdlib++" CXX_SUPPORTS_NOSTDLIBXX_FLAG)
|
|
|
|
if (CXX_SUPPORTS_NOSTDLIBXX_FLAG)
|
2021-02-17 02:02:22 +08:00
|
|
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nostdlib++")
|
|
|
|
else()
|
2022-05-26 22:03:08 +08:00
|
|
|
llvm_check_compiler_linker_flag(C "-nodefaultlibs" C_SUPPORTS_NODEFAULTLIBS_FLAG)
|
2022-03-10 17:47:09 +08:00
|
|
|
if (C_SUPPORTS_NODEFAULTLIBS_FLAG)
|
2021-02-17 02:02:22 +08:00
|
|
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -nodefaultlibs")
|
|
|
|
endif()
|
|
|
|
endif()
|
|
|
|
|
2022-03-10 17:47:09 +08:00
|
|
|
if (CXX_SUPPORTS_NOSTDLIBXX_FLAG OR C_SUPPORTS_NODEFAULTLIBS_FLAG)
|
2017-04-12 10:28:07 +08:00
|
|
|
if (LIBUNWIND_HAS_C_LIB)
|
|
|
|
list(APPEND CMAKE_REQUIRED_LIBRARIES c)
|
|
|
|
endif ()
|
|
|
|
if (LIBUNWIND_USE_COMPILER_RT)
|
2020-09-29 08:37:20 +08:00
|
|
|
include(HandleCompilerRT)
|
|
|
|
find_compiler_rt_library(builtins LIBUNWIND_BUILTINS_LIBRARY
|
|
|
|
FLAGS ${LIBUNWIND_COMPILE_FLAGS})
|
2017-04-12 10:28:07 +08:00
|
|
|
list(APPEND CMAKE_REQUIRED_LIBRARIES "${LIBUNWIND_BUILTINS_LIBRARY}")
|
2018-10-09 02:35:00 +08:00
|
|
|
else ()
|
|
|
|
if (LIBUNWIND_HAS_GCC_S_LIB)
|
|
|
|
list(APPEND CMAKE_REQUIRED_LIBRARIES gcc_s)
|
|
|
|
endif ()
|
|
|
|
if (LIBUNWIND_HAS_GCC_LIB)
|
|
|
|
list(APPEND CMAKE_REQUIRED_LIBRARIES gcc)
|
|
|
|
endif ()
|
2017-04-12 10:28:07 +08:00
|
|
|
endif ()
|
2017-10-03 04:46:37 +08:00
|
|
|
if (MINGW)
|
|
|
|
# Mingw64 requires quite a few "C" runtime libraries in order for basic
|
|
|
|
# programs to link successfully with -nodefaultlibs.
|
|
|
|
if (LIBUNWIND_USE_COMPILER_RT)
|
|
|
|
set(MINGW_RUNTIME ${LIBUNWIND_BUILTINS_LIBRARY})
|
|
|
|
else ()
|
|
|
|
set(MINGW_RUNTIME gcc_s gcc)
|
|
|
|
endif()
|
|
|
|
set(MINGW_LIBRARIES mingw32 ${MINGW_RUNTIME} moldname mingwex msvcrt advapi32
|
|
|
|
shell32 user32 kernel32 mingw32 ${MINGW_RUNTIME}
|
|
|
|
moldname mingwex msvcrt)
|
|
|
|
list(APPEND CMAKE_REQUIRED_LIBRARIES ${MINGW_LIBRARIES})
|
|
|
|
endif()
|
2017-04-12 10:28:07 +08:00
|
|
|
if (CMAKE_C_FLAGS MATCHES -fsanitize OR CMAKE_CXX_FLAGS MATCHES -fsanitize)
|
|
|
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fno-sanitize=all")
|
|
|
|
endif ()
|
|
|
|
if (CMAKE_C_FLAGS MATCHES -fsanitize-coverage OR CMAKE_CXX_FLAGS MATCHES -fsanitize-coverage)
|
[libc++] Disable coverage with sanitize-coverage=0
When building libcxx, libcxxabi, and libunwind the build environment may
specify any number of sanitizers. For some build feature tests these
sanitizers must be disabled to prevent spurious linking errors. With
-fsanitize= this is straight forward with -fno-sanitize=all. With
-fsanitize-coverage= there is no -fno-sanitize-coverage=all, but there
is the equivalent undocumented but tested -fsanitize-coverage=0.
The current build rules fail to disable 'trace-pc-guard'. By disabling
all sanitize-coverage flags, including 'trace-pc-guard', possible
spurious linker errors are prevented. In particular, this allows libcxx,
libcxxabi, and libunwind to be built with HonggFuzz.
CMAKE_REQUIRED_FLAGS is extra compile flags when running CMake build
configuration steps (like check_cxx_compiler_flag). It does not affect
the compile flags for the actual build of the project (unless of course
these flags change whether or not a given source compiles and links or
not). So libcxx, libcxxabi, and libunwind will still be built with any
specified sanitize-coverage as before. The build configuration steps
(which are mostly checking to see if certain compiler flags are
available) will not try to compile and link "int main() { return 0;}"
(or other specified source) with sanitize-coverage (which can fail to
link at this stage in building, since the final compile flags required
are yet to be determined).
The change to LIBFUZZER_CFLAGS was done to keep it consistent with the
obvious intention of disabling all sanitize-coverage. This appears to
be intentional, preventing the fuzzer driver itself from showing up in
any coverage calculations.
Reviewed By: #libunwind, #libc, #libc_abi, ldionne, phosek
Differential Revision: https://reviews.llvm.org/D116050
2022-01-08 09:34:05 +08:00
|
|
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -fsanitize-coverage=0")
|
2017-04-12 10:28:07 +08:00
|
|
|
endif ()
|
|
|
|
endif ()
|
|
|
|
|
2019-05-30 12:40:21 +08:00
|
|
|
# Check compiler pragmas
|
|
|
|
if(CMAKE_CXX_COMPILER_ID MATCHES "Clang")
|
2019-05-30 13:38:06 +08:00
|
|
|
cmake_push_check_state()
|
|
|
|
set(CMAKE_REQUIRED_FLAGS "${CMAKE_REQUIRED_FLAGS} -Werror=unknown-pragmas")
|
2019-05-30 12:40:21 +08:00
|
|
|
check_c_source_compiles("
|
|
|
|
#pragma comment(lib, \"c\")
|
|
|
|
int main() { return 0; }
|
2022-03-10 17:47:09 +08:00
|
|
|
" C_SUPPORTS_COMMENT_LIB_PRAGMA)
|
2019-05-30 13:38:06 +08:00
|
|
|
cmake_pop_check_state()
|
2019-05-30 12:40:21 +08:00
|
|
|
endif()
|
|
|
|
|
2015-04-25 09:46:35 +08:00
|
|
|
# Check compiler flags
|
2022-03-10 17:47:09 +08:00
|
|
|
check_cxx_compiler_flag(-nostdinc++ CXX_SUPPORTS_NOSTDINCXX_FLAG)
|
2015-04-25 09:46:35 +08:00
|
|
|
|
2019-12-06 22:26:35 +08:00
|
|
|
# Check symbols
|
|
|
|
check_symbol_exists(__arm__ "" LIBUNWIND_TARGET_ARM)
|
|
|
|
check_symbol_exists(__USING_SJLJ_EXCEPTIONS__ "" LIBUNWIND_USES_SJLJ_EXCEPTIONS)
|
|
|
|
check_symbol_exists(__ARM_DWARF_EH__ "" LIBUNWIND_USES_DWARF_EH)
|
|
|
|
|
|
|
|
if(LIBUNWIND_TARGET_ARM AND NOT LIBUNWIND_USES_SJLJ_EXCEPTIONS AND NOT LIBUNWIND_USES_DWARF_EH)
|
|
|
|
# This condition is copied from __libunwind_config.h
|
|
|
|
set(LIBUNWIND_USES_ARM_EHABI ON)
|
|
|
|
endif()
|
2019-12-18 09:18:24 +08:00
|
|
|
|
|
|
|
# Check libraries
|
|
|
|
if(FUCHSIA)
|
|
|
|
set(LIBUNWIND_HAS_DL_LIB NO)
|
|
|
|
set(LIBUNWIND_HAS_PTHREAD_LIB NO)
|
|
|
|
else()
|
|
|
|
check_library_exists(dl dladdr "" LIBUNWIND_HAS_DL_LIB)
|
|
|
|
check_library_exists(pthread pthread_once "" LIBUNWIND_HAS_PTHREAD_LIB)
|
|
|
|
endif()
|