Skip to content

Commit 3172730

Browse files
authored
Merge pull request #78887 from compnerd/overlay
Runtimes: create an Overlay project
2 parents aadf874 + c54dfe6 commit 3172730

12 files changed

+431
-0
lines changed

Runtimes/Overlay/CMakeLists.txt

+52
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
2+
cmake_minimum_required(VERSION 3.26...3.29)
3+
4+
set(CMAKE_C_VISIBILITY_PRESET "hidden")
5+
set(CMAKE_CXX_VISIBILITY_PRESET "hidden")
6+
set(CMAKE_VISIBILITY_INLINES_HIDDEN YES)
7+
8+
list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/modules")
9+
10+
# NOTE: always use the 3-component style as the expansion as
11+
# `${PROJECT_VERSION}` will not extend this to the complete form and this can
12+
# change the behaviour for comparison with non-SemVer compliant parsing. If
13+
# possible, use the 4-version component as that is used to differentiate the
14+
# builds of the runtime for Windows.
15+
if($ENV{BUILD_NUMBER})
16+
# NOTE: SxS modules have a limit on each component being [0-65535].
17+
# https://learn.microsoft.com/en-us/windows/win32/sbscs/assembly-versions
18+
math(EXPR BUILD_NUMBER "$ENV{BUILD_NUMBER} % 65535")
19+
set(BUILD_NUMBER ".${BUILD_NUMBER}")
20+
endif()
21+
project(SwiftOverlay
22+
LANGUAGES C CXX Swift
23+
VERSION 6.1.0${BUILD_NUMBER})
24+
25+
# FIXME: We should not need to refer back into the compiler sources. This is
26+
# needed by gyb and AvailabilityMacros
27+
set(SwiftOverlay_SWIFTC_SOURCE_DIR
28+
"${PROJECT_SOURCE_DIR}/../../"
29+
CACHE FILEPATH "Path to the root source directory of the Swift compiler")
30+
31+
include(GNUInstallDirs)
32+
33+
include(gyb)
34+
include(AvailabilityMacros)
35+
include(DefaultSettings)
36+
include(EmitSwiftInterface)
37+
include(PlatformInfo)
38+
include(ResourceEmbedding)
39+
40+
defaulted_option(SwiftOverlay_ENABLE_REFLECTION "Enable runtime support for mirrors and reflection support")
41+
42+
option(SwiftOverlay_INSTALL_NESTED_SUBDIR "Install libraries under a platform and architecture subdirectory" ON)
43+
set(SwiftOverlay_INSTALL_LIBDIR "${CMAKE_INSTALL_LIBDIR}/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>$<$<BOOL:${SwiftOverlay_INSTALL_NESTED_SUBDIR}>:/${SwiftOverlay_PLATFORM_SUBDIR}/${SwiftOverlay_ARCH_SUBDIR}>")
44+
set(SwiftOverlay_INSTALL_SWIFTMODULEDIR "${CMAKE_INSTALL_LIBDIR}/swift$<$<NOT:$<BOOL:${BUILD_SHARED_LIBS}>>:_static>$<$<BOOL:${SwiftOverlay_INSTALL_NESTED_SUBDIR}>:/${SwiftOverlay_PLATFORM_SUBDIR}>")
45+
46+
add_compile_options(
47+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-concurrency-module-import>"
48+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -disable-implicit-string-processing-module-import>")
49+
50+
if(WIN32)
51+
add_subdirectory(Windows)
52+
endif()
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
2+
add_subdirectory(clang)
3+
add_subdirectory(CRT)
4+
add_subdirectory(WinSDK)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
2+
gyb_expand(tgmath.swift.gyb tgmath.swift)
3+
4+
add_library(swiftCRT
5+
tgmath.swift
6+
ucrt.swift
7+
Platform.swift
8+
POSIXError.swift
9+
TiocConstants.swift)
10+
set_target_properties(swiftCRT PROPERTIES
11+
Swift_MODULE_NAME CRT)
12+
target_compile_definitions(swiftCRT PRIVATE
13+
$<$<BOOL:${SwiftOverlay_ENABLE_REFLECTION}>:SWIFT_ENABLE_REFLECTION>)
14+
target_compile_options(swiftCRT PRIVATE
15+
"SHELL:-Xcc -D_USE_MATH_DEFINES")
16+
17+
install(TARGETS swiftCRT
18+
ARCHIVE DESTINATION "${SwiftOverlay_INSTALL_LIBDIR}"
19+
LIBRARY DESTINATION "${SwiftOverlay_INSTALL_LIBDIR}"
20+
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
21+
emit_swift_interface(swiftCRT)
22+
install_swift_interface(swiftCRT)
23+
24+
embed_manifest(swiftCRT)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
2+
add_library(swiftWinSDK
3+
WinSDK.swift)
4+
set_target_properties(swiftWinSDK PROPERTIES
5+
Swift_MODULE_NAME WinSDK)
6+
target_compile_definitions(swiftCRT PRIVATE
7+
$<$<BOOL:${SwiftOverlay_ENABLE_REFLECTION}>:SWIFT_ENABLE_REFLECTION>)
8+
9+
install(TARGETS swiftWinSDK
10+
ARCHIVE DESTINATION "${SwiftOverlay_INSTALL_LIBDIR}"
11+
LIBRARY DESTINATION "${SwiftOverlay_INSTALL_LIBDIR}"
12+
RUNTIME DESTINATION "${CMAKE_INSTALL_BINDIR}")
13+
emit_swift_interface(swiftWinSDK)
14+
install_swift_interface(swiftWinSDK)
15+
16+
embed_manifest(swiftWinSDK)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
2+
install(FILES
3+
ucrt.modulemap
4+
vcruntime.apinotes
5+
vcruntime.modulemap
6+
winsdk.modulemap
7+
DESTINATION ${CMAKE_INSTALL_DATAROOTDIR})
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
file(STRINGS "${SwiftOverlay_SWIFTC_SOURCE_DIR}/utils/availability-macros.def" availability_defs)
2+
list(FILTER availability_defs EXCLUDE REGEX "^\\s*(#.*)?$")
3+
foreach(def ${availability_defs})
4+
add_compile_options("$<$<COMPILE_LANGUAGE:Swift>:SHELL:-Xfrontend -define-availability -Xfrontend \"${def}\">")
5+
endforeach()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# This file is designed to setup reasonable defaults for the various settings so
2+
# that configuring a build for a given platform is likely to build
3+
# out-of-the-box without customization. This does not mean that it is the only
4+
# way that will work, or that it represents a shipping configuration.
5+
# User-specified configurations should be done through cache files or by setting
6+
# the variable with `-DSwiftOverlay_*` on the commandline.
7+
8+
# Provide a boolean option that a user can optionally enable.
9+
# Variables are defaulted based on the value of `<variable>_default`.
10+
# If no such default variable exists, the option is defaults to `OFF`.
11+
macro(defaulted_option variable helptext)
12+
if(NOT DEFINED ${variable}_default)
13+
set(${variable}_default OFF)
14+
endif()
15+
option(${variable} ${helptext} ${${variable}_default})
16+
endmacro()
17+
18+
# Create a defaulted cache entry
19+
# Entries are defaulted on the value of `<variable>_default`.
20+
# If no such default variable exists, the variable is not created.
21+
macro(defaulted_set variable type helptext)
22+
if(DEFINED ${variable}_default)
23+
set(${variable} ${${variable}_default} CACHE ${type} ${helptext})
24+
endif()
25+
endmacro()
26+
27+
if(APPLE)
28+
set(SwiftOverlay_ENABLE_REFLECTION_default ON)
29+
elseif(CMAKE_SYSTEM_NAME STREQUAL "WASM")
30+
set(SwiftOverlay_ENABLE_REFLECTION_default OFF)
31+
elseif(LINUX OR ANDROID OR BSD)
32+
set(SwiftOverlay_ENABLE_REFLECTION_default OFF)
33+
elseif(WIN32)
34+
set(SwiftOverlay_ENABLE_REFLECTION_default OFF)
35+
endif()
36+
37+
include("${SwiftOverlay_VENDOR_MODULE_DIR}/DefaultSettings.cmake" OPTIONAL)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
# Generate and install swift interface files
2+
3+
# TODO: CMake should learn how to model library evolution and generate this
4+
# stuff automatically.
5+
6+
7+
# Generate a swift interface file for the target if library evolution is enabled
8+
function(emit_swift_interface target)
9+
# Generate the target-variant binary swift module when performing zippered
10+
# build
11+
if(SwiftOverlay_VARIANT_MODULE_TRIPLE)
12+
set(variant_module_tmp_dir "${CMAKE_CURRENT_BINARY_DIR}/${target}-${SwiftOverlay_VARIANT_MODULE_TRIPLE}")
13+
file(MAKE_DIRECTORY "${variant_module_tmp_dir}")
14+
target_compile_options(${target} PRIVATE
15+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-emit-variant-module-path ${variant_module_tmp_dir}/${target}.swiftmodule>")
16+
endif()
17+
18+
# Generate textual swift interfaces is library-evolution is enabled
19+
if(SwiftOverlay_ENABLE_LIBRARY_EVOLUTION)
20+
target_compile_options(${target} PRIVATE
21+
$<$<COMPILE_LANGUAGE:Swift>:-emit-module-interface-path$<SEMICOLON>${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftinterface>
22+
$<$<COMPILE_LANGUAGE:Swift>:-emit-private-module-interface-path$<SEMICOLON>${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.private.swiftinterface>
23+
$<$<COMPILE_LANGUAGE:Swift>:-library-level$<SEMICOLON>api>
24+
$<$<COMPILE_LANGUAGE:Swift>:-Xfrontend$<SEMICOLON>-require-explicit-availability=ignore>)
25+
26+
# Emit catalyst swiftmodules and interfaces
27+
if(SwiftOverlay_VARIANT_MODULE_TRIPLE)
28+
target_compile_options(${target} PRIVATE
29+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-emit-variant-module-interface-path ${variant_module_tmp_dir}/${target}.swiftinterface>"
30+
"$<$<COMPILE_LANGUAGE:Swift>:SHELL:-emit-variant-private-module-interface-path ${variant_module_tmp_dir}/${target}.private.swiftinterface>")
31+
endif()
32+
endif()
33+
endfunction()
34+
35+
# Install the generated swift interface file for the target if library evolution
36+
# is enabled.
37+
function(install_swift_interface target)
38+
# Install binary swift modules
39+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftmodule"
40+
RENAME "${SwiftOverlay_MODULE_TRIPLE}.swiftmodule"
41+
DESTINATION "${SwiftOverlay_INSTALL_SWIFTMODULEDIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftmodule")
42+
if(SwiftOverlay_VARIANT_MODULE_TRIPLE)
43+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${target}-${SwiftOverlay_VARIANT_MODULE_TRIPLE}/${target}.swiftmodule"
44+
RENAME "${SwiftOverlay_VARIANT_MODULE_TRIPLE}.swiftmodule"
45+
DESTINATION "${SwiftOverlay_INSTALL_SWIFTMODULEDIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftmodule")
46+
endif()
47+
48+
# Install Swift interfaces if library-evolution is enabled
49+
if(SwiftOverlay_ENABLE_LIBRARY_EVOLUTION)
50+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftinterface"
51+
RENAME "${SwiftOverlay_MODULE_TRIPLE}.swiftinterface"
52+
DESTINATION "${SwiftOverlay_INSTALL_SWIFTMODULEDIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftmodule")
53+
54+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.private.swiftinterface"
55+
RENAME "${SwiftOverlay_MODULE_TRIPLE}.private.swiftinterface"
56+
DESTINATION "${SwiftOverlay_INSTALL_SWIFTMODULEDIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftmodule")
57+
58+
# Install catalyst interface files
59+
if(SwiftOverlay_VARIANT_MODULE_TRIPLE)
60+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${target}-${SwiftOverlay_VARIANT_MODULE_TRIPLE}/${target}.swiftinterface"
61+
RENAME "${SwiftOverlay_VARIANT_MODULE_TRIPLE}.swiftinterface"
62+
DESTINATION "${SwiftOverlay_INSTALL_SWIFTMODULEDIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftmodule")
63+
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${target}-${SwiftOverlay_VARIANT_MODULE_TRIPLE}/${target}.private.swiftinterface"
64+
RENAME "${SwiftOverlay_VARIANT_MODULE_TRIPLE}.private.swiftinterface"
65+
DESTINATION "${SwiftOverlay_INSTALL_SWIFTMODULEDIR}/$<TARGET_PROPERTY:${target},Swift_MODULE_NAME>.swiftmodule")
66+
endif()
67+
endif()
68+
endfunction()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# TODO: This logic should migrate to CMake once CMake supports installing swiftmodules
2+
set(module_triple_command "${CMAKE_Swift_COMPILER}" -print-target-info)
3+
if(CMAKE_Swift_COMPILER_TARGET)
4+
list(APPEND module_triple_command -target ${CMAKE_Swift_COMPILER_TARGET})
5+
endif()
6+
execute_process(COMMAND ${module_triple_command} OUTPUT_VARIABLE target_info_json)
7+
message(CONFIGURE_LOG "Swift target info: ${module_triple_command}\n"
8+
"${target_info_json}")
9+
10+
if(NOT SwiftOverlay_MODULE_TRIPLE)
11+
string(JSON module_triple GET "${target_info_json}" "target" "moduleTriple")
12+
set(SwiftOverlay_MODULE_TRIPLE "${module_triple}" CACHE STRING "Triple used for installed swift{doc,module,interface} files")
13+
mark_as_advanced(SwiftOverlay_MODULE_TRIPLE)
14+
15+
message(CONFIGURE_LOG "Swift module triple: ${module_triple}")
16+
endif()
17+
18+
if(NOT SwiftOverlay_PLATFORM_SUBDIR)
19+
string(JSON platform GET "${target_info_json}" "target" "platform")
20+
set(SwiftOverlay_PLATFORM_SUBDIR "${platform}" CACHE STRING "Platform name used for installed swift{doc,module,interface} files")
21+
mark_as_advanced(SwiftOverlay_PLATFORM_SUBDIR)
22+
23+
message(CONFIGURE_LOG "Swift platform: ${platform}")
24+
endif()
25+
26+
if(NOT SwiftOverlay_ARCH_SUBDIR)
27+
string(JSON arch GET "${target_info_json}" "target" "arch")
28+
set(SwiftOverlay_ARCH_SUBDIR "${arch}" CACHE STRING "Architecture used for setting the architecture subdirectory")
29+
mark_as_advanced(SwiftOverlay_ARCH_SUBDIR)
30+
31+
message(CONFIGURE_LOG "Swift Arch: ${arch}")
32+
endif()
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
function(generate_plist project_name project_version target)
2+
set(PLIST_INFO_PLIST "Info.plist")
3+
set(PLIST_INFO_NAME "${project_name}")
4+
5+
# Underscores aren't permitted in the bundle identifier.
6+
string(REPLACE "_" "" PLIST_INFO_UTI "com.apple.dt.runtime.${PLIST_INFO_NAME}")
7+
set(PLIST_INFO_VERSION "${project_version}")
8+
set(PLIST_INFO_BUILD_VERSION "${project_version}")
9+
10+
set(PLIST_INFO_PLIST_OUT "${PLIST_INFO_PLIST}")
11+
set(PLIST_INFO_PLIST_IN "${PROJECT_SOURCE_DIR}/${PLIST_INFO_PLIST}.in")
12+
13+
if(APPLE)
14+
target_link_options(${target} PRIVATE
15+
"SHELL:-Xlinker -sectcreate -Xlinker __TEXT -Xlinker __info_plist -Xlinker ${CMAKE_CURRENT_BINARY_DIR}/${PLIST_INFO_PLIST_OUT}")
16+
endif()
17+
18+
configure_file(
19+
"${PLIST_INFO_PLIST_IN}"
20+
"${PLIST_INFO_PLIST_OUT}"
21+
@ONLY
22+
NEWLINE_STYLE UNIX)
23+
24+
set_property(TARGET ${target} APPEND PROPERTY LINK_DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${PLIST_INFO_PLIST_OUT}")
25+
26+
# If Application Extensions are enabled, pass the linker flag marking
27+
# the dylib as safe.
28+
if (CXX_SUPPORTS_FAPPLICATION_EXTENSION AND (NOT DISABLE_APPLICATION_EXTENSION))
29+
list(APPEND link_flags "-Wl,-application_extension")
30+
endif()
31+
endfunction()
32+
33+
# FIXME: it appears that `CMAKE_MT` evaluates to an empty string which prevents
34+
# the use of the variable. This aliases `MT` to `CMAKE_MT` and tries to fallback
35+
# to known spellings for the tool.
36+
if(WIN32 AND BUILD_SHARED_LIBS)
37+
find_program(MT HINTS ${CMAKE_MT} NAMES mt llvm-mt REQUIRED)
38+
endif()
39+
40+
function(embed_manifest target)
41+
get_target_property(_EM_TARGET_TYPE ${target} TYPE)
42+
if(NOT "${_EM_TARGET_TYPE}" MATCHES "SHARED_LIBRARY|EXECUTABLE")
43+
return()
44+
endif()
45+
46+
get_target_property(_EM_BINARY_DIR ${target} BINARY_DIR)
47+
get_target_property(_EM_NAME ${target} NAME)
48+
49+
# Evaluate variables
50+
file(CONFIGURE
51+
OUTPUT ${_EM_BINARY_DIR}/${_EM_NAME}-${PROJECT_VERSION}.1.manifest.in
52+
CONTENT [[<?xml version="1.0" encoding="utf-8" standalone="yes"?>
53+
<assembly manifestversion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
54+
<assemblyIdentity
55+
name="$<TARGET_NAME:@target@>"
56+
processorArchitecture="@CMAKE_SYSTEM_PROCESSOR@"
57+
type="win32"
58+
version="@PROJECT_VERSION@" />
59+
<file name="$<TARGET_FILE_NAME:@target@>" />
60+
</assembly>]])
61+
# Evaluate generator expression
62+
file(GENERATE
63+
OUTPUT ${_EM_BINARY_DIR}/${_EM_NAME}-${PROJECT_VERSION}.1.manifest
64+
INPUT ${_EM_BINARY_DIR}/${_EM_NAME}-${PROJECT_VERSION}.1.manifest.in)
65+
66+
if(WIN32)
67+
add_custom_command(TARGET ${target} POST_BUILD
68+
COMMAND "${MT}" -nologo -manifest "${_EM_BINARY_DIR}/${_EM_NAME}-${PROJECT_VERSION}.1.manifest" "-outputresource:$<TARGET_FILE:${target}>;#1")
69+
endif()
70+
endfunction()
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
find_package(Python3 REQUIRED)
2+
3+
# Create a target to expand a gyb source
4+
# target_name: Name of the target
5+
# FLAGS list of flags passed to gyb
6+
# DEPENDS list of dependencies
7+
# COMMENT Custom comment
8+
function(gyb_expand source output)
9+
set(flags)
10+
set(arguments)
11+
set(multival_arguments FLAGS DEPENDS)
12+
cmake_parse_arguments(GYB "${flags}" "${arguments}" "${multival_arguments}" ${ARGN})
13+
14+
get_filename_component(full_output_path ${output} ABSOLUTE BASE_DIR "${CMAKE_CURRENT_BINARY_DIR}")
15+
get_filename_component(dir "${full_output_path}" DIRECTORY)
16+
get_filename_component(fname "${full_output_path}" NAME)
17+
18+
file(READ "${source}" gyb_src)
19+
string(REGEX MATCHALL "\\\$\{[\r\n\t ]*gyb.expand\\\([\r\n\t ]*[\'\"]([^\'\"]*)[\'\"]" gyb_expand_matches "${gyb_src}")
20+
foreach(match ${gyb_expand_matches})
21+
string(REGEX MATCH "[\'\"]\([^\'\"]*\)[\'\"]" gyb_dep "${match}")
22+
list(APPEND gyb_expand_deps "${CMAKE_MATCH_1}")
23+
endforeach()
24+
list(REMOVE_DUPLICATES gyb_expand_deps)
25+
26+
set(utils_dir "${SwiftOverlay_SWIFTC_SOURCE_DIR}/utils/")
27+
set(gyb_tool "${utils_dir}/gyb")
28+
29+
# All the tidbits to track for changes
30+
list(APPEND GYB_DEPENDS
31+
"${source}"
32+
"${utils_dir}/GYBUnicodeDataUtils.py"
33+
"${utils_dir}/SwiftIntTypes.py"
34+
"${utils_dir}/SwiftFloatingPointTypes.py"
35+
"${utils_dir}/UnicodeData/GraphemeBreakProperty.txt"
36+
"${utils_dir}/UnicodeData/GraphemeBreakTest.txt"
37+
"${utils_dir}/gyb_stdlib_support.py")
38+
add_custom_command(
39+
OUTPUT "${full_output_path}"
40+
COMMAND "${CMAKE_COMMAND}" -E make_directory "${dir}"
41+
COMMAND "${CMAKE_COMMAND}" -E env "$<TARGET_FILE:Python3::Interpreter>" "${gyb_tool}" ${GYB_FLAGS} -o "${full_output_path}.tmp" "${source}"
42+
COMMAND "${CMAKE_COMMAND}" -E copy_if_different "${full_output_path}.tmp" "${full_output_path}"
43+
COMMAND "${CMAKE_COMMAND}" -E remove "${full_output_path}.tmp"
44+
DEPENDS ${gyb_tool} ${gyb_tool}.py ${GYB_DEPENDS} ${gyb_expand_deps}
45+
COMMENT "Generating GYB source ${fname} from ${source}"
46+
WORKING_DIRECTORY "${CMAKE_CURRENT_SOURCE_DIR}")
47+
endfunction()

0 commit comments

Comments
 (0)