From b0f915ac6981dc529e3aa27bfe13b93c067da83e Mon Sep 17 00:00:00 2001 From: Karoy Lorentey Date: Fri, 26 Sep 2025 23:51:16 -0700 Subject: [PATCH] =?UTF-8?q?=F0=9F=8D=92=201.1:=20build:=20Install=20librar?= =?UTF-8?q?ies=20in=20an=20`arch`=20sub-folder?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the proper installation scheme for Swift libraries on Windows and prevents having to manually copy them in `build.ps1`. Cherry-pick #505 --- CMakeLists.txt | 6 +-- Sources/CMakeLists.txt | 13 +++--- cmake/modules/SwiftSupport.cmake | 72 +++++++++++++++++++++----------- 3 files changed, 56 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5931546dc..d41eecb69 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,10 +15,7 @@ cmake_minimum_required(VERSION 3.16) project(SwiftCollections LANGUAGES C Swift) -list(APPEND CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules) - -set(CMAKE_Swift_MODULE_DIRECTORY ${CMAKE_BINARY_DIR}/swift) -set(CMAKE_Swift_COMPILE_OPTIONS_MSVC_RUNTIME_LIBRARY MultiThreadedDLL) +list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake/modules) if(NOT SWIFT_SYSTEM_NAME) if(CMAKE_SYSTEM_NAME STREQUAL Darwin) @@ -43,6 +40,7 @@ endif() option(COLLECTIONS_SINGLE_MODULE "Build as a single module" NO) option(COLLECTIONS_FOUNDATION_TOOLCHAIN_MODULE "Build a module for Foundation in the toolchain" NO) +option(COLLECTIONS_INSTALL_ARCH_SUBDIR "Install libraries under an architecture subdirectory" NO) if(COLLECTIONS_FOUNDATION_TOOLCHAIN_MODULE) set(COLLECTIONS_SINGLE_MODULE YES) diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index 7c4fe2a69..b574561cc 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -28,7 +28,6 @@ if(COLLECTIONS_SINGLE_MODULE) INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_Swift_MODULE_DIRECTORY}) if(COLLECTIONS_FOUNDATION_TOOLCHAIN_MODULE) - get_swift_host_os(swift_os) if(BUILD_SHARED_LIBS) # Install only the swift module and not the library set(swift swift) @@ -36,16 +35,16 @@ if(COLLECTIONS_SINGLE_MODULE) # Install both the swift module and the binary set(swift swift_static) install(TARGETS ${COLLECTIONS_MODULE_NAME} - ARCHIVE DESTINATION lib/swift_static/${swift_os} - LIBRARY DESTINATION lib/swift_static/${swift_os} + ARCHIVE DESTINATION lib/swift_static/${COLLECTIONS_PLATFORM}$<$:/${COLLECTIONS_ARCH}> + LIBRARY DESTINATION lib/swift_static/${COLLECTIONS_PLATFORM}$<$:/${COLLECTIONS_ARCH}> RUNTIME DESTINATION bin) endif() install(FILES $/${COLLECTIONS_MODULE_NAME}.swiftdoc - DESTINATION lib/${swift}/${swift_os}/${COLLECTIONS_MODULE_NAME}.swiftmodule - RENAME ${SwiftCollections_MODULE_TRIPLE}.swiftdoc) + DESTINATION lib/${swift}/${COLLECTIONS_PLATFORM}/${COLLECTIONS_MODULE_NAME}.swiftmodule + RENAME ${COLLECTIONS_MODULE_TRIPLE}.swiftdoc) install(FILES $/${COLLECTIONS_MODULE_NAME}.swiftmodule - DESTINATION lib/${swift}/${swift_os}/${COLLECTIONS_MODULE_NAME}.swiftmodule - RENAME ${SwiftCollections_MODULE_TRIPLE}.swiftmodule) + DESTINATION lib/${swift}/${COLLECTIONS_PLATFORM}/${COLLECTIONS_MODULE_NAME}.swiftmodule + RENAME ${COLLECTIONS_MODULE_TRIPLE}.swiftmodule) else() _install_target(${COLLECTIONS_MODULE_NAME}) endif() diff --git a/cmake/modules/SwiftSupport.cmake b/cmake/modules/SwiftSupport.cmake index 71e22c89b..59b29cfbb 100644 --- a/cmake/modules/SwiftSupport.cmake +++ b/cmake/modules/SwiftSupport.cmake @@ -8,32 +8,55 @@ See https://swift.org/LICENSE.txt for license information #]] -if(NOT SwiftCollections_MODULE_TRIPLE) - set(target_info_cmd "${CMAKE_Swift_COMPILER}" -print-target-info) +if(NOT COLLECTIONS_MODULE_TRIPLE OR NOT COLLECTIONS_ARCH OR NOT COLLECTIONS_PLATFORM) + # Get the target information from the Swift compiler. + set(module_triple_command "${CMAKE_Swift_COMPILER}" -print-target-info) if(CMAKE_Swift_COMPILER_TARGET) - list(APPEND target_info_cmd -target ${CMAKE_Swift_COMPILER_TARGET}) + list(APPEND module_triple_command -target ${CMAKE_Swift_COMPILER_TARGET}) endif() - execute_process(COMMAND ${target_info_cmd} OUTPUT_VARIABLE target_info_json) + execute_process(COMMAND ${module_triple_command} OUTPUT_VARIABLE target_info_json) +endif() +if(NOT COLLECTIONS_MODULE_TRIPLE) string(JSON module_triple GET "${target_info_json}" "target" "moduleTriple") - set(SwiftCollections_MODULE_TRIPLE "${module_triple}" CACHE STRING "Triple used for installed swift{doc,module, interface} files") - mark_as_advanced(SwiftCollections_MODULE_TRIPLE) + set(COLLECTIONS_MODULE_TRIPLE "${module_triple}" CACHE STRING "Triple used to install swiftmodule files") + mark_as_advanced(COLLECTIONS_MODULE_TRIPLE) + message(CONFIGURE_LOG "Swift module triple: ${module_triple}") endif() -# Returns the os name in a variable -# -# Usage: -# get_swift_host_os(result_var_name) -# -# -# Sets ${result_var_name} with the converted OS name derived from -# CMAKE_SYSTEM_NAME. -function(get_swift_host_os result_var_name) - set(${result_var_name} ${SWIFT_SYSTEM_NAME} PARENT_SCOPE) -endfunction() +if(NOT COLLECTIONS_ARCH) + if(CMAKE_Swift_COMPILER_VERSION VERSION_EQUAL 0.0.0 OR CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 6.2) + # For newer compilers, we can use the -print-target-info command to get the architecture. + string(JSON module_arch GET "${target_info_json}" "target" "arch") + else() + # For older compilers, extract the value from `COLLECTIONS_MODULE_TRIPLE`. + string(REGEX MATCH "^[^-]+" module_arch "${COLLECTIONS_MODULE_TRIPLE}") + endif() + + set(COLLECTIONS_ARCH "${module_arch}" CACHE STRING "Arch folder name used to install libraries") + mark_as_advanced(COLLECTIONS_ARCH) + message(CONFIGURE_LOG "Swift arch: ${COLLECTIONS_ARCH}") +endif() + +if(NOT COLLECTIONS_PLATFORM) + if(CMAKE_Swift_COMPILER_VERSION VERSION_EQUAL 0.0.0 OR CMAKE_Swift_COMPILER_VERSION VERSION_GREATER_EQUAL 6.2) + # For newer compilers, we can use the -print-target-info command to get the platform. + string(JSON swift_platform GET "${target_info_json}" "target" "platform") + else() + # For older compilers, compile the value from `CMAKE_SYSTEM_NAME`. + if(APPLE) + set(swift_platform macosx) + else() + set(swift_platform "$") + endif() + endif() + + set(COLLECTIONS_PLATFORM "${swift_platform}" CACHE STRING "Platform folder name used to install libraries") + mark_as_advanced(COLLECTIONS_PLATFORM) + message(CONFIGURE_LOG "Swift platform: ${COLLECTIONS_PLATFORM}") +endif() function(_install_target module) - get_swift_host_os(swift_os) get_target_property(type ${module} TYPE) if(type STREQUAL STATIC_LIBRARY) @@ -43,8 +66,8 @@ function(_install_target module) endif() install(TARGETS ${module} - ARCHIVE DESTINATION lib/${swift}/${swift_os} - LIBRARY DESTINATION lib/${swift}/${swift_os} + ARCHIVE DESTINATION lib/${swift}/${COLLECTIONS_PLATFORM}$<$:/${COLLECTIONS_ARCH}> + LIBRARY DESTINATION lib/${swift}/${COLLECTIONS_PLATFORM}$<$:/${COLLECTIONS_ARCH}> RUNTIME DESTINATION bin) if(type STREQUAL EXECUTABLE) return() @@ -56,9 +79,10 @@ function(_install_target module) endif() install(FILES $/${module_name}.swiftdoc - DESTINATION lib/${swift}/${swift_os}/${module_name}.swiftmodule - RENAME ${SwiftCollections_MODULE_TRIPLE}.swiftdoc) + DESTINATION lib/${swift}/${COLLECTIONS_PLATFORM}/${module_name}.swiftmodule + RENAME ${COLLECTIONS_MODULE_TRIPLE}.swiftdoc) + install(FILES $/${module_name}.swiftmodule - DESTINATION lib/${swift}/${swift_os}/${module_name}.swiftmodule - RENAME ${SwiftCollections_MODULE_TRIPLE}.swiftmodule) + DESTINATION lib/${swift}/${COLLECTIONS_PLATFORM}/${module_name}.swiftmodule + RENAME ${COLLECTIONS_MODULE_TRIPLE}.swiftmodule) endfunction()