[libcxx-commits] [libcxxabi] aa656f6 - [runtimes] Introduce object libraries

Louis Dionne via libcxx-commits libcxx-commits at lists.llvm.org
Mon May 16 05:41:28 PDT 2022


Author: Louis Dionne
Date: 2022-05-16T08:41:16-04:00
New Revision: aa656f6c2dec73faceeed21e15401d8f0c743c8b

URL: https://github.com/llvm/llvm-project/commit/aa656f6c2dec73faceeed21e15401d8f0c743c8b
DIFF: https://github.com/llvm/llvm-project/commit/aa656f6c2dec73faceeed21e15401d8f0c743c8b.diff

LOG: [runtimes] Introduce object libraries

This is a variant of D116689 rebased on top of the new (proposed) ABI
refactoring in D120727. It should conserve the basic properties of the
original patch by @phosek, except it also allows cleaning up the merging
of libc++abi into libc++ from the libc++ side.

Differential Revision: https://reviews.llvm.org/D125393

Added: 
    

Modified: 
    libcxx/cmake/Modules/HandleLibCXXABI.cmake
    libcxx/src/CMakeLists.txt
    libcxxabi/cmake/Modules/HandleLibcxxabiFlags.cmake
    libcxxabi/src/CMakeLists.txt
    libunwind/cmake/Modules/HandleLibunwindFlags.cmake
    libunwind/src/CMakeLists.txt

Removed: 
    libcxx/utils/merge_archives.py


################################################################################
diff  --git a/libcxx/cmake/Modules/HandleLibCXXABI.cmake b/libcxx/cmake/Modules/HandleLibCXXABI.cmake
index 1a56c861406b0..e77a4156071b6 100644
--- a/libcxx/cmake/Modules/HandleLibCXXABI.cmake
+++ b/libcxx/cmake/Modules/HandleLibCXXABI.cmake
@@ -6,6 +6,14 @@
 #                       headers of the selected ABI library.
 # - libcxx-abi-shared: A target representing the selected shared ABI library.
 # - libcxx-abi-static: A target representing the selected static ABI library.
+#
+# Furthermore, some ABI libraries also define the following target:
+# - libcxx-abi-shared-objects: An object library representing a set of object files
+#                              constituting the ABI library, suitable for bundling
+#                              into a shared library.
+# - libcxx-abi-static-objects: An object library representing a set of object files
+#                              constituting the ABI library, suitable for bundling
+#                              into a static library.
 #===============================================================================
 
 include(GNUInstallDirs)
@@ -111,6 +119,14 @@ elseif ("${LIBCXX_CXX_ABI}" STREQUAL "libcxxabi")
     add_library(libcxx-abi-static ALIAS cxxabi_static)
   endif()
 
+  if (TARGET cxxabi_shared_objects)
+    add_library(libcxx-abi-shared-objects ALIAS cxxabi_shared_objects)
+  endif()
+
+  if (TARGET cxxabi_static_objects)
+    add_library(libcxx-abi-static-objects ALIAS cxxabi_static_objects)
+  endif()
+
 # Link against a system-provided libc++abi
 elseif ("${LIBCXX_CXX_ABI}" STREQUAL "system-libcxxabi")
   add_library(libcxx-abi-headers INTERFACE)

diff  --git a/libcxx/src/CMakeLists.txt b/libcxx/src/CMakeLists.txt
index 41d07d15f03cd..903105d770958 100644
--- a/libcxx/src/CMakeLists.txt
+++ b/libcxx/src/CMakeLists.txt
@@ -219,6 +219,9 @@ if (LIBCXX_ENABLE_SHARED)
   cxx_set_common_defines(cxx_shared)
 
   # Link against LLVM libunwind
+  # Note that we do need to link against libunwind directly to ensure that the correct
+  # dependencies are recorded when creating a linker script.
+  # TODO: Look into modifying the linker script creation to recursively consider interface libraries
   if (LIBCXXABI_USE_LLVM_UNWINDER)
     if (NOT LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY AND (TARGET unwind_shared OR HAVE_LIBUNWIND))
       target_link_libraries(cxx_shared PUBLIC unwind_shared)
