Skip to content
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

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

Merged
merged 8 commits into from
Sep 19, 2023
Merged

Conversation

ur4t
Copy link
Contributor

@ur4t ur4t commented Sep 6, 2023

There are some issues in llvm-libgcc before this patch:

Commit c5a20b5 ([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.

Commit c5a20b5 ([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.
This commit removes the limitation that `llvm-libgcc` cannot co-exist with
`compiler-rt` and `libunwind` when configuring llvm builds.

There's still a limitation that `-DCOMPILER_RT_BUILTINS_HIDE_SYMBOLS=No` is
required when `compiler-rt` is listed in `LLVM_ENABLE_RUNTIMES`. Because
`llvm-libgcc` will be added after `compiler-rt` in `runtimes/CMakeLists.txt`,
thus flags set in `llvm-libgcc/CMakeLists.txt` will not take effect.

There might be further refactoring which removes `llvm-libgcc` subproject,
merges coresponding components into `compiler-rt` and `libunwind` and adds
options like `COMPILER_RT_ENABLE_LIBGCC`, `LIBUNWIND_ENABLE_LIBGCC_EH` and
`LIBUNWIND_ENABLE_LIBGCC_S`, with old `llvm-libgcc` in `LLVM_ENABLE_RUNTIMES`
and `LLVM_LIBGCC_EXPLICIT_OPT_IN` preserved to keep compatibility.
@ur4t ur4t requested a review from a team as a code owner September 6, 2023 08:30
@compnerd
Copy link
Member

compnerd commented Sep 7, 2023

CC: @cjdb

@MaskRay MaskRay requested a review from cjdb September 7, 2023 04:30
@MaskRay
Copy link
Member

MaskRay commented Sep 7, 2023

FWIW I did notice that the build had been broken (likely for a while) when I recently removed some __{,de}register_frame_info* and __register_frame_table in be91bd0. Thank you for fixing the CMake.

-DLLVM_ENABLE_PROJECTS='clang;lld' -DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi;libunwind;llvm-libgcc;compiler-rt'
-DCOMPILER_RT_BUILTINS_HIDE_SYMBOLS=off  -DLLVM_LIBGCC_EXPLICIT_OPT_IN=on

This patch makes libgcc buildable but note that llvm-libgcc is not a target of the build directory

% ninja -C /tmp/out/custom libgcc
ninja: Entering directory `/tmp/out/custom'
ninja: error: unknown target 'libgcc
% ninja -C /tmp/out/custom llvm-libgcc
...
ninja: error: unknown target 'llvm-libgcc'
FAILED: runtimes/CMakeFiles/llvm-libgcc /tmp/out/custom/runtimes/CMakeFiles/llvm-libgcc
cd /tmp/out/custom/runtimes/runtimes-bins && /usr/bin/cmake --build /tmp/out/custom/runtimes/runtimes-bins/ --target llvm-libgcc --config Release
ninja: build stopped: subcommand failed.
% ninja -C /tmp/out/custom/runtimes/runtimes-bins/ libgcc  # good
% ninja -C /tmp/out/custom/runtimes/runtimes-bins/ llvm-libgcc
ninja: Entering directory `/tmp/out/custom/runtimes/runtimes-bins/'
ninja: error: unknown target 'llvm-libgcc'

Perhaps you can fix this as well.

When configuring with `llvm/CMakeLists.txt`, target `llvm-libgcc` requires a
corresponding target in `llvm-libgcc/CMakeLists.txt`. This commit fixes the
mismatched target names.
@ur4t
Copy link
Contributor Author

ur4t commented Sep 7, 2023

This patch makes libgcc buildable but note that llvm-libgcc is not a target of the build directory

@MaskRay This issue is fixed in c790fd0.

@MaskRay
Copy link
Member

MaskRay commented Sep 7, 2023

MaskRay approved these changes on behalf of https://github.com/orgs/llvm/teams/pr-subscribers-libunwind now

This removed llvm-libunwind from the reviewer list. I wish that somebody familiar with CMake may take a look.

Copy link
Contributor

@cjdb cjdb left a comment

Choose a reason for hiding this comment

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

Thanks for working on this!

IIRC it was @compnerd who convinced me that llvm-libgcc should not be compatible with an independent compiler-rt and libunwind, and that was because you only need one or the other. I still agree with that since llvm-libgcc is only intended for toolchain vendors, and not for casual use.

It would be good to get some exposition on why this PR changes this, and input from @compnerd regarding that design decision too.

"${LLVM_COMMON_CMAKE_UTILS}"
"${LLVM_COMMON_CMAKE_UTILS}/Modules"
)

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.

set(COMPILER_RT_BUILD_BUILTINS On)
set(COMPILER_RT_BUILTINS_HIDE_SYMBOLS Off)
add_subdirectory("../compiler-rt" "compiler-rt")
if(NOT HAVE_COMPILER_RT)
Copy link
Contributor

Choose a reason for hiding this comment

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

This (and libunwind) need to be unconditional, since you shouldn't be building compiler-rt and libunwind independently when building llvm-libgcc.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes, they are added unconditionally. HAVE_COMPILER_RT and HAVE_LIBUNWIND are set by runtimes/CMakeLists.txt if LLVM_ENABLE_RUNTIMES contains compiler-rt and libunwind. These checks are added to avoid target clashes when they are explicitly specified by users.

Copy link
Contributor

Choose a reason for hiding this comment

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

The design is that you should not be adding compiler-rt or libunwind to LLVM_ENABLE_RUNTIMES. Why is this being changed?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

It was changed, and now it is restored in b61aed7.

I tried to make them co-exist happily and found that it is quite hard to set necessary options without further modifying the order of runtime projects in runtimes/CMakeLists.txt.

This finding is documented in the commit message to explain why we chose this approach.

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 happy you're able to delete this file.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

In the refactored approach, we modify libunwind.so added in libunwind directly and no custom shared library is required, so the dummy source file can be deleted.

@ur4t
Copy link
Contributor Author

ur4t commented Sep 8, 2023

@cjdb @compnerd I am sorry for the misleading statement in this PR's initial comment.

refactors llvm-libgcc to co-exist with libunwind and compiler-rt.

This statement shoule be refined: "refactors llvm-libgcc to co-exist with libunwind and compiler-rt in LLVM_ENABLE_RUNTIMES list".

IIRC it was @compnerd who convinced me that llvm-libgcc should not be compatible with an independent compiler-rt and libunwind, and that was because you only need one or the other. I still agree with that since llvm-libgcc is only intended for toolchain vendors, and not for casual use.

It would be good to get some exposition on why this PR changes this, and input from @compnerd regarding that design decision too.

At first, I tried to build llvm-libgcc and found that unwind symbols in libunwind.so is not present in the built libgcc_s.so, and made eb938ef to fix this issue.

Then I found that the original llvm-libgcc/CMakeLists.txt:

  1. adds compiler-rt to get libclang_rt.builtins-ARCH.a object files.
  2. adds libunwind to get libunwind.a object files.
  3. replaces libunwind.so added in libunwind with a new libunwind.so built from object files in step 1 and step 2 and applies the version script.
  4. installs replaced libunwind.so and versioned symlinks.
  5. installs libgcc symlinks and versioned symlinks.

My first refactored llvm-libgcc/CMakeLists.txt:

  1. adds compiler-rt.
  2. adds libunwind.
  3. modifies libunwind.so added in libunwind with libclang_rt.builtins-ARCH.a object files and applies the version script.
  4. creates and installs libgcc symlinks and versioned symlinks.

Now llvm-libgcc/CMakeLists.txt keeps the original behaviour, but in a simplified approach, which means "llvm-libgcc is not compatible with an independent compiler-rt and libunwind" as before.

And I found the target clashes were no longer irreconcilable, via detecting compiler-rt and libunwind with HAVE_COMPILER_RT and HAVE_LIBUNWIND provided by runtimes/CMakeLists.txt, which allows llvm-libgcc to co-exist with libunwind and compiler-rt in LLVM_ENABLE_RUNTIMES list.

So there is no independent compiler-rt and libunwind, just removal of limitations while keeping the original behaviour.

This commit adds targets of `llvm-libgcc` symlinks into the component, which
fixes broken `llvm-libgcc` when installing only the component `llvm-libgcc`.
…nd compiler-rt/libunwind

It is quite hard to set necessary options without further modifying the order
of runtime projects in `runtimes/CMakeLists.txt`.

This commit restores to inhibit co-existence of `llvm-libgcc` and
`compiler-rt`/`libunwind` in commit c5a20b5
([llvm-libgcc] initial commit).
…bgcc

`libunwind.so` in `llvm-libgcc` is linked with clang_rt.builtins objects,
thus dependency on compiler-rt or libgcc is uncessary and should be removed.
@ur4t
Copy link
Contributor Author

ur4t commented Sep 8, 2023

@cjdb @compnerd With b61aed7, co-existence of llvm-libgcc and libunwind/compiler-rt in LLVM_ENABLE_RUNTIMES list is not allowed. Now I believe this PR is ready to be merged.

@ur4t ur4t requested a review from cjdb September 12, 2023 07:32
@llvmbot llvmbot added libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. libc++abi libc++abi C++ Runtime Library. Not libc++. libunwind labels Sep 13, 2023
Copy link
Contributor

@cjdb cjdb left a comment

Choose a reason for hiding this comment

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

Thanks for the patch!

@llvmbot
Copy link
Collaborator

llvmbot commented Sep 15, 2023

@llvm/pr-subscribers-libcxx
@llvm/pr-subscribers-libcxxabi

@llvm/pr-subscribers-libunwind

Changes

This PR:

  1. fixes broken libgcc_s.so which lacks symbols in libunwind.so.
  2. refactors llvm-libgcc/CMakeLists.txt.

Full diff: https://github.com/llvm/llvm-project/pull/65455.diff

5 Files Affected:

  • (modified) llvm-libgcc/CMakeLists.txt (+134-19)
  • (renamed) llvm-libgcc/gcc_s.ver.in ()
  • (removed) llvm-libgcc/lib/CMakeLists.txt (-86)
  • (removed) llvm-libgcc/lib/blank.c ()
  • (modified) runtimes/CMakeLists.txt (-17)
diff --git a/llvm-libgcc/CMakeLists.txt b/llvm-libgcc/CMakeLists.txt
index de42d908c37119d..013c9ca2e330766 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"
-  )
+)
+
+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)
+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()
+
+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()
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 d895a21554b03c9..000000000000000
--- 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_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)
diff --git a/llvm-libgcc/lib/blank.c b/llvm-libgcc/lib/blank.c
deleted file mode 100644
index e69de29bb2d1d64..000000000000000
diff --git a/runtimes/CMakeLists.txt b/runtimes/CMakeLists.txt
index 599529852688f25..06f51243827cdd7 100644
--- a/runtimes/CMakeLists.txt
+++ b/runtimes/CMakeLists.txt
@@ -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})

