Skip to content

[llvm-libgcc][CMake] Refactor llvm-libgcc #65455

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Sep 19, 2023
153 changes: 134 additions & 19 deletions llvm-libgcc/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -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"
)
)

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.")

project(llvm-libgcc LANGUAGES C CXX ASM)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this being removed?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

libunwind/CMakeLists.txt does not contains a project(libunwind LANGUAGES C CXX ASM). To keep consistent with libunwind/CMakeLists.txt, project(llvm-libgcc LANGUAGES C CXX ASM) is not added.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compiler-rt does have it, and I'd prefer to keep this regardless.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now llvm-libgcc use the same approach as compiler-rt in 60eccd0.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not following what you mean, sorry. Since this is the driver for compiler-rt and libunwind, it makes sense to me for this project to indicate this information.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

compiler-rt/CMakeLists.txt detects whether compiler-rt is built as a subproject of runtimes or a standalone project. In standalone mode it sets options to detect llvm and declares the project name with project(CompilerRT C CXX ASM).

Now llvm-libgcc/CMakeLists.txt does the same: in standalone mode, it tells added compiler-rt that we are not built as a subproject of runtimes and we have to detect llvm ourselves.

Here "standalone" means cmake -B build -S compiler-rt or cmake -B build -S llvm-libgcc, not cmake -B build -S runtimes nor cmake -B build -S llvm. Even in the whole llvm-project source tree, directly using compiler-rt/CMakeLists.txt or llvm-libgcc/CMakeLists.txt is "standalone".

If included by other CMakeLists.txt, runtimes/CMakeLists.txt for example, it does not matter whether there is a project(CompilerRT C CXX ASM) or project(llvm-libgcc LANGUAGES C CXX ASM) declaration actually performed. To keep consistent with compiler-rt, llvm-libgcc/CMakeLists.txt is adjusted correspondingly in 60eccd0.

Correspondingly lines from compiler-rt/CMakeLists.txt :

# Check if compiler-rt is built as a standalone project.
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR OR COMPILER_RT_STANDALONE_BUILD)
  project(CompilerRT C CXX ASM)
  set(COMPILER_RT_STANDALONE_BUILD TRUE)
  set_property(GLOBAL PROPERTY USE_FOLDERS ON)
endif()

Correspondingly lines in llvm-libgcc/CMakeLists.txt:

# 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()

And I am a bit confused how should we indicate "this is the driver for compiler-rt and libunwind". It is completely acceptable to perform project(llvm-libgcc LANGUAGES C CXX ASM) declaration unconditionally, but does it makes sense in this scenario?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Understood, thanks for highlighting the change to llvm-libgcc/CMakeLists.txt, which I'd missed.

include(GNUInstallDirs)

if(NOT LLVM_LIBGCC_EXPLICIT_OPT_IN)
message(FATAL_ERROR
Expand All @@ -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()

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()

#===============================================================================
# Configure System
#===============================================================================

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
)

set(COMPILER_RT_BUILD_BUILTINS On)
set(COMPILER_RT_BUILTINS_HIDE_SYMBOLS Off)
add_subdirectory("../compiler-rt" "compiler-rt")
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)

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")
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)

add_subdirectory(lib)
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()
File renamed without changes.
86 changes: 0 additions & 86 deletions llvm-libgcc/lib/CMakeLists.txt

This file was deleted.

Empty file removed llvm-libgcc/lib/blank.c
Empty file.
17 changes: 0 additions & 17 deletions runtimes/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -212,23 +212,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})
Expand Down