@@ -231,11 +234,7 @@ if (LIBCXX_ENABLE_SHARED)
 
   # Link against libc++abi
   if (LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY)
-    if (APPLE)
-      target_link_libraries(cxx_shared PRIVATE "-Wl,-force_load" "$<TARGET_LINKER_FILE:libcxx-abi-static>")
-    else()
-      target_link_libraries(cxx_shared PRIVATE "-Wl,--whole-archive,-Bstatic" "$<TARGET_LINKER_FILE:libcxx-abi-static>" "-Wl,-Bdynamic,--no-whole-archive")
-    endif()
+    target_link_libraries(cxx_shared PRIVATE libcxx-abi-shared-objects)
   else()
     target_link_libraries(cxx_shared PUBLIC libcxx-abi-shared)
   endif()
@@ -293,13 +292,6 @@ if (LIBCXX_ENABLE_STATIC)
   cxx_add_common_build_flags(cxx_static)
   cxx_set_common_defines(cxx_static)
 
-  if (LIBCXXABI_USE_LLVM_UNWINDER)
-    # If we intend to use the just-built unwinder, add a dependency so that it
-    # gets built, even if we technically aren't going to link it in at this
-    # stage.
-    add_dependencies(cxx_static unwind)
-  endif()
-
   if (LIBCXX_HERMETIC_STATIC_LIBRARY)
     # If the hermetic library doesn't define the operator new/delete functions
     # then its code shouldn't declare them with hidden visibility.  They might
@@ -314,22 +306,7 @@ if (LIBCXX_ENABLE_STATIC)
   list(APPEND LIBCXX_BUILD_TARGETS "cxx_static")
   # Attempt to merge the libc++.a archive and the ABI library archive into one.
   if (LIBCXX_STATICALLY_LINK_ABI_IN_STATIC_LIBRARY)