@ldionne
Copy link
Member

ldionne commented Sep 18, 2023

Are we waiting on anything to merge this? I think folks' expectations of how patches are merged might be unclear right now due to the Github PR transition. With Phabricator the patch author would push the change and the "PR" would be closed automatically. Now with Github PRs someone has to press "squash and merge" but it might not be clear whose responsibility it is to do this.

@cjdb @MaskRay We're ready to land this, right? If so, I think either of you can "Squash and merge" (or @ur4t if they are able to).

@cjdb
Copy link
Contributor

cjdb commented Sep 18, 2023

Right, it's ready to land. Thanks for pointing out that the workflow is different now.

@cjdb
Copy link
Contributor

cjdb commented Sep 18, 2023

@ur4t before I squash and merge, could you please provide me with a commit message that explains why the changes were necessary (as a comment)? I've looked at all the commit messages and text, but I don't see anything that captures the full message. If you've already written something, a link to that will be fine :)

@MaskRay
Copy link
Member

MaskRay commented Sep 18, 2023

I agree with a better description is needed.

Are we waiting on anything to merge this? I think folks' expectations of how patches are merged might be unclear right now due to the Github PR transition. With Phabricator the patch author would push the change and the "PR" would be closed automatically. Now with Github PRs someone has to press "squash and merge" but it might not be clear whose responsibility it is to do this.

