Skip to content

Commit 018e680

Browse files
committed
Fine-grained autolinking control
This change adds the following options to allow for greater control over the compiler's autolinking directive use: - '-disable-autolink-library': equivalent to an existing '-disable-autolink-framework', this option takes a library name as input and ensures the compiler does not produce an autolink directive '-l<library-name>'. - '-disable-autolink-frameworks': a boolean disable flag which turns off insertion of autolinking directives for all imported frameworks (of the type '-framework <framework-name>') - '-disable-all-autolinking': a boolean disable flag which turns off insertion of *any* autolinking directives. Resolves rdar://100859983
1 parent 37f652c commit 018e680

File tree

7 files changed

+119
-15
lines changed

7 files changed

+119
-15
lines changed

include/swift/AST/IRGenOptions.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,15 @@ class IRGenOptions {
325325
/// Frameworks that we should not autolink against.
326326
SmallVector<std::string, 1> DisableAutolinkFrameworks;
327327

328+
/// Non-framework libraries that we should not autolink against.
329+
SmallVector<std::string, 1> DisableAutolinkLibraries;
330+
331+
/// Whether we should disable inserting autolink directives for any frameworks.
332+
unsigned DisableFrameworkAutolinking : 1;
333+
334+
/// Whether we should disable inserting autolink directives altogether.
335+
unsigned DisableAllAutolinking : 1;
336+
328337
/// Print the LLVM inline tree at the end of the LLVM pass pipeline.
329338
unsigned PrintInlineTree : 1;
330339

include/swift/Option/FrontendOptions.td

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -517,6 +517,15 @@ def code_complete_call_pattern_heuristics : Flag<["-"], "code-complete-call-patt
517517
def disable_autolink_framework : Separate<["-"],"disable-autolink-framework">,
518518
HelpText<"Disable autolinking against the provided framework">;
519519

520+
def disable_autolink_library : Separate<["-"],"disable-autolink-library">,
521+
HelpText<"Disable autolinking against the provided library">;
522+
523+
def disable_autolink_frameworks : Flag<["-"],"disable-autolink-frameworks">,
524+
HelpText<"Disable autolinking against all frameworks">;
525+
526+
def disable_all_autolinking : Flag<["-"],"disable-all-autolinking">,
527+
HelpText<"Disable all Swift autolink directives">;
528+
520529
def disable_diagnostic_passes : Flag<["-"], "disable-diagnostic-passes">,
521530
HelpText<"Don't run diagnostic passes">;
522531

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2568,6 +2568,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
25682568
for (const Arg *A : Args.filtered(OPT_disable_autolink_framework)) {
25692569
Opts.DisableAutolinkFrameworks.push_back(A->getValue());
25702570
}
2571+
for (const Arg *A : Args.filtered(OPT_disable_autolink_library)) {
2572+
Opts.DisableAutolinkLibraries.push_back(A->getValue());
2573+
}
2574+
Opts.DisableFrameworkAutolinking = Args.hasArg(OPT_disable_autolink_frameworks);
2575+
Opts.DisableAllAutolinking = Args.hasArg(OPT_disable_all_autolinking);
25712576

25722577
Opts.GenerateProfile |= Args.hasArg(OPT_profile_generate);
25732578
const Arg *ProfileUse = Args.getLastArg(OPT_profile_use);

lib/IRGen/IRGenModule.cpp

Lines changed: 27 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1459,21 +1459,33 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
14591459
// emit it into the IR of debugger expressions.
14601460
if (Context.LangOpts.DebuggerSupport)
14611461
return;
1462-
1463-
switch (linkLib.getKind()) {
1464-
case LibraryKind::Library: {
1465-
AutolinkEntries.emplace_back(linkLib);
1466-
break;
1467-
}
1468-
case LibraryKind::Framework: {
1469-
// If we're supposed to disable autolinking of this framework, bail out.
1470-
auto &frameworks = IRGen.Opts.DisableAutolinkFrameworks;
1471-
if (std::find(frameworks.begin(), frameworks.end(), linkLib.getName())
1472-
!= frameworks.end())
1473-
return;
1474-
AutolinkEntries.emplace_back(linkLib);
1475-
break;
1476-
}
1462+
1463+
if (Context.LangOpts.hasFeature(Feature::Embedded))
1464+
return;
1465+
1466+
// '-disable-autolinking' means we will not auto-link
1467+
// any loaded library at all.
1468+
if (!IRGen.Opts.DisableAllAutolinking) {
1469+
switch (linkLib.getKind()) {
1470+
case LibraryKind::Library: {
1471+
auto &libraries = IRGen.Opts.DisableAutolinkLibraries;
1472+
if (llvm::find(libraries, linkLib.getName()) != libraries.end())
1473+
return;
1474+
AutolinkEntries.emplace_back(linkLib);
1475+
break;
1476+
}
1477+
case LibraryKind::Framework: {
1478+
// 'disable-autolink-frameworks' means we will not auto-link
1479+
// any loaded framework.
1480+
if (!IRGen.Opts.DisableFrameworkAutolinking) {
1481+
auto &frameworks = IRGen.Opts.DisableAutolinkFrameworks;
1482+
if (llvm::find(frameworks, linkLib.getName()) != frameworks.end())
1483+
return;
1484+
AutolinkEntries.emplace_back(linkLib);
1485+
}
1486+
break;
1487+
}
1488+
}
14771489
}
14781490

14791491
if (linkLib.shouldForceLoad()) {
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend %s -sdk %S/Inputs -Fsystem %S/Inputs/System/Library/Frameworks -enable-objc-interop -I %S/Inputs/custom-modules -disable-all-autolinking -module-name AutolinkDisableFrameworks -emit-ir -o %t/test.ll
4+
// RUN: cat %t/test.ll | %FileCheck %s
5+
6+
// Linux uses a different autolinking mechanism, based on
7+
// swift-autolink-extract. This file tests the Darwin mechanism.
8+
// UNSUPPORTED: autolink-extract
9+
10+
import LinkMusket
11+
import LinkFramework
12+
import ClangModuleUser
13+
import IndirectFrameworkImporter
14+
import UsesSubmodule
15+
16+
// No linker options produced
17+
// CHECK: !llvm.linker.options = !{}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend %s -sdk %S/Inputs -Fsystem %S/Inputs/System/Library/Frameworks -enable-objc-interop -I %S/Inputs/custom-modules -disable-autolink-frameworks -module-name AutolinkDisableFrameworks -emit-ir -o %t/test.ll
4+
// RUN: cat %t/test.ll | %FileCheck %s
5+
6+
// Linux uses a different autolinking mechanism, based on
7+
// swift-autolink-extract. This file tests the Darwin mechanism.
8+
// UNSUPPORTED: autolink-extract
9+
10+
import LinkMusket
11+
import LinkFramework
12+
import ClangModuleUser
13+
import IndirectFrameworkImporter
14+
import UsesSubmodule
15+
16+
// CHECK: !llvm.linker.options = !{
17+
18+
// CHECK-DAG: !{{[0-9]+}} = !{!{{"-lLock"|"/DEFAULTLIB:Lock.lib"}}}
19+
// CHECK-DAG: !{{[0-9]+}} = !{!{{"-lStock"|"/DEFAULTLIB:Stock.lib"}}}
20+
// CHECK-DAG: !{{[0-9]+}} = !{!{{"-lUnderlyingClangLibrary"|"/DEFAULTLIB:UnderlyingClangLibrary.lib"}}}
21+
22+
// CHECK-NOT: !{!"-framework", !"Barrel"}
23+
// CHECK-NOT: !{!"-framework", !"LinkFramework"}
24+
// CHECK-NOT: !{!"-framework", !"Indirect"}
25+
// CHECK-NOT: !{!"-framework", !"HasSubmodule"}
26+
// CHECK-NOT: !{!"-framework", !"Barrel"}
27+
// CHECK-NOT: !{!"-framework", !"Indirect"}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend %s -sdk %S/Inputs -Fsystem %S/Inputs/System/Library/Frameworks -enable-objc-interop -I %S/Inputs/custom-modules -disable-autolink-library Stock -disable-autolink-library UnderlyingClangLibrary -module-name AutolinkDisableFrameworks -emit-ir -o %t/test.ll
4+
// RUN: cat %t/test.ll | %FileCheck %s
5+
6+
// Linux uses a different autolinking mechanism, based on
7+
// swift-autolink-extract. This file tests the Darwin mechanism.
8+
// UNSUPPORTED: autolink-extract
9+
10+
import LinkMusket
11+
import LinkFramework
12+
import ClangModuleUser
13+
import IndirectFrameworkImporter
14+
import UsesSubmodule
15+
16+
// CHECK: !llvm.linker.options = !{
17+
18+
// CHECK-DAG: !{{[0-9]+}} = !{!{{"-lLock"|"/DEFAULTLIB:Lock.lib"}}}
19+
// CHECK-DAG: !{{[0-9]+}} = !{!"-framework", !"Barrel"}
20+
// CHECK-DAG: !{{[0-9]+}} = !{!"-framework", !"LinkFramework"}
21+
// CHECK-DAG: !{{[0-9]+}} = !{!"-framework", !"Indirect"}
22+
// CHECK-DAG: !{{[0-9]+}} = !{!"-framework", !"HasSubmodule"}
23+
24+
// CHECK-NOT: !{!{{"-lStock"|"/DEFAULTLIB:Stock.lib"}}}
25+
// CHECK-NOT: !{!{{"-lUnderlyingClangLibrary"|"/DEFAULTLIB:UnderlyingClangLibrary.lib"}}}

0 commit comments

Comments
 (0)