From 7a8ab198364dfe3405d36eea89e6eb5fba9be2c8 Mon Sep 17 00:00:00 2001 From: Saleem Abdulrasool Date: Mon, 14 Jul 2025 16:49:34 -0700 Subject: [PATCH] build: add support for installing the image This replicates much of the logic from the new runtimes build to support installing the Swift interface and the runtime components. Additionally, we are now able to generate the targets configuration to allow dependencies between projects. --- CMakeLists.txt | 30 ++++++++++-- Sources/Subprocess/CMakeLists.txt | 8 +++ Sources/_SubprocessCShims/CMakeLists.txt | 3 ++ cmake/modules/EmitSwiftInterface.cmake | 60 +++++++++++++++++++++++ cmake/modules/InstallSwiftInterface.cmake | 23 +++++++++ cmake/modules/PlatformInfo.cmake | 43 ++++++++++++++++ 6 files changed, 164 insertions(+), 3 deletions(-) create mode 100644 cmake/modules/EmitSwiftInterface.cmake create mode 100644 cmake/modules/InstallSwiftInterface.cmake create mode 100644 cmake/modules/PlatformInfo.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 8129705..f07181f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,11 +10,35 @@ ##===----------------------------------------------------------------------===## cmake_minimum_required(VERSION 3.26...3.29) -project(Subprocess LANGUAGES C Swift) -list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") -add_compile_options("$<$:SHELL:-package-name ${PROJECT_NAME}>") +set(CMAKE_C_VISIBILITY_PRESET "hidden") +project(Subprocess + LANGUAGES C Swift) + +list(APPEND CMAKE_MODULE_PATH + "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") + +include(EmitSwiftInterface) +include(GNUInstallDirs) include(InstallExternalDependencies) +include(PlatformInfo) +include(InstallSwiftInterface) + +option(${PROJECT_NAME}_INSTALL_NESTED_SUBDIR "Install libraries under a platform and architecture subdirectory" ON) +set(${PROJECT_NAME}_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/swift$<$>:_static>$<$:/${${PROJECT_NAME}_PLATFORM_SUBDIR}/${${PROJECT_NAME}_ARCH_SUBDIR}>") +set(${PROJECT_NAME}_INSTALL_SWIFTMODULEDIR "${CMAKE_INSTALL_LIBDIR}/swift$<$>:_static>$<$:/${${PROJECT_NAME}_PLATFORM_SUBDIR}>") + +option(${PROJECT_NAME}_ENABLE_LIBRARY_EVOLUTION "Generate ABI resilient runtime libraries" NO) +option(${PROJECT_NAME}_ENABLE_PRESPECIALIZATION "Enable generic metadata prespecialization" NO) + +add_compile_options( + "$<$:SHELL:-package-name ${PROJECT_NAME}>" + "$<$,$>:-enable-library-evolution>" + "$<$,$>:SHELL:-Xfrontend -prespecialize-generic-metadata>") add_subdirectory(Sources) + +export(EXPORT SwiftSubprocessTargets + FILE "cmake/SwiftSubprocess/SwiftSubprocessTargets.cmake" + NAMESPACE "SwiftSubprocess::") diff --git a/Sources/Subprocess/CMakeLists.txt b/Sources/Subprocess/CMakeLists.txt index 1142445..dea6cd6 100644 --- a/Sources/Subprocess/CMakeLists.txt +++ b/Sources/Subprocess/CMakeLists.txt @@ -46,3 +46,11 @@ target_link_libraries(Subprocess PUBLIC _SubprocessCShims) target_link_libraries(Subprocess PRIVATE SwiftSystem::SystemPackage) + +install(TARGETS Subprocess + EXPORT SwiftSubprocessTargets + ARCHIVE DESTINATION "${${PROJECT_NAME}_INSTALL_LIBDIR}" + LIBRARY DESTINATION "${${PROJECT_NAME}_INSTALL_LIBDIR}" + RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}") +emit_swift_interface(Subprocess) +install_swift_interface(Subprocess) diff --git a/Sources/_SubprocessCShims/CMakeLists.txt b/Sources/_SubprocessCShims/CMakeLists.txt index 131bc8e..4c152ee 100644 --- a/Sources/_SubprocessCShims/CMakeLists.txt +++ b/Sources/_SubprocessCShims/CMakeLists.txt @@ -13,3 +13,6 @@ add_library(_SubprocessCShims STATIC process_shims.c) target_include_directories(_SubprocessCShims PUBLIC include) + +install(TARGETS _SubprocessCShims + EXPORT SwiftSubprocessTargets) diff --git a/cmake/modules/EmitSwiftInterface.cmake b/cmake/modules/EmitSwiftInterface.cmake new file mode 100644 index 0000000..7f4f489 --- /dev/null +++ b/cmake/modules/EmitSwiftInterface.cmake @@ -0,0 +1,60 @@ +##===----------------------------------------------------------------------===## +## +## This source file is part of the Swift.org open source project +## +## Copyright (c) 2025 Apple Inc. and the Swift project authors +## Licensed under Apache License v2.0 with Runtime Library Exception +## +## See https://swift.org/LICENSE.txt for license information +## +##===----------------------------------------------------------------------===## + +function(emit_swift_interface target) + # Generate the target-variant binary swift module when performing zippered + # build + # + # Clean this up once CMake has nested swiftmodules in the build directory: + # https://gitlab.kitware.com/cmake/cmake/-/merge_requests/10664 + # https://cmake.org/cmake/help/git-stage/policy/CMP0195.html + + # We can't expand the Swift_MODULE_NAME target property in a generator + # expression or it will fail saying that the target doesn't exist. + get_target_property(module_name ${target} Swift_MODULE_NAME) + if(NOT module_name) + set(module_name ${target}) + endif() + + # Account for an existing swiftmodule file generated with the previous logic + if(EXISTS "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule" + AND NOT IS_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule") + message(STATUS "Removing regular file ${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule to support nested swiftmodule generation") + file(REMOVE "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule") + endif() + + target_compile_options(${target} PRIVATE + "$<$:SHELL:-emit-module-path ${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule/${${PROJECT_NAME}_MODULE_TRIPLE}.swiftmodule>") + if(${PROJECT_NAME}_VARIANT_MODULE_TRIPLE) + target_compile_options(${target} PRIVATE + "$<$:SHELL:-emit-variant-module-path ${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule/${${PROJECT_NAME}_VARIANT_MODULE_TRIPLE}.swiftmodule>") + endif() + add_custom_command(OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule/${${PROJECT_NAME}_MODULE_TRIPLE}.swiftmodule" + DEPENDS ${target}) + target_sources(${target} + INTERFACE + $) + + # Generate textual swift interfaces is library-evolution is enabled + if(${PROJECT_NAME}_ENABLE_LIBRARY_EVOLUTION) + target_compile_options(${target} PRIVATE + $<$:-emit-module-interface-path$${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule/${${PROJECT_NAME}_MODULE_TRIPLE}.swiftinterface> + $<$:-emit-private-module-interface-path$${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule/${${PROJECT_NAME}_MODULE_TRIPLE}.private.swiftinterface>) + if(${PROJECT_NAME}_VARIANT_MODULE_TRIPLE) + target_compile_options(${target} PRIVATE + "$<$:SHELL:-emit-variant-module-interface-path ${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule/${${PROJECT_NAME}_VARIANT_MODULE_TRIPLE}.swiftinterface>" + "$<$:SHELL:-emit-variant-private-module-interface-path ${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule/${${PROJECT_NAME}_VARIANT_MODULE_TRIPLE}.private.swiftinterface>") + endif() + target_compile_options(${target} PRIVATE + $<$:-library-level$api> + $<$:-Xfrontend$-require-explicit-availability=ignore>) + endif() +endfunction() diff --git a/cmake/modules/InstallSwiftInterface.cmake b/cmake/modules/InstallSwiftInterface.cmake new file mode 100644 index 0000000..73b18b4 --- /dev/null +++ b/cmake/modules/InstallSwiftInterface.cmake @@ -0,0 +1,23 @@ +##===----------------------------------------------------------------------===## +## +## This source file is part of the Swift.org open source project +## +## Copyright (c) 2025 Apple Inc. and the Swift project authors +## Licensed under Apache License v2.0 with Runtime Library Exception +## +## See https://swift.org/LICENSE.txt for license information +## +##===----------------------------------------------------------------------===## + +# Install the generated swift interface files for the target. +function(install_swift_interface target) + # Swiftmodules are already in the directory structure + get_target_property(module_name ${target} Swift_MODULE_NAME) + if(NOT module_name) + set(module_name ${target}) + endif() + + install(DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/${module_name}.swiftmodule" + DESTINATION "${${PROJECT_NAME}_INSTALL_SWIFTMODULEDIR}" + COMPONENT SwiftSubprocess_development) +endfunction() diff --git a/cmake/modules/PlatformInfo.cmake b/cmake/modules/PlatformInfo.cmake new file mode 100644 index 0000000..6680a63 --- /dev/null +++ b/cmake/modules/PlatformInfo.cmake @@ -0,0 +1,43 @@ +##===----------------------------------------------------------------------===## +## +## This source file is part of the Swift.org open source project +## +## Copyright (c) 2025 Apple Inc. and the Swift project authors +## Licensed under Apache License v2.0 with Runtime Library Exception +## +## See https://swift.org/LICENSE.txt for license information +## +##===----------------------------------------------------------------------===## + +# TODO: This logic should migrate to CMake once CMake supports installing swiftmodules +set(module_triple_command "${CMAKE_Swift_COMPILER}" -print-target-info) +if(CMAKE_Swift_COMPILER_TARGET) + list(APPEND module_triple_command -target ${CMAKE_Swift_COMPILER_TARGET}) +endif() +execute_process(COMMAND ${module_triple_command} OUTPUT_VARIABLE target_info_json) +message(CONFIGURE_LOG "Swift target info: ${module_triple_command}\n" +"${target_info_json}") + +if(NOT ${PROJECT_NAME}_MODULE_TRIPLE) + string(JSON module_triple GET "${target_info_json}" "target" "moduleTriple") + set(${PROJECT_NAME}_MODULE_TRIPLE "${module_triple}" CACHE STRING "Triple used for installed swift{doc,module,interface} files") + mark_as_advanced(${PROJECT_NAME}_MODULE_TRIPLE) + + message(CONFIGURE_LOG "Swift module triple: ${module_triple}") +endif() + +if(NOT ${PROJECT_NAME}_PLATFORM_SUBDIR) + string(JSON platform GET "${target_info_json}" "target" "platform") + set(${PROJECT_NAME}_PLATFORM_SUBDIR "${platform}" CACHE STRING "Platform name used for installed swift{doc,module,interface} files") + mark_as_advanced(${PROJECT_NAME}_PLATFORM_SUBDIR) + + message(CONFIGURE_LOG "Swift platform: ${platform}") +endif() + +if(NOT ${PROJECT_NAME}_ARCH_SUBDIR) + string(JSON arch GET "${target_info_json}" "target" "arch") + set(${PROJECT_NAME}_ARCH_SUBDIR "${arch}" CACHE STRING "Architecture used for setting the architecture subdirectory") + mark_as_advanced(${PROJECT_NAME}_ARCH_SUBDIR) + + message(CONFIGURE_LOG "Swift Arch: ${arch}") +endif()