I feel the author is the best one to perform the action, as they can adjust the description to be clearer, rebase as needed, or do other minor adjustments that do not need re-review.

@ldionne
Copy link
Member

ldionne commented Sep 18, 2023

I feel the author is the best one to perform the action, as they can adjust the description to be clearer, rebase as needed, or do other minor adjustments that do not need re-review.

FWIW that may not always be possible for folks who don't have direct commit access to the repo. But feel free to handle that however makes the most sense to you. For libc++/libc++abi, I often merge on behalf of folks to make sure that the PR isn't forgotten, etc.

@ur4t
Copy link
Contributor Author

ur4t commented Sep 19, 2023

@cjdb Sorry for the circuitous commit history. I am glad to provide a summary.

[llvm-libgcc][CMake] Refactor llvm-libgcc

There are some issues in llvm-libgcc before this patch:

Commit c5a20b5 ([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.

@MaskRay MaskRay merged commit 7ac1f60 into llvm:main Sep 19, 2023
5 checks passed
ZijunZhaoCCK pushed a commit to ZijunZhaoCCK/llvm-project that referenced this pull request Sep 19, 2023
There are some issues in `llvm-libgcc` before this patch:

Commit c5a20b5 ([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.
@ur4t ur4t deleted the refactor-llvm-libgcc branch September 19, 2023 08:08
@ur4t
Copy link
Contributor Author

ur4t commented Sep 19, 2023

@MaskRay It seems that Github enforce a column limit of 70 characters in "Squash and Merge" commit messages (refined-github#1475). Commit messages targeting a 80 character limitation will be truncated again when texts are copied and pasted directly with original line breakages (7ac1f60 and af935cf). Should we mention this behaviour in documents for the Github PR transition?

@MaskRay
Copy link
Member

MaskRay commented Sep 20, 2023

@MaskRay It seems that Github enforce a column limit of 70 characters in "Squash and Merge" commit messages (refined-github#1475). Commit messages targeting a 80 character limitation will be truncated again when texts are copied and pasted directly with original line breakages (7ac1f60 and af935cf). Should we mention this behaviour in documents for the Github PR transition?

Thanks for mentioning this behavior. Perhaps comment on https://discourse.llvm.org/t/hows-it-going-with-pull-requests/73467 or a related github pr transition post?

If github has such a truncation problem, i'll try to avoid the web ui completely...
With Phabricator, I always double checked the commit message..

Due to email spam from github notifications, I almost missed your comment...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
libc++abi libc++abi C++ Runtime Library. Not libc++. libc++ libc++ C++ Standard Library. Not GNU libstdc++. Not libc++abi. libunwind
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

6 participants