Revert "Revert "Use autolinking to pull in compatibility libraries.""

This commit is contained in:
Joe Groff
2019-06-03 20:10:51 -07:00
committed by GitHub
parent 547e4e957c
commit 4ed8de10f9
15 changed files with 196 additions and 61 deletions

View File

@@ -730,7 +730,8 @@ function(_add_swift_library_single target name)
OBJECT_LIBRARY
SHARED
STATIC
TARGET_LIBRARY)
TARGET_LIBRARY
INSTALL_WITH_SHARED)
set(SWIFTLIB_SINGLE_single_parameter_options
ARCHITECTURE
DEPLOYMENT_VERSION_IOS
@@ -1085,18 +1086,24 @@ function(_add_swift_library_single target name)
BINARY_DIR ${SWIFT_RUNTIME_OUTPUT_INTDIR}
LIBRARY_DIR ${SWIFT_LIBRARY_OUTPUT_INTDIR})
if(SWIFTLIB_INSTALL_WITH_SHARED)
set(swift_lib_dir ${SWIFTLIB_DIR})
else()
set(swift_lib_dir ${SWIFTSTATICLIB_DIR})
endif()
foreach(config ${CMAKE_CONFIGURATION_TYPES})
string(TOUPPER ${config} config_upper)
escape_path_for_xcode(
"${config}" "${SWIFTSTATICLIB_DIR}" config_lib_dir)
"${config}" "${swift_lib_dir}" config_lib_dir)
set_target_properties(${target_static} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY_${config_upper} ${config_lib_dir}/${SWIFTLIB_SINGLE_SUBDIR}
ARCHIVE_OUTPUT_DIRECTORY_${config_upper} ${config_lib_dir}/${SWIFTLIB_SINGLE_SUBDIR})
endforeach()
set_target_properties(${target_static} PROPERTIES
LIBRARY_OUTPUT_DIRECTORY ${SWIFTSTATICLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}
ARCHIVE_OUTPUT_DIRECTORY ${SWIFTSTATICLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR})
LIBRARY_OUTPUT_DIRECTORY ${swift_lib_dir}/${SWIFTLIB_SINGLE_SUBDIR}
ARCHIVE_OUTPUT_DIRECTORY ${swift_lib_dir}/${SWIFTLIB_SINGLE_SUBDIR})
endif()
set_target_properties(${target}
@@ -1347,8 +1354,14 @@ function(_add_swift_library_single target name)
set_property(TARGET "${target_static}" APPEND_STRING PROPERTY
COMPILE_FLAGS " ${c_compile_flags}")
# FIXME: The fallback paths here are going to be dynamic libraries.
if(SWIFTLIB_INSTALL_WITH_SHARED)
set(search_base_dir ${SWIFTLIB_DIR})
else()
set(search_base_dir ${SWIFTSTATICLIB_DIR})
endif()
set(library_search_directories
"${SWIFTSTATICLIB_DIR}/${SWIFTLIB_SINGLE_SUBDIR}"
"${search_base_dir}/${SWIFTLIB_SINGLE_SUBDIR}"
"${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/../lib/swift/${SWIFTLIB_SINGLE_SUBDIR}"
"${SWIFT_NATIVE_SWIFT_TOOLS_PATH}/../lib/swift/${SWIFT_SDK_${SWIFTLIB_SINGLE_SDK}_LIB_SUBDIR}")
swift_target_link_search_directories("${target_static}" "${library_search_directories}")
@@ -1477,6 +1490,7 @@ endfunction()
# [IS_STDLIB]
# [IS_STDLIB_CORE]
# [TARGET_LIBRARY]
# [INSTALL_WITH_SHARED]
# INSTALL_IN_COMPONENT comp
# DEPLOYMENT_VERSION_OSX version
# DEPLOYMENT_VERSION_IOS version
@@ -1583,6 +1597,9 @@ endfunction()
# DEPLOYMENT_VERSION_WATCHOS
# The minimum deployment version to build for if this is an WATCHOS library.
#
# INSTALL_WITH_SHARED
# Install a static library target alongside shared libraries
#
# source1 ...
# Sources to add into this library.
function(add_swift_target_library name)
@@ -1597,7 +1614,8 @@ function(add_swift_target_library name)
OBJECT_LIBRARY
SHARED
STATIC
TARGET_LIBRARY)
TARGET_LIBRARY
INSTALL_WITH_SHARED)
set(SWIFTLIB_single_parameter_options
DEPLOYMENT_VERSION_IOS
DEPLOYMENT_VERSION_OSX
@@ -1882,6 +1900,7 @@ function(add_swift_target_library name)
${SWIFTLIB_SHARED_keyword}
${SWIFTLIB_STATIC_keyword}
${SWIFTLIB_OBJECT_LIBRARY_keyword}
${SWIFTLIB_INSTALL_WITH_SHARED_keyword}
${SWIFTLIB_SOURCES}
MODULE_TARGET ${MODULE_VARIANT_NAME}
SDK ${sdk}
@@ -1996,7 +2015,7 @@ function(add_swift_target_library name)
set(resource_dir_sdk_subdir "${SWIFT_SDK_${sdk}_LIB_SUBDIR}")
precondition(resource_dir_sdk_subdir)
if(SWIFTLIB_SHARED)
if(SWIFTLIB_SHARED OR SWIFTLIB_INSTALL_WITH_SHARED)
set(resource_dir "swift")
set(file_permissions
OWNER_READ OWNER_WRITE OWNER_EXECUTE
@@ -2058,10 +2077,18 @@ function(add_swift_target_library name)
list(APPEND THIN_INPUT_TARGETS_STATIC "${TARGET}-static")
endforeach()
if(SWIFTLIB_INSTALL_WITH_SHARED)
set(install_subdir "swift")
set(universal_subdir ${SWIFTLIB_DIR})
else()
set(install_subdir "swift_static")
set(universal_subdir ${SWIFTSTATICLIB_DIR})
endif()
set(lipo_target_static
"${name}-${SWIFT_SDK_${sdk}_LIB_SUBDIR}-static")
set(UNIVERSAL_LIBRARY_NAME
"${SWIFTSTATICLIB_DIR}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
"${universal_subdir}/${SWIFT_SDK_${sdk}_LIB_SUBDIR}/${CMAKE_STATIC_LIBRARY_PREFIX}${name}${CMAKE_STATIC_LIBRARY_SUFFIX}")
_add_swift_lipo_target(SDK
${sdk}
TARGET
@@ -2070,7 +2097,7 @@ function(add_swift_target_library name)
"${UNIVERSAL_LIBRARY_NAME}"
${THIN_INPUT_TARGETS_STATIC})
swift_install_in_component(FILES "${UNIVERSAL_LIBRARY_NAME}"
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/swift_static/${resource_dir_sdk_subdir}"
DESTINATION "lib${LLVM_LIBDIR_SUFFIX}/${install_subdir}/${resource_dir_sdk_subdir}"
PERMISSIONS
OWNER_READ OWNER_WRITE
GROUP_READ

View File

@@ -253,12 +253,10 @@ function(_compile_swift_files
list(APPEND swift_flags "-module-name" "${SWIFTFILE_MODULE_NAME}")
endif()
# Force swift 5 mode for Standard Library.
# Force swift 5 mode for Standard Library and overlays.
if (SWIFTFILE_IS_STDLIB)
list(APPEND swift_flags "-swift-version" "5")
endif()
# Force swift 4 compatibility mode for overlays.
if (SWIFTFILE_IS_SDK_OVERLAY)
list(APPEND swift_flags "-swift-version" "5")
endif()
@@ -267,6 +265,12 @@ function(_compile_swift_files
list(APPEND swift_flags "-autolink-force-load")
endif()
# Don't need to link runtime compatibility libraries for older runtimes
# into the new runtime.
if (SWIFTFILE_IS_STDLIB OR SWIFTFILE_IS_SDK_OVERLAY)
list(APPEND swift_flags "-runtime-compatibility-version" "none")
endif()
if (SWIFTFILE_IS_STDLIB_CORE OR SWIFTFILE_IS_SDK_OVERLAY)
list(APPEND swift_flags "-warn-swift3-objc-inference-complete")
endif()

View File

@@ -26,6 +26,7 @@
// FIXME: This include is just for llvm::SanitizerCoverageOptions. We should
// split the header upstream so we don't include so much.
#include "llvm/Transforms/Instrumentation.h"
#include "llvm/Support/VersionTuple.h"
#include <string>
#include <vector>
@@ -225,6 +226,9 @@ public:
TypeInfoDumpFilter TypeInfoFilter;
/// Pull in runtime compatibility shim libraries by autolinking.
Optional<llvm::VersionTuple> AutolinkRuntimeCompatibilityLibraryVersion;
IRGenOptions()
: DWARFVersion(2), OutputKind(IRGenOutputKind::LLVMAssembly),
Verify(true), OptMode(OptimizationMode::NotSet),

View File

@@ -19,6 +19,7 @@
namespace llvm {
class Triple;
class VersionTuple;
}
namespace swift {
@@ -85,6 +86,12 @@ namespace swift {
/// The input triple should already be "normalized" in the sense that
/// llvm::Triple::normalize() would not affect it.
llvm::Triple getTargetSpecificModuleTriple(const llvm::Triple &triple);
/// Get the Swift runtime version to deploy back to, given a deployment target expressed as an
/// LLVM target triple.
Optional<llvm::VersionTuple>
getSwiftRuntimeCompatibilityVersionForTarget(const llvm::Triple &Triple);
} // end namespace swift
#endif // SWIFT_BASIC_PLATFORM_H

View File

@@ -892,4 +892,9 @@ def vfsoverlay_EQ : Joined<["-"], "vfsoverlay=">,
def runtime_compatibility_version : Separate<["-"], "runtime-compatibility-version">,
Flags<[FrontendOption]>,
HelpText<"Link compatibility library for Swift runtime version, or 'none'">;
def disable_autolinking_runtime_compatibility : Flag<["-"], "disable-autolinking-runtime-compatibility">,
Flags<[FrontendOption]>,
HelpText<"Do not use autolinking for runtime compatibility libraries">;
include "FrontendOptions.td"

View File

@@ -14,6 +14,7 @@
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringSwitch.h"
#include "llvm/ADT/Triple.h"
#include "llvm/Support/VersionTuple.h"
using namespace swift;
@@ -313,3 +314,37 @@ llvm::Triple swift::getTargetSpecificModuleTriple(const llvm::Triple &triple) {
return triple;
}
Optional<llvm::VersionTuple>
swift::getSwiftRuntimeCompatibilityVersionForTarget(const llvm::Triple &Triple){
unsigned Major, Minor, Micro;
if (Triple.isMacOSX()) {
Triple.getMacOSXVersion(Major, Minor, Micro);
if (Major == 10) {
if (Minor <= 14) {
return llvm::VersionTuple(5, 0);
} else {
return None;
}
} else {
return None;
}
} else if (Triple.isiOS()) { // includes tvOS
Triple.getiOSVersion(Major, Minor, Micro);
if (Major <= 12) {
return llvm::VersionTuple(5, 0);
} else {
return None;
}
} else if (Triple.isWatchOS()) {
Triple.getWatchOSVersion(Major, Minor, Micro);
if (Major <= 5) {
return llvm::VersionTuple(5, 0);
} else {
return None;
}
} else {
return None;
}
}

View File

@@ -33,6 +33,7 @@
#include "llvm/Support/Path.h"
#include "llvm/Support/Process.h"
#include "llvm/Support/Program.h"
#include "llvm/Support/VersionTuple.h"
using namespace swift;
using namespace swift::driver;
@@ -221,42 +222,6 @@ static bool wantsObjCRuntime(const llvm::Triple &triple) {
llvm_unreachable("unknown Darwin OS");
}
/// Return the earliest backward deployment compatibility version we need to
/// link in for the given target triple, if any.
static Optional<std::pair<unsigned, unsigned>>
getSwiftRuntimeCompatibilityVersionForTarget(const llvm::Triple &Triple) {
unsigned Major, Minor, Micro;
if (Triple.isMacOSX()) {
Triple.getMacOSXVersion(Major, Minor, Micro);
if (Major == 10) {
if (Minor <= 14) {
return std::make_pair(5u, 0u);
} else {
return None;
}
} else {
return None;
}
} else if (Triple.isiOS()) { // includes tvOS
Triple.getiOSVersion(Major, Minor, Micro);
if (Major <= 12) {
return std::make_pair(5u, 0u);
} else {
return None;
}
} else if (Triple.isWatchOS()) {
Triple.getWatchOSVersion(Major, Minor, Micro);
if (Major <= 5) {
return std::make_pair(5u, 0u);
} else {
return None;
}
} else {
return None;
}
}
ToolChain::InvocationInfo
toolchains::Darwin::constructInvocation(const LinkJobAction &job,
const JobContext &context) const
@@ -431,12 +396,13 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
// Link compatibility libraries, if we're deploying back to OSes that
// have an older Swift runtime.
Optional<std::pair<unsigned, unsigned>> runtimeCompatibilityVersion;
Optional<llvm::VersionTuple> runtimeCompatibilityVersion;
if (context.Args.hasArg(options::OPT_runtime_compatibility_version)) {
auto value = context.Args.getLastArgValue(options::OPT_runtime_compatibility_version);
auto value = context.Args.getLastArgValue(
options::OPT_runtime_compatibility_version);
if (value.equals("5.0")) {
runtimeCompatibilityVersion = std::make_pair(5u, 0u);
runtimeCompatibilityVersion = llvm::VersionTuple(5, 0);
} else if (value.equals("none")) {
runtimeCompatibilityVersion = None;
} else {
@@ -448,7 +414,7 @@ toolchains::Darwin::constructInvocation(const LinkJobAction &job,
}
if (runtimeCompatibilityVersion) {
if (*runtimeCompatibilityVersion <= std::make_pair(5u, 0u)) {
if (*runtimeCompatibilityVersion <= llvm::VersionTuple(5, 0)) {
// Swift 5.0 compatibility library
SmallString<128> BackDeployLib;
BackDeployLib.append(RuntimeLibPath);

View File

@@ -433,6 +433,17 @@ ToolChain::constructInvocation(const CompileJobAction &job,
Arguments.push_back("-debug-info-store-invocation");
}
if (context.Args.hasArg(
options::OPT_disable_autolinking_runtime_compatibility)) {
Arguments.push_back("-disable-autolinking-runtime-compatibility");
}
if (auto arg = context.Args.getLastArg(
options::OPT_runtime_compatibility_version)) {
Arguments.push_back("-runtime-compatibility-version");
Arguments.push_back(arg->getValue());
}
return II;
}

View File

@@ -1156,6 +1156,30 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
}
}
// Autolink runtime compatibility libraries, if asked to.
if (!Args.hasArg(options::OPT_disable_autolinking_runtime_compatibility)) {
Optional<llvm::VersionTuple> runtimeCompatibilityVersion;
if (auto versionArg = Args.getLastArg(
options::OPT_runtime_compatibility_version)) {
auto version = StringRef(versionArg->getValue());
if (version.equals("none")) {
runtimeCompatibilityVersion = None;
} else if (version.equals("5.0")) {
runtimeCompatibilityVersion = llvm::VersionTuple(5, 0);
} else {
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
versionArg->getAsString(Args), version);
}
} else {
runtimeCompatibilityVersion =
getSwiftRuntimeCompatibilityVersionForTarget(Triple);
}
Opts.AutolinkRuntimeCompatibilityLibraryVersion =
runtimeCompatibilityVersion;
}
return false;
}

View File

@@ -449,6 +449,26 @@ void IRGenModule::emitSourceFile(SourceFile &SF) {
if (ObjCInterop)
this->addLinkLibrary(LinkLibrary("objc", LibraryKind::Library));
// FIXME: It'd be better to have the driver invocation or build system that
// executes the linker introduce these compatibility libraries, since at
// that point we know whether we're building an executable, which is the only
// place where the compatibility libraries take effect. For the benefit of
// build systems that build Swift code, but don't use Swift to drive
// the linker, we can also use autolinking to pull in the compatibility
// libraries. This may however cause the library to get pulled in in
// situations where it isn't useful, such as for dylibs, though this is
// harmless aside from code size.
if (!IRGen.Opts.UseJIT) {
if (auto compatibilityVersion
= IRGen.Opts.AutolinkRuntimeCompatibilityLibraryVersion) {
if (*compatibilityVersion <= llvm::VersionTuple(5, 0)) {
this->addLinkLibrary(LinkLibrary("swiftCompatibility50",
LibraryKind::Library,
/*forceLoad*/ true));
}
}
}
}
/// Collect elements of an already-existing global list with the given

View File

@@ -1,10 +1,12 @@
set(swift_runtime_compile_flags ${SWIFT_RUNTIME_CORE_CXX_FLAGS})
set(swift_runtime_linker_flags ${SWIFT_RUNTIME_CORE_LINK_FLAGS})
add_swift_target_library(swiftCompatibility50 TARGET_LIBRARY STATIC
add_swift_target_library(swiftCompatibility50 TARGET_LIBRARY STATIC INSTALL_WITH_SHARED
ProtocolConformance.cpp
Overrides.cpp
C_COMPILE_FLAGS ${swift_runtime_library_compile_flags}
LINK_FLAGS ${swift_runtime_linker_flags}
TARGET_SDKS ${SWIFT_APPLE_PLATFORMS}
INSTALL_IN_COMPONENT stdlib)
INSTALL_IN_COMPONENT compiler)

View File

@@ -31,3 +31,8 @@ __attribute__((used, section("__DATA,__swift_hooks"))) = {
.version = 0,
.conformsToProtocol = swift50override_conformsToProtocol,
};
// Allow this library to get force-loaded by autolinking
__attribute__((weak, visibility("hidden")))
extern "C"
char _swift_FORCE_LOAD_$_swiftCompatibility50 = 0;

View File

@@ -0,0 +1,25 @@
// REQUIRES: OS=macosx
// Doesn't autolink compatibility library because autolinking is disabled
// RUN: %target-swift-frontend -target x86_64-apple-macosx10.9 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
// RUN: %target-swift-frontend -runtime-compatibility-version 5.0 -disable-autolinking-runtime-compatibility -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
// Doesn't autolink compatibility library because runtime compatibility library is disabled
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
// Doesn't autolink compatibility library because target OS doesn't need it
// RUN: %target-swift-frontend -target x86_64-apple-macosx10.24 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=NO-FORCE-LOAD %s
// Autolinks because compatibility library was explicitly asked for
// RUN: %target-swift-frontend -runtime-compatibility-version 5.0 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD %s
// RUN: %target-swift-frontend -target x86_64-apple-macosx10.24 -runtime-compatibility-version 5.0 -emit-ir -parse-stdlib %s | %FileCheck -check-prefix=FORCE-LOAD %s
public func foo() {}
// NO-FORCE-LOAD-NOT: FORCE_LOAD
// NO-FORCE-LOAD-NOT: !{!"-lswiftCompatibility50"}
// FORCE-LOAD: declare {{.*}} @"_swift_FORCE_LOAD_$_swiftCompatibility50"
// FORCE-LOAD-DAG: [[AUTOLINK_SWIFT_COMPAT:![0-9]+]] = !{!"-lswiftCompatibility50"}
// FORCE-LOAD-DAG: !llvm.linker.options = !{{{.*}}[[AUTOLINK_SWIFT_COMPAT]]{{[,}]}}

View File

@@ -1,4 +1,4 @@
// RUN: %target-swift-frontend -primary-file %s -emit-ir | %FileCheck -check-prefix CHECK -check-prefix NEGATIVE -check-prefix CHECK-%target-object-format %s
// RUN: %target-swift-frontend -runtime-compatibility-version none -primary-file %s -emit-ir | %FileCheck -check-prefix CHECK -check-prefix NEGATIVE -check-prefix CHECK-%target-object-format %s
// REQUIRES: CPU=x86_64

View File

@@ -1,23 +1,23 @@
// RUN: %empty-directory(%t)
// RUN: %target-swift-frontend -emit-module -parse-stdlib -o %t -module-name someModule -module-link-name module %S/../Inputs/empty.swift
// RUN: %target-swift-frontend -emit-ir -lmagic %s -I %t > %t/out.txt
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -lmagic %s -I %t > %t/out.txt
// RUN: %FileCheck %s < %t/out.txt
// RUN: %FileCheck -check-prefix=NO-FORCE-LOAD %s < %t/out.txt
// RUN: %empty-directory(%t/someModule.framework/Modules/someModule.swiftmodule)
// RUN: mv %t/someModule.swiftmodule %t/someModule.framework/Modules/someModule.swiftmodule/%target-swiftmodule-name
// RUN: %target-swift-frontend -emit-ir -lmagic %s -F %t > %t/framework.txt
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -lmagic %s -F %t > %t/framework.txt
// RUN: %FileCheck -check-prefix=FRAMEWORK %s < %t/framework.txt
// RUN: %FileCheck -check-prefix=NO-FORCE-LOAD %s < %t/framework.txt
// RUN: %target-swift-frontend -emit-module -parse-stdlib -o %t -module-name someModule -module-link-name module %S/../Inputs/empty.swift -autolink-force-load
// RUN: %target-swift-frontend -emit-ir -lmagic %s -I %t > %t/force-load.txt
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -lmagic %s -I %t > %t/force-load.txt
// RUN: %FileCheck %s < %t/force-load.txt
// RUN: %FileCheck -check-prefix FORCE-LOAD-CLIENT -check-prefix FORCE-LOAD-CLIENT-%target-object-format %s < %t/force-load.txt
// RUN: %target-swift-frontend -emit-ir -parse-stdlib -module-name someModule -module-link-name module %S/../Inputs/empty.swift | %FileCheck --check-prefix=NO-FORCE-LOAD %s
// RUN: %target-swift-frontend -emit-ir -parse-stdlib -module-name someModule -module-link-name module %S/../Inputs/empty.swift -autolink-force-load | %FileCheck --check-prefix=FORCE-LOAD %s
// RUN: %target-swift-frontend -emit-ir -parse-stdlib -module-name someModule -module-link-name 0module %S/../Inputs/empty.swift -autolink-force-load | %FileCheck --check-prefix=FORCE-LOAD-HEX %s
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib -module-name someModule -module-link-name module %S/../Inputs/empty.swift | %FileCheck --check-prefix=NO-FORCE-LOAD %s
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib -module-name someModule -module-link-name module %S/../Inputs/empty.swift -autolink-force-load | %FileCheck --check-prefix=FORCE-LOAD %s
// RUN: %target-swift-frontend -runtime-compatibility-version none -emit-ir -parse-stdlib -module-name someModule -module-link-name 0module %S/../Inputs/empty.swift -autolink-force-load | %FileCheck --check-prefix=FORCE-LOAD-HEX %s
// Linux uses a different autolinking mechanism, based on
// swift-autolink-extract. This file tests the Darwin mechanism.