diff --git a/include/swift/AST/IRGenOptions.h b/include/swift/AST/IRGenOptions.h index b446950b1cb97..41d3eeba82eaf 100644 --- a/include/swift/AST/IRGenOptions.h +++ b/include/swift/AST/IRGenOptions.h @@ -204,6 +204,9 @@ class IRGenOptions { /// The libraries and frameworks specified on the command line. SmallVector LinkLibraries; + /// The public dependent libraries specified on the command line. + std::vector 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; diff --git a/include/swift/Option/FrontendOptions.td b/include/swift/Option/FrontendOptions.td index bba4435087e06..f471c663f28b0 100644 --- a/include/swift/Option/FrontendOptions.td +++ b/include/swift/Option/FrontendOptions.td @@ -163,6 +163,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">; diff --git a/include/swift/Serialization/SerializationOptions.h b/include/swift/Serialization/SerializationOptions.h index 94725c3fe3b5d..47a542f65e0b5 100644 --- a/include/swift/Serialization/SerializationOptions.h +++ b/include/swift/Serialization/SerializationOptions.h @@ -130,6 +130,7 @@ namespace swift { uint64_t getSize() const { return Size; } }; ArrayRef Dependencies; + ArrayRef PublicDependentLibraries; bool AutolinkForceLoad = false; bool SerializeAllSIL = false; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index dc93cb1063dc6..c2ffd845ff6ac 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -1674,6 +1674,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") diff --git a/lib/Frontend/Frontend.cpp b/lib/Frontend/Frontend.cpp index 5bb5ebcaee1da..2554b542d555a 100644 --- a/lib/Frontend/Frontend.cpp +++ b/lib/Frontend/Frontend.cpp @@ -156,7 +156,9 @@ 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()) { serializationOpts.SymbolGraphOutputDir = opts.SymbolGraphOutputDir; diff --git a/lib/Serialization/Serialization.cpp b/lib/Serialization/Serialization.cpp index 70b805453b35b..55c9c3f8bcbce 100644 --- a/lib/Serialization/Serialization.cpp +++ b/lib/Serialization/Serialization.cpp @@ -1210,6 +1210,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 diff --git a/test/IRGen/autolink_elf.swift b/test/IRGen/autolink_elf.swift index 974383e41e6b0..de0b90771ed2f 100644 --- a/test/IRGen/autolink_elf.swift +++ b/test/IRGen/autolink_elf.swift @@ -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 diff --git a/test/Serialization/autolinking.swift b/test/Serialization/autolinking.swift index 5cf99c40b4a69..fcfaf6519c4fa 100644 --- a/test/Serialization/autolinking.swift +++ b/test/Serialization/autolinking.swift @@ -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 @@ -55,3 +60,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"}}}