From ed97c9c7088340aedb3deb5f8faeded79a9789bf Mon Sep 17 00:00:00 2001 From: Yuta Saito Date: Thu, 29 Aug 2024 12:46:38 +0000 Subject: [PATCH] CMake: Install `_TestingInternals` in static library builds When building the Testing library as a static library (BUILD_SHARED_LIBS=FALSE), `_TestingInternals` was not being installed alongside the main library. This caused the missing symbol error when linking against the Testing library statically. --- CMakeLists.txt | 1 + Sources/Testing/CMakeLists.txt | 7 ++++- Sources/_TestingInternals/CMakeLists.txt | 9 +++++++ cmake/modules/SwiftModuleInstallation.cmake | 30 ++++++++++++++++----- 4 files changed, 39 insertions(+), 8 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ef465083a..a8b5712ca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,4 +38,5 @@ if(NOT SWIFT_SYSTEM_NAME) endif() endif() +include(SwiftModuleInstallation) add_subdirectory(Sources) diff --git a/Sources/Testing/CMakeLists.txt b/Sources/Testing/CMakeLists.txt index 573f198a9..69b851645 100644 --- a/Sources/Testing/CMakeLists.txt +++ b/Sources/Testing/CMakeLists.txt @@ -94,11 +94,16 @@ add_library(Testing Traits/Trait.swift) target_link_libraries(Testing PRIVATE _TestingInternals) +if(NOT BUILD_SHARED_LIBS) + # When building a static library, tell clients to autolink the internal + # library. + target_compile_options(Testing PRIVATE + "SHELL:-Xfrontend -public-autolink-library -Xfrontend _TestingInternals") +endif() add_dependencies(Testing TestingMacros) target_compile_options(Testing PRIVATE -enable-library-evolution -emit-module-interface -emit-module-interface-path $/Testing.swiftinterface) -include(SwiftModuleInstallation) _swift_testing_install_target(Testing) diff --git a/Sources/_TestingInternals/CMakeLists.txt b/Sources/_TestingInternals/CMakeLists.txt index 128b0aa48..e33faeecf 100644 --- a/Sources/_TestingInternals/CMakeLists.txt +++ b/Sources/_TestingInternals/CMakeLists.txt @@ -17,3 +17,12 @@ target_include_directories(_TestingInternals PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}/include) target_compile_options(_TestingInternals PRIVATE -fno-exceptions) + +if(NOT BUILD_SHARED_LIBS) + # When building a static library, install the internal library archive + # alongside the main library. In shared library builds, the internal library + # is linked into the main library and does not need to be installed separately. + get_swift_install_lib_dir(STATIC_LIBRARY lib_destination_dir) + install(TARGETS _TestingInternals + ARCHIVE DESTINATION ${lib_destination_dir}) +endif() diff --git a/cmake/modules/SwiftModuleInstallation.cmake b/cmake/modules/SwiftModuleInstallation.cmake index 65c9f3c14..9f9ad7538 100644 --- a/cmake/modules/SwiftModuleInstallation.cmake +++ b/cmake/modules/SwiftModuleInstallation.cmake @@ -18,28 +18,44 @@ function(get_swift_host_os result_var_name) set(${result_var_name} ${SWIFT_SYSTEM_NAME} PARENT_SCOPE) endfunction() -function(_swift_testing_install_target module) +# Returns the path to the Swift Testing library installation directory +# +# Usage: +# get_swift_testing_install_lib_dir(type result_var_name) +# +# Arguments: +# type: The type of the library (STATIC_LIBRARY, SHARED_LIBRARY, or EXECUTABLE). +# Typically, the value of the TYPE target property. +# result_var_name: The name of the variable to set +function(get_swift_testing_install_lib_dir type result_var_name) get_swift_host_os(swift_os) - get_target_property(type ${module} TYPE) - if(type STREQUAL STATIC_LIBRARY) set(swift swift_static) else() set(swift swift) endif() + if(APPLE) + set(${result_var_name} "lib/${swift}/${swift_os}/testing" PARENT_SCOPE) + else() + set(${result_var_name} "lib/${swift}/${swift_os}" PARENT_SCOPE) + endif() +endfunction() + +function(_swift_testing_install_target module) target_compile_options(Testing PRIVATE "-no-toolchain-stdlib-rpath") - if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") - set(lib_destination_dir "lib/${swift}/${swift_os}/testing") + if(APPLE) set_property(TARGET ${module} PROPERTY INSTALL_RPATH "@loader_path/..") else() - set(lib_destination_dir "lib/${swift}/${swift_os}") set_property(TARGET ${module} PROPERTY INSTALL_RPATH "$ORIGIN") endif() + get_target_property(type ${module} TYPE) + get_swift_testing_install_lib_dir(${type} lib_destination_dir) + install(TARGETS ${module} ARCHIVE DESTINATION "${lib_destination_dir}" LIBRARY DESTINATION "${lib_destination_dir}" @@ -71,7 +87,7 @@ function(_swift_testing_install_target module) install(FILES $/${module_name}.swiftmodule DESTINATION "${module_dir}" RENAME ${SwiftTesting_MODULE_TRIPLE}.swiftmodule) - if(CMAKE_SYSTEM_NAME STREQUAL "Darwin") + if(APPLE) # Only Darwin has stable ABI. install(FILES $/${module_name}.swiftinterface DESTINATION "${module_dir}"