From 7ac1f60f01a73f9678bba2385e933864ecce8622 Mon Sep 17 00:00:00 2001 From: ur4t <46435411+ur4t@users.noreply.github.com> Date: Tue, 19 Sep 2023 13:56:03 +0800 Subject: [PATCH] [llvm-libgcc][CMake] Refactor llvm-libgcc (#65455) There are some issues in `llvm-libgcc` before this patch: Commit c5a20b518203613497fa864867fc232648006068 ([llvm-libgcc] initial commit) uses `$` to get libunwind objects, which is empty. The built library is actually a shared version of libclang_rt.builtins. When configuring with `llvm/CMakeLists.txt`, target `llvm-libgcc` requires a corresponding target in `llvm-libgcc/CMakeLists.txt`. Per target installation is not handled by `llvm-libgcc`, which is not consistent with `libunwind`. This patch fixes those issues by: Reusing target `unwind_shared` in `libunwind`, linking `compiler-rt.builtins` objects into it, and applying version script. Adding target `llvm-libgcc`, creating symlinks, and utilizing cmake's dependency and component mechanism to ensure link targets will be built and installed along with symlinks. Mimicking `libunwind` to handle per target installation. It is quite hard to set necessary options without further modifying the order of runtime projects in `runtimes/CMakeLists.txt`. So though this patch reveals the possibility of co-existence of `llvm-libgcc` and `compiler-rt`/`libunwind` in `LLVM_ENABLE_RUNTIMES`, we still inhibit it to minimize influence on other projects, considering that `llvm-libgcc` is only intended for toolchain vendors, and not for casual use. --- llvm-libgcc/CMakeLists.txt | 153 +++++++++++++++++--- llvm-libgcc/{lib/gcc_s.ver => gcc_s.ver.in} | 0 llvm-libgcc/lib/CMakeLists.txt | 86 ----------- llvm-libgcc/lib/blank.c | 0 runtimes/CMakeLists.txt | 17 --- 5 files changed, 134 insertions(+), 122 deletions(-) rename llvm-libgcc/{lib/gcc_s.ver => gcc_s.ver.in} (100%) delete mode 100644 llvm-libgcc/lib/CMakeLists.txt delete mode 100644 llvm-libgcc/lib/blank.c diff --git a/llvm-libgcc/CMakeLists.txt b/llvm-libgcc/CMakeLists.txt index de42d908c371..013c9ca2e330 100644 --- a/llvm-libgcc/CMakeLists.txt +++ b/llvm-libgcc/CMakeLists.txt @@ -1,19 +1,38 @@ -cmake_minimum_required(VERSION 3.20.0) +#=============================================================================== +# Setup Project +#=============================================================================== -if (NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../libunwind") - message(FATAL_ERROR "llvm-libgcc requires being built in a monorepo layout with libunwind available") -endif() +cmake_minimum_required(VERSION 3.20.0) set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake") -list(APPEND CMAKE_MODULE_PATH +# Check if llvm-libgcc is built as a standalone project +if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR LLVM_LIBGCC_STANDALONE_BUILD) + project(llvm-libgcc LANGUAGES C CXX ASM) + set(COMPILER_RT_STANDALONE_BUILD ON) + set_property(GLOBAL PROPERTY USE_FOLDERS ON) + set(LLVM_LIBGCC_COMPILER_RT_BINARY_DIR "compiler-rt") + set(LLVM_LIBGCC_LIBUNWIND_BINARY_DIR "libunwind") +else() + set(LLVM_LIBGCC_COMPILER_RT_BINARY_DIR "../compiler-rt") + set(LLVM_LIBGCC_LIBUNWIND_BINARY_DIR "../libunwind") +endif() + +# Add path for custom modules +list(INSERT CMAKE_MODULE_PATH 0 "${CMAKE_CURRENT_SOURCE_DIR}/cmake" "${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules" + "${CMAKE_CURRENT_SOURCE_DIR}/../runtimes/cmake/Modules" "${LLVM_COMMON_CMAKE_UTILS}" "${LLVM_COMMON_CMAKE_UTILS}/Modules" - ) +) -project(llvm-libgcc LANGUAGES C CXX ASM) +set(LLVM_LIBGCC_LIBUNWIND_PATH "${CMAKE_CURRENT_LIST_DIR}/../libunwind" + CACHE PATH "Specify path to libunwind source.") +set(LLVM_LIBGCC_COMPILER_RT_PATH "${CMAKE_CURRENT_LIST_DIR}/../compiler-rt" + CACHE PATH "Specify path to compiler-rt source.") + +include(GNUInstallDirs) if(NOT LLVM_LIBGCC_EXPLICIT_OPT_IN) message(FATAL_ERROR @@ -25,18 +44,114 @@ if(NOT LLVM_LIBGCC_EXPLICIT_OPT_IN) "to your CMake invocation and try again.") endif() -set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib${LLVMLIB_DIR_SUFFIX}") -set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib${LLVMLIB_DIR_SUFFIX}") -set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin") +if(HAVE_COMPILER_RT) + message(FATAL_ERROR + "Attempting to build both compiler-rt and llvm-libgcc will cause irreconcilable " + "target clashes. Please choose one or the other, but not both.") +endif() -set(COMPILER_RT_BUILD_BUILTINS On) -set(COMPILER_RT_BUILTINS_HIDE_SYMBOLS Off) -add_subdirectory("../compiler-rt" "compiler-rt") +if(HAVE_LIBUNWIND) + message(FATAL_ERROR + "Attempting to build both libunwind and llvm-libgcc will cause irreconcilable " + "target clashes. Please choose one or the other, but not both.") +endif() -set(LIBUNWIND_ENABLE_STATIC On) -set(LIBUNWIND_ENABLE_SHARED Off) -set(LIBUNWIND_HAS_COMMENT_LIB_PRAGMA Off) -set(LIBUNWIND_USE_COMPILER_RT On) -add_subdirectory("../libunwind" "libunwind") +#=============================================================================== +# Configure System +#=============================================================================== -add_subdirectory(lib) +if(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR AND NOT APPLE) + set(LLVM_LIBGCC_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}/${LLVM_DEFAULT_TARGET_TRIPLE}) + set(LLVM_LIBGCC_INSTALL_LIBRARY_DIR lib${LLVM_LIBDIR_SUFFIX}/${LLVM_DEFAULT_TARGET_TRIPLE} CACHE PATH + "Path where built llvm-libgcc libraries should be installed.") + if(LIBCXX_LIBDIR_SUBDIR) + string(APPEND LLVM_LIBGCC_LIBRARY_DIR /${LLVM_LIBGCC_LIBDIR_SUBDIR}) + string(APPEND LLVM_LIBGCC_INSTALL_LIBRARY_DIR /${LLVM_LIBGCC_LIBDIR_SUBDIR}) + endif() +else() + if(LLVM_LIBRARY_OUTPUT_INTDIR) + set(LLVM_LIBGCC_LIBRARY_DIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) + else() + set(LLVM_LIBGCC_LIBRARY_DIR ${CMAKE_BINARY_DIR}/lib${LLVM_LIBGCC_LIBDIR_SUFFIX}) + endif() + set(LLVM_LIBGCC_INSTALL_LIBRARY_DIR lib${LLVM_LIBGCC_LIBDIR_SUFFIX} CACHE PATH + "Path where built llvm-libgcc libraries should be installed.") +endif() + +set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${LLVM_LIBGCC_LIBRARY_DIR}) +set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${LLVM_LIBGCC_LIBRARY_DIR}) +set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${LLVM_LIBGCC_LIBRARY_DIR}) + +#=============================================================================== +# Build libraries +#=============================================================================== + +set(COMPILER_RT_BUILD_BUILTINS ON) +set(COMPILER_RT_BUILTINS_HIDE_SYMBOLS OFF) +add_subdirectory(${LLVM_LIBGCC_COMPILER_RT_PATH} ${LLVM_LIBGCC_COMPILER_RT_BINARY_DIR}) + +set(LIBUNWIND_ENABLE_STATIC ON) +set(LIBUNWIND_ENABLE_SHARED ON) +set(LIBUNWIND_USE_COMPILER_RT OFF) +set(LIBUNWIND_HAS_GCC_LIB OFF) +set(LIBUNWIND_HAS_GCC_S_LIB OFF) +add_subdirectory(${LLVM_LIBGCC_LIBUNWIND_PATH} ${LLVM_LIBGCC_LIBUNWIND_BINARY_DIR}) + +add_custom_target(gcc_s.ver + SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/gcc_s.ver.in + COMMAND ${CMAKE_C_COMPILER} -E + -xc ${CMAKE_CURRENT_SOURCE_DIR}/gcc_s.ver.in + -o ${CMAKE_CURRENT_BINARY_DIR}/gcc_s.ver +) + +add_dependencies(unwind_shared gcc_s.ver) + +construct_compiler_rt_default_triple() + +target_link_options(unwind_shared PUBLIC + -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/gcc_s.ver +) + +target_link_libraries(unwind_shared PUBLIC + $ + m +) + +#=============================================================================== +# Install Symlinks +#=============================================================================== + +get_compiler_rt_install_dir(${COMPILER_RT_DEFAULT_TARGET_ARCH} install_dir_builtins) +string(REGEX REPLACE "^lib/" "" install_dir_builtins "${install_dir_builtins}") +string(FIND "${install_dir_builtins}" "clang" install_path_contains_triple) +if(install_path_contains_triple EQUAL -1) + set(builtins_suffix "-${COMPILER_RT_DEFAULT_TARGET_ARCH}") +else() + string(PREPEND install_dir_builtins "../") +endif() +set(LLVM_LIBGCC_COMPILER_RT ${install_dir_builtins}/libclang_rt.builtins${builtins_suffix}.a) + +add_custom_target(llvm-libgcc ALL + DEPENDS unwind_shared unwind_static clang_rt.builtins-${COMPILER_RT_DEFAULT_TARGET_ARCH} + COMMAND ${CMAKE_COMMAND} -E create_symlink ${LLVM_LIBGCC_COMPILER_RT} libgcc.a + COMMAND ${CMAKE_COMMAND} -E create_symlink libunwind.a libgcc_eh.a + COMMAND ${CMAKE_COMMAND} -E create_symlink libunwind.so libgcc_s.so.1.0 + COMMAND ${CMAKE_COMMAND} -E create_symlink libgcc_s.so.1.0 libgcc_s.so.1 + COMMAND ${CMAKE_COMMAND} -E create_symlink libgcc_s.so.1 libgcc_s.so +) + +install(TARGETS unwind_shared unwind_static + LIBRARY DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR} COMPONENT llvm-libgcc + ARCHIVE DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR} COMPONENT llvm-libgcc + RUNTIME DESTINATION ${LLVM_LIBGCC_INSTALL_RUNTIME_DIR} COMPONENT llvm-libgcc) + +install(TARGETS clang_rt.builtins-${COMPILER_RT_DEFAULT_TARGET_ARCH} + LIBRARY DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR}/${install_dir_builtins} COMPONENT llvm-libgcc + ARCHIVE DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR}/${install_dir_builtins} COMPONENT llvm-libgcc + RUNTIME DESTINATION ${LLVM_LIBGCC_INSTALL_RUNTIME_DIR}/${install_dir_builtins} COMPONENT llvm-libgcc) + +foreach(VAR libgcc.a libgcc_eh.a libgcc_s.so.1.0 libgcc_s.so.1 libgcc_s.so) + install(FILES ${CMAKE_CURRENT_BINARY_DIR}/${VAR} + DESTINATION ${LLVM_LIBGCC_INSTALL_LIBRARY_DIR} + COMPONENT llvm-libgcc) +endforeach() diff --git a/llvm-libgcc/lib/gcc_s.ver b/llvm-libgcc/gcc_s.ver.in similarity index 100% rename from llvm-libgcc/lib/gcc_s.ver rename to llvm-libgcc/gcc_s.ver.in diff --git a/llvm-libgcc/lib/CMakeLists.txt b/llvm-libgcc/lib/CMakeLists.txt deleted file mode 100644 index d895a21554b0..000000000000 --- a/llvm-libgcc/lib/CMakeLists.txt +++ /dev/null @@ -1,86 +0,0 @@ -include(CheckLibraryExists) -include(GNUInstallDirs) -include(ExtendPath) - -string(REPLACE "-Wl,-z,defs" "" CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS}") - -add_custom_target(gcc_s_ver ALL DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/gcc_s.ver") -set(LLVM_LIBGCC_GCC_S_VER "${CMAKE_CURRENT_BINARY_DIR}/gcc_s.ver") - -add_custom_target(gcc_s.ver ALL - DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/gcc_s.ver" - COMMAND - "${CMAKE_C_COMPILER}" - "-E" - "-xc" "${CMAKE_CURRENT_SOURCE_DIR}/gcc_s.ver" - "-o" "${CMAKE_CURRENT_BINARY_DIR}/gcc_s.ver" -) -set_target_properties(gcc_s.ver PROPERTIES - OUTPUT_PATH "${CMAKE_CURRENT_BINARY_DIR}/gcc_s.ver") - -add_library(libgcc_s SHARED blank.c) -add_dependencies(libgcc_s gcc_s_ver) -set_target_properties(libgcc_s - PROPERTIES - LINKER_LANGUAGE C - OUTPUT_NAME "unwind" - VERSION "1.0" - SOVERSION "1" - POSITION_INDEPENDENT_CODE ON) -string(REGEX MATCH "[^-]+" LLVM_LIBGCC_TARGET_ARCH ${CMAKE_C_COMPILER_TARGET}) -target_link_libraries(libgcc_s PRIVATE - $ - $ -) -target_link_options(libgcc_s PRIVATE - -nostdlib - -Wl,--version-script,$) - -check_library_exists(m sin "" LLVM_LIBGCC_HAS_LIBM) -target_link_libraries(libgcc_s PRIVATE - $<$:m> - c -) - -extend_path(LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT "${CMAKE_INSTALL_PREFIX}" "${LIBUNWIND_INSTALL_LIBRARY_DIR}") -#string(REPLACE "${CMAKE_INSTALL_FULL_LIBDIR}/" "" LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT "${LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT}") - -install(TARGETS libgcc_s - LIBRARY DESTINATION "${LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT}" COMPONENT unwind - ARCHIVE DESTINATION "${LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT}" COMPONENT unwind - RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}" COMPONENT unwind) - -get_compiler_rt_install_dir(${LLVM_LIBGCC_TARGET_ARCH} install_dir_builtins) -string(REGEX REPLACE "^lib/" "" install_dir_builtins "${install_dir_builtins}") -string(FIND "${install_dir_builtins}" "clang" install_path_contains_triple) -if(install_path_contains_triple EQUAL -1) - set(builtins_suffix "-${LLVM_LIBGCC_TARGET_ARCH}") -else() - string(PREPEND install_dir_builtins "../") -endif() -install(CODE "execute_process( - COMMAND \"\${CMAKE_COMMAND}\" -E - create_symlink ${install_dir_builtins}/libclang_rt.builtins${builtins_suffix}.a libgcc.a - WORKING_DIRECTORY \"\$ENV{DESTDIR}${LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT}\")" - COMPONENT unwind) - -install(CODE "execute_process( - COMMAND \"\${CMAKE_COMMAND}\" -E - create_symlink libunwind.a libgcc_eh.a - WORKING_DIRECTORY \"\$ENV{DESTDIR}${LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT}\")" - COMPONENT unwind) -install(CODE "execute_process( - COMMAND \"\${CMAKE_COMMAND}\" -E - create_symlink libunwind.so libgcc_s.so.1.0 - WORKING_DIRECTORY \"\$ENV{DESTDIR}${LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT}\")" - COMPONENT unwind) -install(CODE "execute_process( - COMMAND \"\${CMAKE_COMMAND}\" -E - create_symlink libgcc_s.so.1.0 libgcc_s.so.1 - WORKING_DIRECTORY \"\$ENV{DESTDIR}${LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT}\")" - COMPONENT unwind) -install(CODE "execute_process( - COMMAND \"\${CMAKE_COMMAND}\" -E - create_symlink libgcc_s.so.1 libgcc_s.so - WORKING_DIRECTORY \"\$ENV{DESTDIR}${LLVM_LIBGCC_LIBUNWIND_STATIC_ROOT}\")" - COMPONENT unwind) diff --git a/llvm-libgcc/lib/blank.c b/llvm-libgcc/lib/blank.c deleted file mode 100644 index e69de29bb2d1..000000000000 diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt index 58af4c8b131b..010ec879e44a 100644 --- a/runtimes/CMakeLists.txt +++ b/runtimes/CMakeLists.txt @@ -216,23 +216,6 @@ if(LLVM_INCLUDE_TESTS) umbrella_lit_testsuite_begin(check-runtimes) endif() -# llvm-libgcc incorporates both compiler-rt and libunwind as subprojects with very -# specific flags, which causes clashes when they're independently built too. -if("llvm-libgcc" IN_LIST runtimes) - if("compiler-rt" IN_LIST runtimes OR "compiler-rt" IN_LIST LLVM_ENABLE_PROJECTS) - message(FATAL_ERROR - "Attempting to build both compiler-rt and llvm-libgcc will cause irreconcilable " - "target clashes. Please choose one or the other, but not both.") - endif() - - if("libunwind" IN_LIST runtimes) - message( - FATAL_ERROR - "Attempting to build both libunwind and llvm-libgcc will cause irreconcilable " - "target clashes. Please choose one or the other, but not both.") - endif() -endif() - # We do this in two loops so that HAVE_* is set for each runtime before the # other runtimes are added. foreach(entry ${runtimes})