[Frontend] Add -public-autolink-library option (#35936)

Foundation imports CoreFoundation with `@_implementationOnly`,
so CoreFoundation's modulemap won't be read, and the dependent libraries
of CoreFoundation will not be automatically linked when using static
linking.

For example, CoreFoundation depends on libicui18n and it's modulemap has
`link "icui18n"` statement. If Foundation imports CoreFoundation with
`@_implementationOnly` as a private dependency, the toolchain doesn't have
CoreFoundation's modulemap and Foundation's swiftmodule  doesn't import
CoreFoundation. So the swiftc can't know that libicui18n is required.

This new option will add LINK_LIBRARY entry in swiftmodule to
specify dependent libraries (in the example case, Foundation's
swiftmodule should have LINK_LIBRARY entry of libicui18n)


See also: [Autolinking behavior of @_implementationOnly with static linking](https://forums.swift.org/t/autolinking-behavior-of-implementationonly-with-static-linking/44393)
This commit is contained in:
Yuta Saito
2021-06-15 20:38:19 +09:00
committed by GitHub
parent 6ef20577b4
commit 6362a98aa0
8 changed files with 30 additions and 4 deletions

View File

@@ -204,6 +204,9 @@ public:
/// The libraries and frameworks specified on the command line.
SmallVector<LinkLibrary, 4> LinkLibraries;
/// The public dependent libraries specified on the command line.
std::vector<std::string> PublicLinkLibraries;
/// If non-empty, the (unmangled) name of a dummy symbol to emit that can be
/// used to force-load this module.
std::string ForceLoadSymbolName;

View File

@@ -160,6 +160,9 @@ def no_serialize_debugging_options :
def autolink_library : Separate<["-"], "autolink-library">,
HelpText<"Add dependent library">, Flags<[FrontendOption]>;
def public_autolink_library : Separate<["-"], "public-autolink-library">,
HelpText<"Add public dependent library">, Flags<[FrontendOption]>;
def disable_typo_correction : Flag<["-"], "disable-typo-correction">,
HelpText<"Disable typo correction">;

View File

@@ -131,6 +131,7 @@ namespace swift {
uint64_t getSize() const { return Size; }
};
ArrayRef<FileDependency> Dependencies;
ArrayRef<std::string> PublicDependentLibraries;
bool AutolinkForceLoad = false;
bool SerializeAllSIL = false;

View File

@@ -1759,6 +1759,10 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
for (const auto &Lib : Args.getAllArgValues(options::OPT_autolink_library))
Opts.LinkLibraries.push_back(LinkLibrary(Lib, LibraryKind::Library));
for (const auto &Lib : Args.getAllArgValues(options::OPT_public_autolink_library)) {
Opts.PublicLinkLibraries.push_back(Lib);
}
if (const Arg *A = Args.getLastArg(OPT_type_info_dump_filter_EQ)) {
StringRef mode(A->getValue());
if (mode == "all")

View File

@@ -156,6 +156,8 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
serializationOpts.ModuleLinkName = opts.ModuleLinkName;
serializationOpts.UserModuleVersion = opts.UserModuleVersion;
serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs;
serializationOpts.PublicDependentLibraries =
getIRGenOptions().PublicLinkLibraries;
if (opts.EmitSymbolGraph) {
if (!opts.SymbolGraphOutputDir.empty()) {

View File

@@ -1217,6 +1217,10 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
LinkLibrary.emit(ScratchRecord, serialization::LibraryKind::Library,
options.AutolinkForceLoad, options.ModuleLinkName);
}
for (auto dependentLib : options.PublicDependentLibraries) {
LinkLibrary.emit(ScratchRecord, serialization::LibraryKind::Library,
options.AutolinkForceLoad, dependentLib);
}
}
/// Translate AST default argument kind to the Serialization enum values, which

View File

@@ -1,5 +1,5 @@
// RUN: %empty-directory(%t)
// RUN: %swift -disable-legacy-type-info -target x86_64-unknown-linux-gnu -emit-module -parse-stdlib -o %t -module-name Empty -module-link-name swiftEmpty %S/../Inputs/empty.swift
// RUN: %swift -disable-legacy-type-info -target x86_64-unknown-linux-gnu -emit-module -parse-stdlib -o %t -module-name Empty -module-link-name swiftEmpty -public-autolink-library anotherLib %S/../Inputs/empty.swift
// RUN: %swift -disable-legacy-type-info -target x86_64-unknown-linux-gnu %s -I %t -parse-stdlib -disable-objc-interop -module-name main -emit-ir -o - | %FileCheck %s
// REQUIRES: CODEGENERATOR=X86
@@ -9,6 +9,6 @@ import Empty
// Check that on ELF targets autolinking information is emitted and marked
// as used.
// CHECK-DAG: @_swift1_autolink_entries = private constant [13 x i8] c"-lswiftEmpty\00", section ".swift1_autolink_entries", align 8
// CHECK-DAG: @llvm.used = appending global [{{.*}} x i8*] [{{.*}}i8* getelementptr inbounds ([13 x i8], [13 x i8]* @_swift1_autolink_entries, i32 0, i32 0){{.*}}], section "llvm.metadata", align 8
// CHECK-DAG: @_swift1_autolink_entries = private constant [26 x i8] c"-lswiftEmpty\00-lanotherLib\00", section ".swift1_autolink_entries", align 8
// CHECK-DAG: @llvm.used = appending global [{{.*}} x i8*] [{{.*}}i8* getelementptr inbounds ([26 x i8], [26 x i8]* @_swift1_autolink_entries, i32 0, i32 0){{.*}}], section "llvm.metadata", align 8

View File

@@ -22,6 +22,11 @@
// 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
// RUN: %target-swift-frontend -emit-module -parse-stdlib -o %t -module-name someModule -module-link-name module %S/../Inputs/empty.swift -public-autolink-library anotherLib
// RUN: %target-swift-frontend -disable-autolinking-runtime-compatibility-dynamic-replacements -runtime-compatibility-version none -emit-ir -lmagic %s -I %t > %t/public-autolink.txt
// RUN: %FileCheck %s < %t/public-autolink.txt
// RUN: %FileCheck -check-prefix=PUBLIC-DEP %s < %t/public-autolink.txt
// Linux uses a different autolinking mechanism, based on
// swift-autolink-extract. This file tests the Darwin mechanism.
// UNSUPPORTED: autolink-extract
@@ -51,3 +56,7 @@ import someModule
// FORCE-LOAD-CLIENT-macho: declare extern_weak {{(dllimport )?}}void @"_swift_FORCE_LOAD_$_module"()
// FORCE-LOAD-CLIENT-COFF: declare extern {{(dllimport )?}}void @"_swift_FORCE_LOAD_$_module"()
// PUBLIC-DEP: !llvm.linker.options = !{
// PUBLIC-DEP-DAG: !{{[0-9]+}} = !{!{{"-lmagic"|"/DEFAULTLIB:magic.lib"}}}
// PUBLIC-DEP-DAG: !{{[0-9]+}} = !{!{{"-lmodule"|"/DEFAULTLIB:module.lib"}}}
// PUBLIC-DEP-DAG: !{{[0-9]+}} = !{!{{"-lanotherLib"|"/DEFAULTLIB:anotherLib.lib"}}}