Skip to content

Commit 57e4f24

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 9050690 commit 57e4f24

File tree

7 files changed

+116
-15
lines changed

7 files changed

+116
-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
@@ -524,6 +524,15 @@ def code_complete_call_pattern_heuristics : Flag<["-"], "code-complete-call-patt
524524
def disable_autolink_framework : Separate<["-"],"disable-autolink-framework">,
525525
HelpText<"Disable autolinking against the provided framework">;
526526

527+
def disable_autolink_library : Separate<["-"],"disable-autolink-library">,
528+
HelpText<"Disable autolinking against the provided library">;
529+
530+
def disable_autolink_frameworks : Flag<["-"],"disable-autolink-frameworks">,
531+
HelpText<"Disable autolinking against all frameworks">;
532+
533+
def disable_all_autolinking : Flag<["-"],"disable-all-autolinking">,
534+
HelpText<"Disable all Swift autolink directives">;
535+
527536
def disable_diagnostic_passes : Flag<["-"], "disable-diagnostic-passes">,
528537
HelpText<"Don't run diagnostic passes">;
529538

lib/Frontend/CompilerInvocation.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2601,6 +2601,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
26012601
for (const Arg *A : Args.filtered(OPT_disable_autolink_framework)) {
26022602
Opts.DisableAutolinkFrameworks.push_back(A->getValue());
26032603
}
2604+
for (const Arg *A : Args.filtered(OPT_disable_autolink_library)) {
2605+
Opts.DisableAutolinkLibraries.push_back(A->getValue());
2606+
}
2607+
Opts.DisableFrameworkAutolinking = Args.hasArg(OPT_disable_autolink_frameworks);
2608+
Opts.DisableAllAutolinking = Args.hasArg(OPT_disable_all_autolinking);
26042609

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

lib/IRGen/IRGenModule.cpp

Lines changed: 24 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1466,21 +1466,30 @@ void IRGenModule::addLinkLibrary(const LinkLibrary &linkLib) {
14661466

14671467
if (Context.LangOpts.hasFeature(Feature::Embedded))
14681468
return;
1469-
1470-
switch (linkLib.getKind()) {
1471-
case LibraryKind::Library: {
1472-
AutolinkEntries.emplace_back(linkLib);
1473-
break;
1474-
}
1475-
case LibraryKind::Framework: {
1476-
// If we're supposed to disable autolinking of this framework, bail out.
1477-
auto &frameworks = IRGen.Opts.DisableAutolinkFrameworks;
1478-
if (std::find(frameworks.begin(), frameworks.end(), linkLib.getName())
1479-
!= frameworks.end())
1480-
return;
1481-
AutolinkEntries.emplace_back(linkLib);
1482-
break;
1483-
}
1469+
1470+
// '-disable-autolinking' means we will not auto-link
1471+
// any loaded library at all.
1472+
if (!IRGen.Opts.DisableAllAutolinking) {
1473+
switch (linkLib.getKind()) {
1474+
case LibraryKind::Library: {
1475+
auto &libraries = IRGen.Opts.DisableAutolinkLibraries;
1476+
if (llvm::find(libraries, linkLib.getName()) != libraries.end())
1477+
return;
1478+
AutolinkEntries.emplace_back(linkLib);
1479+
break;
1480+
}
1481+
case LibraryKind::Framework: {
1482+
// 'disable-autolink-frameworks' means we will not auto-link
1483+
// any loaded framework.
1484+
if (!IRGen.Opts.DisableFrameworkAutolinking) {
1485+
auto &frameworks = IRGen.Opts.DisableAutolinkFrameworks;
1486+
if (llvm::find(frameworks, linkLib.getName()) != frameworks.end())
1487+
return;
1488+
AutolinkEntries.emplace_back(linkLib);
1489+
}
1490+
break;
1491+
}
1492+
}
14841493
}
14851494

14861495
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)