Skip to content

Commit c94abaf

Browse files
authored
Merge pull request #25330 from jckarter/SR-10600-back-deploy-5.1
[5.1] Introduce a backward-deployment library for SR-10600.
2 parents a12d9a4 + 31206ea commit c94abaf

File tree

23 files changed

+412
-39
lines changed

23 files changed

+412
-39
lines changed

cmake/modules/AddSwift.cmake

Lines changed: 36 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -705,7 +705,8 @@ function(_add_swift_library_single target name)
705705
OBJECT_LIBRARY
706706
SHARED
707707
STATIC
708-
TARGET_LIBRARY)
708+
TARGET_LIBRARY
709+
INSTALL_WITH_SHARED)
709710
set(SWIFTLIB_SINGLE_single_parameter_options
710711
ARCHITECTURE
711712
DEPLOYMENT_VERSION_IOS
@@ -1083,18 +1084,24 @@ function(_add_swift_library_single target name)
10831084
BINARY_DIR ${SWIFT_RUNTIME_OUTPUT_INTDIR}
10841085
LIBRARY_DIR ${SWIFT_LIBRARY_OUTPUT_INTDIR})
10851086

1087+
if(SWIFTLIB_INSTALL_WITH_SHARED)
1088+
set(swift_lib_dir ${SWIFTLIB_DIR})
1089+
else()
1090+
set(swift_lib_dir ${SWIFTSTATICLIB_DIR})
1091+
endif()
1092+
10861093
foreach(config ${CMAKE_CONFIGURATION_TYPES})
10871094
string(TOUPPER ${config} config_upper)
10881095
escape_path_for_xcode(
1089-
"${config}" "${SWIFTSTATICLIB_DIR}" config_lib_dir)
1096+
"${config}" "${swift_lib_dir}" config_lib_dir)
10901097
set_target_properties(${target_static} PROPERTIES
10911098
LIBRARY_OUTPUT_DIRECTORY_${config_upper} ${config_lib_dir}/${SWIFTLIB_SINGLE_SUBDIR}
10921099
ARCHIVE_OUTPUT_DIRECTORY_${config_upper} ${config_lib_dir}/${SWIFTLIB_SINGLE_SUBDIR})
10931100
endforeach()
10941101

10951102
set_target_properties(${target_static} PROPERTIES
1096-
LIBRARY_OUTPUT_DIRECTORY ${SWIFTSTATICLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}
1097-
ARCHIVE_OUTPUT_DIRECTORY ${SWIFTSTATICLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR})
1103+
LIBRARY_OUTPUT_DIRECTORY ${swift_lib_dir}/${SWIFTLIB_SINGLE_SUBDIR}
1104+
ARCHIVE_OUTPUT_DIRECTORY ${swift_lib_dir}/${SWIFTLIB_SINGLE_SUBDIR})
10981105
endif()
10991106

