mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-26 23:21:11 +00:00
[llvm-libgcc][CMake] Refactor llvm-libgcc (#65455)
There are some issues in `llvm-libgcc` before this patch:
Commit c5a20b5182
([llvm-libgcc] initial
commit)
uses `$<TARGET_OBJECTS:unwind_static>` 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.
This commit is contained in:
parent
44532a9dd4
commit
7ac1f60f01
@ -1,19 +1,38 @@
|
|||||||
cmake_minimum_required(VERSION 3.20.0)
|
#===============================================================================
|
||||||
|
# Setup Project
|
||||||
|
#===============================================================================
|
||||||
|
|
||||||
if (NOT IS_DIRECTORY "${CMAKE_CURRENT_LIST_DIR}/../libunwind")
|
cmake_minimum_required(VERSION 3.20.0)
|
||||||
message(FATAL_ERROR "llvm-libgcc requires being built in a monorepo layout with libunwind available")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(LLVM_COMMON_CMAKE_UTILS "${CMAKE_CURRENT_SOURCE_DIR}/../cmake")
|
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"
|
||||||
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
|
"${CMAKE_CURRENT_SOURCE_DIR}/cmake/Modules"
|
||||||
|
"${CMAKE_CURRENT_SOURCE_DIR}/../runtimes/cmake/Modules"
|
||||||
"${LLVM_COMMON_CMAKE_UTILS}"
|
"${LLVM_COMMON_CMAKE_UTILS}"
|
||||||
"${LLVM_COMMON_CMAKE_UTILS}/Modules"
|
"${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)
|
if(NOT LLVM_LIBGCC_EXPLICIT_OPT_IN)
|
||||||
message(FATAL_ERROR
|
message(FATAL_ERROR
|
||||||
@ -25,18 +44,114 @@ if(NOT LLVM_LIBGCC_EXPLICIT_OPT_IN)
|
|||||||
"to your CMake invocation and try again.")
|
"to your CMake invocation and try again.")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib${LLVMLIB_DIR_SUFFIX}")
|
if(HAVE_COMPILER_RT)
|
||||||
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/lib${LLVMLIB_DIR_SUFFIX}")
|
message(FATAL_ERROR
|
||||||
set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${PROJECT_BINARY_DIR}/bin")
|
"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)
|
if(HAVE_LIBUNWIND)
|
||||||
set(COMPILER_RT_BUILTINS_HIDE_SYMBOLS Off)
|
message(FATAL_ERROR
|
||||||
add_subdirectory("../compiler-rt" "compiler-rt")
|
"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)
|
# Configure System
|
||||||
set(LIBUNWIND_HAS_COMMENT_LIB_PRAGMA Off)
|
#===============================================================================
|
||||||
set(LIBUNWIND_USE_COMPILER_RT On)
|
|
||||||
add_subdirectory("../libunwind" "libunwind")
|
|
||||||
|
|
||||||
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
|
||||||
|
$<TARGET_OBJECTS:clang_rt.builtins-${COMPILER_RT_DEFAULT_TARGET_ARCH}>
|
||||||
|
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()
|
||||||
|
@ -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_OBJECTS:unwind_static>
|
|
||||||
$<TARGET_OBJECTS:clang_rt.builtins-${LLVM_LIBGCC_TARGET_ARCH}>
|
|
||||||
)
|
|
||||||
target_link_options(libgcc_s PRIVATE
|
|
||||||
-nostdlib
|
|
||||||
-Wl,--version-script,$<TARGET_PROPERTY:gcc_s.ver,OUTPUT_PATH>)
|
|
||||||
|
|
||||||
check_library_exists(m sin "" LLVM_LIBGCC_HAS_LIBM)
|
|
||||||
target_link_libraries(libgcc_s PRIVATE
|
|
||||||
$<$<BOOL:LLVM_LIBGCC_HAS_LIBM>: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)
|
|
@ -216,23 +216,6 @@ if(LLVM_INCLUDE_TESTS)
|
|||||||
umbrella_lit_testsuite_begin(check-runtimes)
|
umbrella_lit_testsuite_begin(check-runtimes)
|
||||||
endif()
|
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
|
# We do this in two loops so that HAVE_* is set for each runtime before the
|
||||||
# other runtimes are added.
|
# other runtimes are added.
|
||||||
foreach(entry ${runtimes})
|
foreach(entry ${runtimes})
|
||||||
|
Loading…
Reference in New Issue
Block a user