-    if (APPLE)
-      set(MERGE_ARCHIVES_LIBTOOL "--use-libtool" "--libtool" "${CMAKE_LIBTOOL}")
-    endif()
-    add_custom_command(TARGET cxx_static POST_BUILD
-    COMMAND
-      ${Python3_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/utils/merge_archives.py
-    ARGS
-      -o $<TARGET_LINKER_FILE:cxx_static>
-      --ar "${CMAKE_AR}"
-      ${MERGE_ARCHIVES_LIBTOOL}
-      "$<TARGET_LINKER_FILE:cxx_static>"
-      "$<TARGET_LINKER_FILE:libcxx-abi-static>"
-      ""
-    WORKING_DIRECTORY ${LIBCXX_BUILD_DIR}
-    DEPENDS ${MERGE_ARCHIVES_ABI_TARGET}
-    )
+    target_link_libraries(cxx_static PRIVATE libcxx-abi-static-objects)
   endif()
 endif()
 

diff  --git a/libcxx/utils/merge_archives.py b/libcxx/utils/merge_archives.py
deleted file mode 100755
index fa0b2ee681713..0000000000000
--- a/libcxx/utils/merge_archives.py
+++ /dev/null
@@ -1,153 +0,0 @@
-#!/usr/bin/env python
-#===----------------------------------------------------------------------===##
-#
-# Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
-# See https://llvm.org/LICENSE.txt for license information.
-# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-#
-#===----------------------------------------------------------------------===##
-
-from argparse import ArgumentParser
-import distutils.spawn
-import tempfile
-import os
-import shutil
-import subprocess
-import signal
-import sys
-
-temp_directory_root = None
-def exit_with_cleanups(status):
-    if temp_directory_root is not None:
-        shutil.rmtree(temp_directory_root)
-    sys.exit(status)
-
-def print_and_exit(msg):
-    sys.stderr.write(msg + '\n')
-    exit_with_cleanups(1)
-
-def find_and_diagnose_missing(lib, search_paths):
-    if os.path.exists(lib):
-        return os.path.abspath(lib)
-    if not lib.startswith('lib') or not lib.endswith('.a'):
-        print_and_exit(("input file '%s' not not name a static library. "
-                       "It should start with 'lib' and end with '.a") % lib)
-    for sp in search_paths:
-        assert type(sp) is list and len(sp) == 1
-        path = os.path.join(sp[0], lib)
-        if os.path.exists(path):
-            return os.path.abspath(path)
-    print_and_exit("input '%s' does not exist" % lib)
-
-
-def execute_command(cmd, cwd=None):
-    """
-    Execute a command, capture and return its output.
-    """
-    kwargs = {
-        'stdin': subprocess.PIPE,
-        'stdout': subprocess.PIPE,
-        'stderr': subprocess.PIPE,
-        'cwd': cwd,
-        'universal_newlines': True
-    }
-    p = subprocess.Popen(cmd, **kwargs)
-    out, err = p.communicate()
-    exitCode = p.wait()
-    if exitCode == -signal.SIGINT:
-        raise KeyboardInterrupt
-    return out, err, exitCode
-
-
-def execute_command_verbose(cmd, cwd=None, verbose=False):
-    """
-    Execute a command and print its output on failure.
-    """
-    out, err, exitCode = execute_command(cmd, cwd=cwd)
-    if exitCode != 0 or verbose:
-        report = "Command: %s\n" % ' '.join(["'%s'" % a for a in cmd])
-        if exitCode != 0:
-            report += "Exit Code: %d\n" % exitCode
-        if out:
-            report += "Standard Output:\n--\n%s--" % out
-        if err:
-            report += "Standard Error:\n--\n%s--" % err
-        if exitCode != 0:
-            report += "\n\nFailed!"
-        sys.stderr.write('%s\n' % report)
-        if exitCode != 0:
-            exit_with_cleanups(exitCode)
-    return out
-
-def main():
-    parser = ArgumentParser(
-        description="Merge multiple archives into a single library")
-    parser.add_argument(
-        '-v', '--verbose', dest='verbose', action='store_true', default=False)
-    parser.add_argument(
-        '-o', '--output', dest='output', required=True,
-        help='The output file. stdout is used if not given',
-        type=str, action='store')
-    parser.add_argument(
-        '-L', dest='search_paths',
-        help='Paths to search for the libraries along', action='append',
-        nargs=1, default=[])
-    parser.add_argument(
-        '--ar', dest='ar_exe', required=False,
-        help='The ar executable to use, finds \'ar\' in the path if not given',
-        type=str, action='store')
-    parser.add_argument(
-        '--use-libtool', dest='use_libtool', action='store_true', default=False)
-    parser.add_argument(
-        '--libtool', dest='libtool_exe', required=False,
-        help='The libtool executable to use, finds \'libtool\' in the path if not given',
-        type=str, action='store')
-    parser.add_argument(
-        'archives', metavar='archives',  nargs='+',
-        help='The archives to merge')
-
-    args = parser.parse_args()
-
-    ar_exe = args.ar_exe
-    if not ar_exe:
-        ar_exe = distutils.spawn.find_executable('ar')
-    if not ar_exe:
-        print_and_exit("failed to find 'ar' executable")
-
-    if args.use_libtool:
-        libtool_exe = args.libtool_exe
-        if not libtool_exe:
-            libtool_exe = distutils.spawn.find_executable('libtool')
-        if not libtool_exe:
-            print_and_exit("failed to find 'libtool' executable")
-
-    if len(args.archives) < 2:
-        print_and_exit('fewer than 2 inputs provided')
-    archives = [find_and_diagnose_missing(ar, args.search_paths)
-                for ar in args.archives]
-    print ('Merging archives: %s' % archives)
-    if not os.path.exists(os.path.dirname(args.output)):
-        print_and_exit("output path doesn't exist: '%s'" % args.output)
-
-    global temp_directory_root
-    temp_directory_root = tempfile.mkdtemp('.libcxx.merge.archives')
-
-    files = []
-    for arc in archives:
-        execute_command_verbose([ar_exe, 'x', arc],
-                                cwd=temp_directory_root, verbose=args.verbose)
-        out = execute_command_verbose([ar_exe, 't', arc])
-        files.extend(out.splitlines())
-
-    if args.use_libtool:
-        files = [f for f in files if not f.startswith('__.SYMDEF')]
-        execute_command_verbose([libtool_exe, '-static', '-o', args.output] + files,
-                                cwd=temp_directory_root, verbose=args.verbose)
-    else:
-        execute_command_verbose([ar_exe, 'rcs', args.output] + files,
-                                cwd=temp_directory_root, verbose=args.verbose)
-
-
-if __name__ == '__main__':
-    main()
-    exit_with_cleanups(0)

diff  --git a/libcxxabi/cmake/Modules/HandleLibcxxabiFlags.cmake b/libcxxabi/cmake/Modules/HandleLibcxxabiFlags.cmake
index 98b455c5cb304..25d4789a2fdae 100644
--- a/libcxxabi/cmake/Modules/HandleLibcxxabiFlags.cmake
+++ b/libcxxabi/cmake/Modules/HandleLibcxxabiFlags.cmake
@@ -240,3 +240,15 @@ endmacro()
 macro(split_list listname)
   string(REPLACE ";" " " ${listname} "${${listname}}")
 endmacro()
+
+# For each specified flag, add that compile flag to the provided target.
+# The flags are added with the given visibility, i.e. PUBLIC|PRIVATE|INTERFACE.
+function(target_add_compile_flags_if_supported target visibility)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
+    if (CXX_SUPPORTS_${flagname}_FLAG)
+      target_compile_options(${target} ${visibility} ${flag})
+    endif()
+  endforeach()
+endfunction()

diff  --git a/libcxxabi/src/CMakeLists.txt b/libcxxabi/src/CMakeLists.txt
index 2ce8dd8fb9f67..e19f33c55a29f 100644
--- a/libcxxabi/src/CMakeLists.txt
+++ b/libcxxabi/src/CMakeLists.txt
@@ -77,32 +77,13 @@ else()
   add_library_flags_if(LIBCXXABI_HAS_C_LIB c)
 endif()
 
-if (LIBCXXABI_USE_COMPILER_RT)
-  find_compiler_rt_library(builtins LIBCXXABI_BUILTINS_LIBRARY)
-  list(APPEND LIBCXXABI_SHARED_LIBRARIES "${LIBCXXABI_BUILTINS_LIBRARY}")
-endif ()
-
-if (LIBCXXABI_USE_LLVM_UNWINDER)
-  # Prefer using the in-tree version of libunwind, either shared or static. If
-  # none are found fall back to using -lunwind.
-  # FIXME: Is it correct to prefer the static version of libunwind?
-  if (NOT LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY AND (TARGET unwind_shared OR HAVE_LIBUNWIND))
-    list(APPEND LIBCXXABI_SHARED_LIBRARIES unwind_shared)
-  elseif (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY AND (TARGET unwind_static OR HAVE_LIBUNWIND))
-    list(APPEND LIBCXXABI_SHARED_LIBRARIES unwind_static)
-  else()
-    list(APPEND LIBCXXABI_SHARED_LIBRARIES unwind)
-  endif()
-  if (NOT LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY AND (TARGET unwind_shared OR HAVE_LIBUNWIND))
-    list(APPEND LIBCXXABI_STATIC_LIBRARIES unwind_shared)
-  elseif (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY AND (TARGET unwind_static OR HAVE_LIBUNWIND))
-      # We handle this by directly merging libunwind objects into libc++abi.
-  else()
-    list(APPEND LIBCXXABI_STATIC_LIBRARIES unwind)
-  endif()
-else()
+if (NOT LIBCXXABI_USE_COMPILER_RT)
+  add_library_flags_if(LIBCXXABI_HAS_GCC_LIB gcc)
+endif()
+if (NOT LIBCXXABI_USE_LLVM_UNWINDER)
   add_library_flags_if(LIBCXXABI_HAS_GCC_S_LIB gcc_s)
 endif()
+
 if (MINGW)
   # MINGW_LIBRARIES is defined in config-ix.cmake
   list(APPEND LIBCXXABI_LIBRARIES ${MINGW_LIBRARIES})
@@ -111,10 +92,6 @@ if (ANDROID AND ANDROID_PLATFORM_LEVEL LESS 21)
   list(APPEND LIBCXXABI_LIBRARIES android_support)
 endif()
 
-if (NOT LIBCXXABI_USE_COMPILER_RT)
-  add_library_flags_if(LIBCXXABI_HAS_GCC_LIB gcc)
-endif ()
-
 # Setup flags.
 if (CXX_SUPPORTS_NOSTDLIBXX_FLAG)
   add_link_flags_if_supported(-nostdlib++)
@@ -175,25 +152,43 @@ if (NOT TARGET pstl::ParallelSTL)
 endif()
 
 # Build the shared library.
-if (LIBCXXABI_ENABLE_SHARED)
-  add_library(cxxabi_shared SHARED ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
-  target_link_libraries(cxxabi_shared PRIVATE cxx-headers ${LIBCXXABI_SHARED_LIBRARIES} ${LIBCXXABI_LIBRARIES})
-  target_link_libraries(cxxabi_shared PUBLIC cxxabi-headers)
-  if (TARGET pstl::ParallelSTL)
-    target_link_libraries(cxxabi_shared PUBLIC pstl::ParallelSTL)
+add_library(cxxabi_shared_objects OBJECT EXCLUDE_FROM_ALL ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
+if (LIBCXXABI_USE_LLVM_UNWINDER)
+  if (LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY)
+    target_sources(cxxabi_shared_objects PUBLIC $<TARGET_OBJECTS:unwind_shared_objects>)
+  else()
+    target_link_libraries(cxxabi_shared_objects PUBLIC unwind_shared)
   endif()
+endif()
+target_link_libraries(cxxabi_shared_objects PRIVATE cxx-headers ${LIBCXXABI_BUILTINS_LIBRARY} ${LIBCXXABI_SHARED_LIBRARIES} ${LIBCXXABI_LIBRARIES})
+target_link_libraries(cxxabi_shared_objects PUBLIC cxxabi-headers)
+set_target_properties(cxxabi_shared_objects
+  PROPERTIES
+    CXX_EXTENSIONS OFF
+    CXX_STANDARD 20
+    CXX_STANDARD_REQUIRED OFF
+    COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
+    DEFINE_SYMBOL ""
+)
+if (CMAKE_POSITION_INDEPENDENT_CODE OR NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
+  set_target_properties(cxxabi_shared_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) # must set manually because it's an object library
+endif()
+
+if (LIBCXXABI_ENABLE_SHARED)
+  add_library(cxxabi_shared SHARED)
   set_target_properties(cxxabi_shared
     PROPERTIES
-      CXX_EXTENSIONS OFF
-      CXX_STANDARD 20
-      CXX_STANDARD_REQUIRED OFF
-      COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
       LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
       OUTPUT_NAME "c++abi"
       SOVERSION "1"
       VERSION "${LIBCXXABI_LIBRARY_VERSION}"
-      DEFINE_SYMBOL ""
   )
+  target_link_libraries(cxxabi_shared
+    PUBLIC cxxabi_shared_objects
+    PRIVATE ${LIBCXXABI_SHARED_LIBRARIES} ${LIBCXXABI_LIBRARIES})
+  if (TARGET pstl::ParallelSTL)
+    target_link_libraries(cxxabi_shared PUBLIC pstl::ParallelSTL)
+  endif()
 
   list(APPEND LIBCXXABI_BUILD_TARGETS "cxxabi_shared")
   if (LIBCXXABI_INSTALL_SHARED_LIBRARY)
@@ -231,61 +226,55 @@ if (LIBCXXABI_ENABLE_SHARED)
 endif()
 
 # Build the static library.
+add_library(cxxabi_static_objects OBJECT EXCLUDE_FROM_ALL ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
+if (LIBCXXABI_USE_LLVM_UNWINDER AND LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY)
+  target_sources(cxxabi_static_objects PUBLIC $<TARGET_OBJECTS:unwind_static_objects>)
+endif()
+target_link_libraries(cxxabi_static_objects PRIVATE cxx-headers ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
+target_link_libraries(cxxabi_static_objects PUBLIC cxxabi-headers)
+set_target_properties(cxxabi_static_objects
+  PROPERTIES
+    CXX_EXTENSIONS OFF
+    CXX_STANDARD 20
+    CXX_STANDARD_REQUIRED OFF
+    COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
+)
+
+if(LIBCXXABI_HERMETIC_STATIC_LIBRARY)
+  target_add_compile_flags_if_supported(cxxabi_static_objects PRIVATE -fvisibility=hidden)
+  # If the hermetic library doesn't define the operator new/delete functions
+  # then its code shouldn't declare them with hidden visibility.  They might
+  # actually be provided by a shared library at link time.
+  if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS)
+    target_add_compile_flags_if_supported(cxxabi_static_objects PRIVATE -fvisibility-global-new-delete-hidden)
+  endif()
+  target_compile_definitions(cxxabi_static_objects
+    PRIVATE
+      _LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS
+      _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+endif()
+
 if (LIBCXXABI_ENABLE_STATIC)
-  add_library(cxxabi_static STATIC ${LIBCXXABI_SOURCES} ${LIBCXXABI_HEADERS})
-  target_link_libraries(cxxabi_static PRIVATE cxx-headers ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
-  target_link_libraries(cxxabi_static PUBLIC cxxabi-headers)
-  if (TARGET pstl::ParallelSTL)
-    target_link_libraries(cxxabi_static PUBLIC pstl::ParallelSTL)
+  add_library(cxxabi_static STATIC)
+  if (LIBCXXABI_USE_LLVM_UNWINDER AND NOT LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY)
+    target_link_libraries(cxxabi_static PUBLIC unwind_static)
   endif()
   set_target_properties(cxxabi_static
     PROPERTIES
-      CXX_EXTENSIONS OFF
-      CXX_STANDARD 20
-      CXX_STANDARD_REQUIRED OFF
-      COMPILE_FLAGS "${LIBCXXABI_COMPILE_FLAGS}"
       LINK_FLAGS "${LIBCXXABI_LINK_FLAGS}"
       OUTPUT_NAME "c++abi"
     )
-
-  if(LIBCXXABI_HERMETIC_STATIC_LIBRARY)
-    append_flags_if_supported(CXXABI_STATIC_LIBRARY_FLAGS -fvisibility=hidden)
-    # If the hermetic library doesn't define the operator new/delete functions
-    # then its code shouldn't declare them with hidden visibility.  They might
-    # actually be provided by a shared library at link time.
-    if (LIBCXXABI_ENABLE_NEW_DELETE_DEFINITIONS)
-      append_flags_if_supported(CXXABI_STATIC_LIBRARY_FLAGS -fvisibility-global-new-delete-hidden)
-    endif()
-    target_compile_options(cxxabi_static PRIVATE ${CXXABI_STATIC_LIBRARY_FLAGS})
-    target_compile_definitions(cxxabi_static
-      PRIVATE
-        _LIBCXXABI_DISABLE_VISIBILITY_ANNOTATIONS
-        _LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS)
+  target_link_libraries(cxxabi_static
+    PUBLIC cxxabi_static_objects
+    PRIVATE ${LIBCXXABI_STATIC_LIBRARIES} ${LIBCXXABI_LIBRARIES})
+  if (TARGET pstl::ParallelSTL)
+    target_link_libraries(cxxabi_static PUBLIC pstl::ParallelSTL)
   endif()
 
   list(APPEND LIBCXXABI_BUILD_TARGETS "cxxabi_static")
   if (LIBCXXABI_INSTALL_STATIC_LIBRARY)
     list(APPEND LIBCXXABI_INSTALL_TARGETS "cxxabi_static")
   endif()
-
-  if (APPLE)
-    set(MERGE_ARCHIVES_LIBTOOL "--use-libtool" "--libtool" "${CMAKE_LIBTOOL}")
-  endif()
-
-  # Merge the libc++abi.a and libunwind.a into one.
-  if(LIBCXXABI_USE_LLVM_UNWINDER AND LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_STATIC_LIBRARY)
-    add_custom_command(TARGET cxxabi_static POST_BUILD
-      COMMAND ${Python3_EXECUTABLE} ${LIBCXXABI_LIBCXX_PATH}/utils/merge_archives.py
-      ARGS
-        -o "$<TARGET_LINKER_FILE:cxxabi_static>"
-        --ar "${CMAKE_AR}"
-        ${MERGE_ARCHIVES_LIBTOOL}
-        "$<TARGET_LINKER_FILE:cxxabi_static>"
-        "$<TARGET_LINKER_FILE:unwind_static>"
-      WORKING_DIRECTORY ${LIBCXXABI_BUILD_DIR}
-      DEPENDS unwind_static
-    )
-  endif()
 endif()
 
 # Add a meta-target for both libraries.

diff  --git a/libunwind/cmake/Modules/HandleLibunwindFlags.cmake b/libunwind/cmake/Modules/HandleLibunwindFlags.cmake
index 18a5fd27c1c9d..c5d76034d8709 100644
--- a/libunwind/cmake/Modules/HandleLibunwindFlags.cmake
+++ b/libunwind/cmake/Modules/HandleLibunwindFlags.cmake
@@ -281,3 +281,15 @@ endmacro()
 macro(split_list listname)
   string(REPLACE ";" " " ${listname} "${${listname}}")
 endmacro()
+
+# For each specified flag, add that compile flag to the provided target.
+# The flags are added with the given visibility, i.e. PUBLIC|PRIVATE|INTERFACE.
+function(target_add_compile_flags_if_supported target visibility)
+  foreach(flag ${ARGN})
+    mangle_name("${flag}" flagname)
+    check_cxx_compiler_flag("${flag}" "CXX_SUPPORTS_${flagname}_FLAG")
+    if (CXX_SUPPORTS_${flagname}_FLAG)
+      target_compile_options(${target} ${visibility} ${flag})
+    endif()
+  endforeach()
+endfunction()

diff  --git a/libunwind/src/CMakeLists.txt b/libunwind/src/CMakeLists.txt
index faef6a83e5cb9..61df2737be754 100644
--- a/libunwind/src/CMakeLists.txt
+++ b/libunwind/src/CMakeLists.txt
@@ -136,27 +136,36 @@ set_property(SOURCE ${LIBUNWIND_C_SOURCES}
 set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
 
 # Build the shared library.
+add_library(unwind_shared_objects OBJECT EXCLUDE_FROM_ALL ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
+if(CMAKE_C_COMPILER_ID STREQUAL MSVC)
+  target_compile_options(unwind_shared_objects PRIVATE /GR-)
+else()
+  target_compile_options(unwind_shared_objects PRIVATE -fno-rtti)
+endif()
+target_link_libraries(unwind_shared_objects PRIVATE unwind-headers ${LIBUNWIND_LIBRARIES})
+set_target_properties(unwind_shared_objects
+  PROPERTIES
+    CXX_EXTENSIONS OFF
+    CXX_STANDARD 11
+    CXX_STANDARD_REQUIRED ON
+    COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
+)
+if (CMAKE_POSITION_INDEPENDENT_CODE OR NOT DEFINED CMAKE_POSITION_INDEPENDENT_CODE)
+  set_target_properties(unwind_shared_objects PROPERTIES POSITION_INDEPENDENT_CODE ON) # must set manually because it's an object library
+endif()
+
 if (LIBUNWIND_ENABLE_SHARED)
-  add_library(unwind_shared SHARED ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
-  if(CMAKE_C_COMPILER_ID STREQUAL MSVC)
-    target_compile_options(unwind_shared PRIVATE /GR-)
-  else()
-    target_compile_options(unwind_shared PRIVATE -fno-rtti)
-  endif()
-  target_link_libraries(unwind_shared PRIVATE ${LIBUNWIND_LIBRARIES}
-                                      PRIVATE unwind-headers)
+  add_library(unwind_shared SHARED)
+  target_link_libraries(unwind_shared PUBLIC unwind_shared_objects)
   set_target_properties(unwind_shared
     PROPERTIES
-      CXX_EXTENSIONS OFF
-      CXX_STANDARD 11
-      CXX_STANDARD_REQUIRED ON
-      COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
       LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}"
       LINKER_LANGUAGE C
       OUTPUT_NAME "unwind"
       VERSION "1.0"
       SOVERSION "1"
   )
+
   list(APPEND LIBUNWIND_BUILD_TARGETS "unwind_shared")
   if (LIBUNWIND_INSTALL_SHARED_LIBRARY)
     list(APPEND LIBUNWIND_INSTALL_TARGETS "unwind_shared")
@@ -164,33 +173,37 @@ if (LIBUNWIND_ENABLE_SHARED)
 endif()
 
 # Build the static library.
+add_library(unwind_static_objects OBJECT EXCLUDE_FROM_ALL ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
+if(CMAKE_C_COMPILER_ID STREQUAL MSVC)
+  target_compile_options(unwind_static_objects PRIVATE /GR-)
+else()
+  target_compile_options(unwind_static_objects PRIVATE -fno-rtti)
+endif()
+target_link_libraries(unwind_static_objects PRIVATE unwind-headers ${LIBUNWIND_LIBRARIES})
+set_target_properties(unwind_static_objects
+  PROPERTIES
+    CXX_EXTENSIONS OFF
+    CXX_STANDARD 11
+    CXX_STANDARD_REQUIRED ON
+    COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
+)
+
+if(LIBUNWIND_HIDE_SYMBOLS)
+  target_add_compile_flags_if_supported(unwind_static_objects PRIVATE -fvisibility=hidden)
+  target_add_compile_flags_if_supported(unwind_static_objects PRIVATE -fvisibility-global-new-delete-hidden)
+  target_compile_definitions(unwind_static_objects PRIVATE _LIBUNWIND_HIDE_SYMBOLS)
+endif()
+
 if (LIBUNWIND_ENABLE_STATIC)
-  add_library(unwind_static STATIC ${LIBUNWIND_SOURCES} ${LIBUNWIND_HEADERS})
-  if(CMAKE_C_COMPILER_ID STREQUAL MSVC)
-    target_compile_options(unwind_static PRIVATE /GR-)
-  else()
-    target_compile_options(unwind_static PRIVATE -fno-rtti)
-  endif()
-  target_link_libraries(unwind_static PRIVATE ${LIBUNWIND_LIBRARIES}
-                                      PRIVATE unwind-headers)
+  add_library(unwind_static STATIC)
+  target_link_libraries(unwind_static PUBLIC unwind_static_objects)
   set_target_properties(unwind_static
     PROPERTIES
-      CXX_EXTENSIONS OFF
-      CXX_STANDARD 11
-      CXX_STANDARD_REQUIRED ON
-      COMPILE_FLAGS "${LIBUNWIND_COMPILE_FLAGS}"
       LINK_FLAGS "${LIBUNWIND_LINK_FLAGS}"
       LINKER_LANGUAGE C
       OUTPUT_NAME "unwind"
   )
 
-  if(LIBUNWIND_HIDE_SYMBOLS)
-    append_flags_if_supported(UNWIND_STATIC_LIBRARY_FLAGS -fvisibility=hidden)
-    append_flags_if_supported(UNWIND_STATIC_LIBRARY_FLAGS -fvisibility-global-new-delete-hidden)
-    target_compile_options(unwind_static PRIVATE ${UNWIND_STATIC_LIBRARY_FLAGS})
-    target_compile_definitions(unwind_static PRIVATE _LIBUNWIND_HIDE_SYMBOLS)
-  endif()
-
   list(APPEND LIBUNWIND_BUILD_TARGETS "unwind_static")
   if (LIBUNWIND_INSTALL_STATIC_LIBRARY)
     list(APPEND LIBUNWIND_INSTALL_TARGETS "unwind_static")


        


More information about the libcxx-commits mailing list