11001107
set_target_properties(${target}
@@ -1353,8 +1360,14 @@ function(_add_swift_library_single target name)
13531360
set_property(TARGET "${target_static}" APPEND_STRING PROPERTY
13541361
COMPILE_FLAGS " ${c_compile_flags}")
13551362
# FIXME: The fallback paths here are going to be dynamic libraries.
1363+
1364+
if(SWIFTLIB_INSTALL_WITH_SHARED)
1365+
set(search_base_dir ${SWIFTLIB_DIR})
1366+
else()
1367+
set(search_base_dir ${SWIFTSTATICLIB_DIR})
1368+
endif()
13561369
set(library_search_directories
1357-
"${SWIFTSTATICLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}"
1370+
"${search_base_dir}/${SWIFTLIB_SINGLE_SUBDIR}"
13581371
"${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/../lib/swift/${SWIFTLIB_SINGLE_SUBDIR}"
13591372
"${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/../lib/swift/${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}")
13601373
swift_target_link_search_directories("${target_static}" "${library_search_directories}")
@@ -1503,6 +1516,7 @@ endfunction()
15031516
# [IS_STDLIB]
15041517
# [IS_STDLIB_CORE]
15051518
# [TARGET_LIBRARY]
1519+
# [INSTALL_WITH_SHARED]
15061520
# INSTALL_IN_COMPONENT comp
15071521
# DEPLOYMENT_VERSION_OSX version
15081522
# DEPLOYMENT_VERSION_IOS version
@@ -1609,6 +1623,9 @@ endfunction()
16091623
# DEPLOYMENT_VERSION_WATCHOS
16101624
# The minimum deployment version to build for if this is an WATCHOS library.
16111625
#
1626+
# INSTALL_WITH_SHARED
1627+
# Install a static library target alongside shared libraries
1628+
#
16121629
# source1 ...
16131630
# Sources to add into this library.
16141631
function(add_swift_target_library name)
@@ -1623,7 +1640,8 @@ function(add_swift_target_library name)
16231640
OBJECT_LIBRARY
16241641
SHARED
16251642
STATIC
1626-
TARGET_LIBRARY)
1643+
TARGET_LIBRARY
1644+
INSTALL_WITH_SHARED)
16271645
set(SWIFTLIB_single_parameter_options
16281646
DEPLOYMENT_VERSION_IOS
16291647
DEPLOYMENT_VERSION_OSX
@@ -1913,6 +1931,7 @@ function(add_swift_target_library name)
19131931
${SWIFTLIB_SHARED_keyword}
19141932
${SWIFTLIB_STATIC_keyword}
19151933
${SWIFTLIB_OBJECT_LIBRARY_keyword}
1934+
${SWIFTLIB_INSTALL_WITH_SHARED_keyword}
19161935
${SWIFTLIB_SOURCES}
19171936
MODULE_TARGET ${MODULE_VARIANT_NAME}
19181937
SDK ${sdk}
@@ -2039,7 +2058,7 @@ function(add_swift_target_library name)
20392058
set(resource_dir_sdk_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}")
20402059
precondition(resource_dir_sdk_subdir)
20412060

2042-
if(SWIFTLIB_SHARED)
2061+
if(SWIFTLIB_SHARED OR SWIFTLIB_INSTALL_WITH_SHARED)
20432062
set(resource_dir "swift")
20442063
set(file_permissions
20452064
OWNER_READ OWNER_WRITE OWNER_EXECUTE
@@ -2124,10 +2143,18 @@ function(add_swift_target_library name)
21242143
list(APPEND THIN_INPUT_TARGETS_STATIC "${TARGET}-static")
21252144
endforeach()
21262145

2146+
if(SWIFTLIB_INSTALL_WITH_SHARED)
2147+
set(install_subdir "swift")
2148+
set(universal_subdir ${SWIFTLIB_DIR})
2149+
else()
2150+
set(install_subdir "swift_static")
2151+
set(universal_subdir ${SWIFTSTATICLIB_DIR})
2152+
endif()
2153+
21272154
set(lipo_target_static
21282155
"${name}-${SWIFT_SDK_${sdk}_LIB_SUBDIR}-static")
21292156
set(UNIVERSAL_LIBRARY_NAME
2130-
"${SWIFTSTATICLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
2157+
"${universal_subdir}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
21312158
_add_swift_lipo_target(SDK
21322159
${sdk}
21332160
TARGET
@@ -2137,7 +2164,7 @@ function(add_swift_target_library name)
21372164
${THIN_INPUT_TARGETS_STATIC})
21382165
swift_install_in_component("${SWIFTLIB_INSTALL_IN_COMPONENT}"
21392166
FILES "${UNIVERSAL_LIBRARY_NAME}"
2140-
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift_static/${resource_dir_sdk_subdir}"
2167+
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${install_subdir}/${resource_dir_sdk_subdir}"
21412168
PERMISSIONS
21422169
OWNER_READ OWNER_WRITE
21432170
GROUP_READ

cmake/modules/SwiftSource.cmake

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -258,12 +258,10 @@ function(_compile_swift_files
258258
list(APPEND swift_flags "-module-name" "${SWIFTFILE_MODULE_NAME}")
259259
endif()
260260

261-
# Force swift 5 mode for Standard Library.
261+
# Force swift 5 mode for Standard Library and overlays.
262262
if (SWIFTFILE_IS_STDLIB)
263263
list(APPEND swift_flags "-swift-version" "5")
264264
endif()
265-
266-
# Force swift 4 compatibility mode for overlays.
267265
if (SWIFTFILE_IS_SDK_OVERLAY)
268266
list(APPEND swift_flags "-swift-version" "5")
269267
endif()
@@ -272,6 +270,12 @@ function(_compile_swift_files
272270
list(APPEND swift_flags "-autolink-force-load")
273271
endif()
274272

273+
# Don't need to link runtime compatibility libraries for older runtimes
274+
# into the new runtime.
275+
if (SWIFTFILE_IS_STDLIB OR SWIFTFILE_IS_SDK_OVERLAY)
276+
list(APPEND swift_flags "-runtime-compatibility-version" "none")
277+
endif()
278+
275279
if (SWIFTFILE_IS_STDLIB_CORE OR SWIFTFILE_IS_SDK_OVERLAY)
276280
list(APPEND swift_flags "-warn-swift3-objc-inference-complete")
277281
endif()

include/swift/AST/IRGenOptions.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
// FIXME: This include is just for llvm::SanitizerCoverageOptions. We should
2727
// split the header upstream so we don't include so much.
2828
#include "llvm/Transforms/Instrumentation.h"
29+
#include "llvm/Support/VersionTuple.h"
2930
#include <string>
3031
#include <vector>
3132

@@ -224,6 +225,9 @@ class IRGenOptions {
224225
};
225226

226227
TypeInfoDumpFilter TypeInfoFilter;
228+
229+
/// Pull in runtime compatibility shim libraries by autolinking.
230+
Optional<llvm::VersionTuple> AutolinkRuntimeCompatibilityLibraryVersion;
227231

228232
IRGenOptions()
229233
: DWARFVersion(2), OutputKind(IRGenOutputKind::LLVMAssembly),

include/swift/Basic/Platform.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
namespace llvm {
2121
class Triple;
22+
class VersionTuple;
2223
}
2324

2425
namespace swift {
@@ -85,6 +86,12 @@ namespace swift {
8586
/// The input triple should already be "normalized" in the sense that
8687
/// llvm::Triple::normalize() would not affect it.
8788
llvm::Triple getTargetSpecificModuleTriple(const llvm::Triple &triple);
89+
90+
91+
/// Get the Swift runtime version to deploy back to, given a deployment target expressed as an
92+
/// LLVM target triple.
93+
Optional<llvm::VersionTuple>
94+
getSwiftRuntimeCompatibilityVersionForTarget(const llvm::Triple &Triple);
8895
} // end namespace swift
8996

9097
#endif // SWIFT_BASIC_PLATFORM_H

include/swift/Option/Options.td

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -887,4 +887,9 @@ def vfsoverlay_EQ : Joined<["-"], "vfsoverlay=">,
887887
def runtime_compatibility_version : Separate<["-"], "runtime-compatibility-version">,
888888
Flags<[FrontendOption]>,
889889
HelpText<"Link compatibility library for Swift runtime version, or 'none'">;
890+
891+
def disable_autolinking_runtime_compatibility : Flag<["-"], "disable-autolinking-runtime-compatibility">,
892+
Flags<[FrontendOption]>,
893+
HelpText<"Do not use autolinking for runtime compatibility libraries">;
894+
890895
include "FrontendOptions.td"

lib/Basic/Platform.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#include "llvm/ADT/StringExtras.h"
1515
#include "llvm/ADT/StringSwitch.h"
1616
#include "llvm/ADT/Triple.h"
17+
#include "llvm/Support/VersionTuple.h"
1718

1819
using namespace swift;
1920

@@ -313,3 +314,37 @@ llvm::Triple swift::getTargetSpecificModuleTriple(const llvm::Triple &triple) {
313314
return triple;
314315
}
315316

317+
Optional<llvm::VersionTuple>
318+
swift::getSwiftRuntimeCompatibilityVersionForTarget(const llvm::Triple &Triple){
319+
unsigned Major, Minor, Micro;
320+
321+
if (Triple.isMacOSX()) {
322+
Triple.getMacOSXVersion(Major, Minor, Micro);
323+
if (Major == 10) {
324+
if (Minor <= 14) {
325+
return llvm::VersionTuple(5, 0);
326+
} else {
327+
return None;
328+
}
329+
} else {
330+
return None;
331+
}
332+
} else if (Triple.isiOS()) { // includes tvOS
333+
Triple.getiOSVersion(Major, Minor, Micro);
334+
if (Major <= 12) {
335+
return llvm::VersionTuple(5, 0);
336+
} else {
337+
return None;
338+
}
339+
} else if (Triple.isWatchOS()) {
340+
Triple.getWatchOSVersion(Major, Minor, Micro);
341+
if (Major <= 5) {
342+
return llvm::VersionTuple(5, 0);
343+
} else {
344+
return None;
345+
}
346+
} else {
347+
return None;
348+
}
349+
}
350+

lib/Driver/DarwinToolChains.cpp

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
#include "llvm/Support/Path.h"
3434
#include "llvm/Support/Process.h"
3535
#include "llvm/Support/Program.h"
36+
#include "llvm/Support/VersionTuple.h"
3637

3738
using namespace swift;
3839
using namespace swift::driver;
@@ -230,7 +231,8 @@ static bool wantsObjCRuntime(const llvm::Triple &triple) {
230231

231232
ToolChain::InvocationInfo
232233
toolchains::Darwin::constructInvocation(const LinkJobAction &job,
233-
const JobContext &context) const {
234+
const JobContext &context) const
235+
{
234236
assert(context.Output.getPrimaryOutputType() == file_types::TY_Image &&
235237
"Invalid linker output type.");
236238

@@ -399,6 +401,39 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
399401
SmallString<128> RuntimeLibPath;
400402
getRuntimeLibraryPath(RuntimeLibPath, context.Args, /*Shared=*/true);
401403

404+
// Link compatibility libraries, if we're deploying back to OSes that
405+
// have an older Swift runtime.
406+
Optional<llvm::VersionTuple> runtimeCompatibilityVersion;
407+
408+
if (context.Args.hasArg(options::OPT_runtime_compatibility_version)) {
409+
auto value = context.Args.getLastArgValue(
410+
options::OPT_runtime_compatibility_version);
411+
if (value.equals("5.0")) {
412+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 0);
413+
} else if (value.equals("none")) {
414+
runtimeCompatibilityVersion = None;
415+
} else {
416+
// TODO: diagnose unknown runtime compatibility version?
417+
}
418+
} else if (job.getKind() == LinkKind::Executable) {
419+
runtimeCompatibilityVersion
420+
= getSwiftRuntimeCompatibilityVersionForTarget(Triple);
421+
}
422+
423+
if (runtimeCompatibilityVersion) {
424+
if (*runtimeCompatibilityVersion <= llvm::VersionTuple(5, 0)) {
425+
// Swift 5.0 compatibility library
426+
SmallString<128> BackDeployLib;
427+
BackDeployLib.append(RuntimeLibPath);
428+
llvm::sys::path::append(BackDeployLib, "libswiftCompatibility50.a");
429+
430+
if (llvm::sys::fs::exists(BackDeployLib)) {
431+
Arguments.push_back("-force_load");
432+
Arguments.push_back(context.Args.MakeArgString(BackDeployLib));
433+
}
434+
}
435+
}
436+
402437
// Link the standard library.
403438
Arguments.push_back("-L");
404439
if (context.Args.hasFlag(options::OPT_static_stdlib,

lib/Driver/ToolChains.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -391,6 +391,17 @@ ToolChain::constructInvocation(const CompileJobAction &job,
391391
Arguments.push_back("-debug-info-store-invocation");
392392
}
393393

394+
if (context.Args.hasArg(
395+
options::OPT_disable_autolinking_runtime_compatibility)) {
396+
Arguments.push_back("-disable-autolinking-runtime-compatibility");
397+
}
398+
399+
if (auto arg = context.Args.getLastArg(
400+
options::OPT_runtime_compatibility_version)) {
401+
Arguments.push_back("-runtime-compatibility-version");
402+
Arguments.push_back(arg->getValue());
403+
}
404+
394405
return II;
395406
}
396407

lib/Frontend/CompilerInvocation.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1147,6 +1147,30 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
11471147
A->getAsString(Args), A->getValue());
11481148
}
11491149
}
1150+
1151+
// Autolink runtime compatibility libraries, if asked to.
1152+
if (!Args.hasArg(options::OPT_disable_autolinking_runtime_compatibility)) {
1153+
Optional<llvm::VersionTuple> runtimeCompatibilityVersion;
1154+
1155+
if (auto versionArg = Args.getLastArg(
1156+
options::OPT_runtime_compatibility_version)) {
1157+
auto version = StringRef(versionArg->getValue());
1158+
if (version.equals("none")) {
1159+
runtimeCompatibilityVersion = None;
1160+
} else if (version.equals("5.0")) {
1161+
runtimeCompatibilityVersion = llvm::VersionTuple(5, 0);
1162+
} else {
1163+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
1164+
versionArg->getAsString(Args), version);
1165+
}
1166+
} else {
1167+
runtimeCompatibilityVersion =
1168+
getSwiftRuntimeCompatibilityVersionForTarget(Triple);
1169+
}
1170+
1171+
Opts.AutolinkRuntimeCompatibilityLibraryVersion =
1172+
runtimeCompatibilityVersion;
1173+
}
11501174

11511175
return false;
11521176
}

lib/IRGen/GenDecl.cpp

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -449,6 +449,26 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
449449

450450
if (ObjCInterop)
451451
this->addLinkLibrary(LinkLibrary("objc", LibraryKind::Library));
452+
453+
// FIXME: It'd be better to have the driver invocation or build system that
454+
// executes the linker introduce these compatibility libraries, since at
455+
// that point we know whether we're building an executable, which is the only
456+
// place where the compatibility libraries take effect. For the benefit of
457+
// build systems that build Swift code, but don't use Swift to drive
458+
// the linker, we can also use autolinking to pull in the compatibility
459+
// libraries. This may however cause the library to get pulled in in
460+
// situations where it isn't useful, such as for dylibs, though this is
461+
// harmless aside from code size.
462+
if (!IRGen.Opts.UseJIT) {
463+
if (auto compatibilityVersion
464+
= IRGen.Opts.AutolinkRuntimeCompatibilityLibraryVersion) {
465+
if (*compatibilityVersion <= llvm::VersionTuple(5, 0)) {
466+
this->addLinkLibrary(LinkLibrary("swiftCompatibility50",
467+
LibraryKind::Library,
468+
/*forceLoad*/ true));
469+
}
470+
}
471+
}
452472
}
453473

454474
/// Collect elements of an already-existing global list with the given

stdlib/public/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ if(SWIFT_BUILD_STDLIB)
6161
add_subdirectory(stubs)
6262
add_subdirectory(core)
6363
add_subdirectory(SwiftOnoneSupport)
64+
add_subdirectory(Compatibility50)
6465
endif()
6566

6667
if(SWIFT_BUILD_STDLIB OR SWIFT_BUILD_REMOTE_MIRROR)

0 commit comments

Comments
 (0)