Index: libcxx/trunk/CMakeLists.txt =================================================================== --- libcxx/trunk/CMakeLists.txt +++ libcxx/trunk/CMakeLists.txt @@ -270,9 +270,13 @@ # LIBCXX_CXX_FLAGS: General flags for both the compiler and linker. # LIBCXX_COMPILE_FLAGS: Compile only flags. # LIBCXX_LINK_FLAGS: Linker only flags. +# LIBCXX_LIBRARIES: Private libraries libc++ is linked to. +# LIBCXX_LIBRARIES_PUBLIC: Public libraries libc++ is linked to, +# also exposed in the linker script. set(LIBCXX_COMPILE_FLAGS "") set(LIBCXX_LINK_FLAGS "") set(LIBCXX_LIBRARIES "") +set(LIBCXX_LIBRARIES_PUBLIC "") # Include macros for adding and removing libc++ flags. include(HandleLibcxxFlags) Index: libcxx/trunk/lib/CMakeLists.txt =================================================================== --- libcxx/trunk/lib/CMakeLists.txt +++ libcxx/trunk/lib/CMakeLists.txt @@ -33,9 +33,17 @@ add_library_flags_if(LIBCXX_COVERAGE_LIBRARY "${LIBCXX_COVERAGE_LIBRARY}") -add_library_flags_if(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "-Wl,--whole-archive" "-Wl,-Bstatic") -add_library_flags("${LIBCXX_CXX_ABI_LIBRARY}") -add_library_flags_if(LIBCXX_ENABLE_STATIC_ABI_LIBRARY "-Wl,-Bdynamic" "-Wl,--no-whole-archive") +if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY) + add_library_flags("-Wl,--whole-archive" "-Wl,-Bstatic") + add_library_flags("${LIBCXX_CXX_ABI_LIBRARY}") + add_library_flags("-Wl,-Bdynamic" "-Wl,--no-whole-archive") +elseif (APPLE AND (LIBCXX_CXX_ABI_LIBNAME STREQUAL "libcxxabi" OR + LIBCXX_CXX_ABI_LIBNAME STREQUAL "none")) + # Apple re-exports libc++abi in libc++, so don't make it public + add_library_flags("${LIBCXX_CXX_ABI_LIBRARY}") +else() + list(APPEND LIBCXX_LIBRARIES_PUBLIC "${LIBCXX_CXX_ABI_LIBRARY}") +endif() if (APPLE AND LLVM_USE_SANITIZER) if (("${LLVM_USE_SANITIZER}" STREQUAL "Address") OR @@ -67,7 +75,7 @@ endif() endif() -# Generate library list. +# Generate private library list. add_library_flags_if(LIBCXX_HAS_PTHREAD_LIB pthread) add_library_flags_if(LIBCXX_HAS_C_LIB c) add_library_flags_if(LIBCXX_HAS_M_LIB m) @@ -75,6 +83,11 @@ add_library_flags_if(LIBCXX_HAS_GCC_S_LIB gcc_s) add_library_flags_if(LIBCXX_HAVE_CXX_ATOMICS_WITH_LIB atomic) +# Add the unwinder library. +if (LIBCXXABI_USE_LLVM_UNWINDER) + list(APPEND LIBCXX_LIBRARIES_PUBLIC unwind) +endif() + # Setup flags. if (NOT WIN32) add_flags_if_supported(-fPIC) @@ -151,7 +164,9 @@ # Build the shared library. if (LIBCXX_ENABLE_SHARED) add_library(cxx_shared SHARED $) - target_link_libraries(cxx_shared ${LIBCXX_LIBRARIES}) + target_link_libraries(cxx_shared + PRIVATE ${LIBCXX_LIBRARIES} + PUBLIC ${LIBCXX_LIBRARIES_PUBLIC}) set_target_properties(cxx_shared PROPERTIES LINK_FLAGS "${LIBCXX_LINK_FLAGS}" @@ -165,7 +180,9 @@ # Build the static library. if (LIBCXX_ENABLE_STATIC) add_library(cxx_static STATIC $) - target_link_libraries(cxx_static ${LIBCXX_LIBRARIES}) + target_link_libraries(cxx_static + PRIVATE ${LIBCXX_LIBRARIES} + PUBLIC ${LIBCXX_LIBRARIES_PUBLIC}) set_target_properties(cxx_static PROPERTIES LINK_FLAGS "${LIBCXX_LINK_FLAGS}" @@ -238,7 +255,7 @@ ${PYTHON_EXECUTABLE} ${LIBCXX_SOURCE_DIR}/utils/gen_link_script/gen_link_script.py ARGS "$" - "${SCRIPT_ABI_LIBNAME}" + "\"${LIBCXX_LIBRARIES_PUBLIC}\"" WORKING_DIRECTORY ${LIBCXX_BUILD_DIR} ) endif() Index: libcxx/trunk/utils/gen_link_script/gen_link_script.py =================================================================== --- libcxx/trunk/utils/gen_link_script/gen_link_script.py +++ libcxx/trunk/utils/gen_link_script/gen_link_script.py @@ -22,7 +22,7 @@ help_msg = \ """Usage - gen_link_script.py [--help] [--dryrun] + gen_link_script.py [--help] [--dryrun] Generate a linker script that links libc++ to the proper ABI library. The script replaces the specified libc++ symlink. @@ -31,8 +31,7 @@ Arguments - The top level symlink to the versioned libc++ shared library. This file is replaced with a linker script. - - The name of the ABI library to use in the linker script. - The name must be one of [c++abi, stdc++, supc++, cxxrt]. + - List of library names to include in linker script. Exit Status: 0 if OK, @@ -53,11 +52,11 @@ if len(args) != 2: usage_and_exit() symlink_file = args[0] - abi_libname = args[1] - return dryrun, symlink_file, abi_libname + public_libs = args[1].split(';') + return dryrun, symlink_file, public_libs def main(): - dryrun, symlink_file, abi_libname = parse_args() + dryrun, symlink_file, public_libs = parse_args() # Check that the given libc++.so file is a valid symlink. if not os.path.islink(symlink_file): @@ -66,15 +65,12 @@ # Read the symlink so we know what libc++ to link to in the linker script. linked_libcxx = os.readlink(symlink_file) - # Check that the abi_libname is one of the supported values. - supported_abi_list = ['c++abi', 'stdc++', 'supc++', 'cxxrt'] - if abi_libname not in supported_abi_list: - print_and_exit("abi name '%s' is not supported: Use one of %r" % - (abi_libname, supported_abi_list)) + # Prepare the list of public libraries to link. + public_libs = ['-l%s' % l for l in public_libs] # Generate the linker script contents and print the script and destination # information. - contents = "INPUT(%s -l%s)" % (linked_libcxx, abi_libname) + contents = "INPUT(%s %s)" % (linked_libcxx, ' '.join(public_libs)) print("GENERATING SCRIPT: '%s' as file %s" % (contents, symlink_file)) # Remove the existing libc++ symlink and replace it with the script.