Skip to content

Commit 548e281

Browse files
committed
[Driver/Frontend] Thread the target SDK version through to the IR.
Teach the driver to pass the SDK version it computes (from the SDK settings JSON in a Darwin-based platform's SDK) down into the frontend. The frontend then sets that SDK version in the LLVM module, which eventually makes its way into the Mach-O file. Last part of rdar://problem/60332732.
1 parent 43bb415 commit 548e281

File tree

11 files changed

+110
-38
lines changed

11 files changed

+110
-38
lines changed

include/swift/Basic/LangOptions.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,9 @@ namespace swift {
7575
/// performed.
7676
llvm::Optional<llvm::Triple> TargetVariant;
7777

78+
/// The SDK version, if known.
79+
Optional<llvm::VersionTuple> SDKVersion;
80+
7881
///
7982
/// Language features
8083
///

include/swift/Driver/ToolChain.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,13 @@ class ToolChain {
136136
ExtraEnvironment(std::move(extraEnv)) {}
137137
};
138138

139+
/// Handle arguments common to all invocations of the frontend (compilation,
140+
/// module-merging, LLDB's REPL, etc).
141+
virtual void addCommonFrontendArgs(const OutputInfo &OI,
142+
const CommandOutput &output,
143+
const llvm::opt::ArgList &inputArgs,
144+
llvm::opt::ArgStringList &arguments) const;
145+
139146
virtual InvocationInfo constructInvocation(const CompileJobAction &job,
140147
const JobContext &context) const;
141148
virtual InvocationInfo constructInvocation(const InterpretJobAction &job,

include/swift/Option/FrontendOptions.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -702,4 +702,7 @@ def disable_interface_lockfile : Flag<["-"], "disable-interface-lock">,
702702
def bridging_header_directory_for_print: Separate<["-"], "bridging-header-directory-for-print">, MetaVarName<"<path>">,
703703
HelpText<"Directory for bridging header to be printed in compatibility header">;
704704

705+
def target_sdk_version : Separate<["-"], "target-sdk-version">,
706+
HelpText<"The version of target SDK used for compilation">;
707+
705708
} // end let Flags = [FrontendOption, NoDriverOption, HelpHidden]

lib/ClangImporter/ClangImporter.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -706,6 +706,12 @@ addCommonInvocationArguments(std::vector<std::string> &invocationArgStrs,
706706
invocationArgStrs.push_back("-target");
707707
invocationArgStrs.push_back(triple.str());
708708

709+
if (ctx.LangOpts.SDKVersion) {
710+
invocationArgStrs.push_back("-Xclang");
711+
invocationArgStrs.push_back(
712+
"-target-sdk-version=" + ctx.LangOpts.SDKVersion->getAsString());
713+
}
714+
709715
invocationArgStrs.push_back(ImporterImpl::moduleImportBufferName);
710716

711717
if (ctx.LangOpts.EnableAppExtensionRestrictions) {

lib/Driver/DarwinToolChains.cpp

Lines changed: 38 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -518,6 +518,26 @@ static Optional<llvm::VersionTuple> remapVersion(
518518
return None;
519519
}
520520

521+
Optional<llvm::VersionTuple>
522+
toolchains::Darwin::getTargetSDKVersion(const llvm::Triple &triple) const {
523+
if (!SDKInfo)
524+
return None;
525+
526+
// Retrieve the SDK version.
527+
auto SDKVersion = SDKInfo->getVersion();
528+
529+
// For the Mac Catalyst environment, we have a macOS SDK with a macOS
530+
// SDK version. Map that to the corresponding iOS version number to pass
531+
// down to the linker.
532+
if (tripleIsMacCatalystEnvironment(triple)) {
533+
return remapVersion(
534+
SDKInfo->getVersionMap().MacOS2iOSMacMapping, SDKVersion)
535+
.getValueOr(llvm::VersionTuple(0, 0, 0));
536+
}
537+
538+
return SDKVersion;
539+
}
540+
521541
void
522542
toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments,
523543
const JobContext &context) const {
@@ -584,23 +604,10 @@ toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments,
584604

585605
// Compute the SDK version.
586606
unsigned sdkMajor = 0, sdkMinor = 0, sdkMicro = 0;
587-
if (SDKInfo) {
588-
// Retrieve the SDK version.
589-
auto SDKVersion = SDKInfo->getVersion();
590-
591-
// For the Mac Catalyst environment, we have a macOS SDK with a macOS
592-
// SDK version. Map that to the corresponding iOS version number to pass
593-
// down to the linker.
594-
if (tripleIsMacCatalystEnvironment(triple)) {
595-
SDKVersion = remapVersion(
596-
SDKInfo->getVersionMap().MacOS2iOSMacMapping, SDKVersion)
597-
.getValueOr(llvm::VersionTuple(0, 0, 0));
598-
}
599-
600-
// Extract the version information.
601-
sdkMajor = SDKVersion.getMajor();
602-
sdkMinor = SDKVersion.getMinor().getValueOr(0);
603-
sdkMicro = SDKVersion.getSubminor().getValueOr(0);
607+
if (auto sdkVersion = getTargetSDKVersion(triple)) {
608+
sdkMajor = sdkVersion->getMajor();
609+
sdkMinor = sdkVersion->getMinor().getValueOr(0);
610+
sdkMicro = sdkVersion->getSubminor().getValueOr(0);
604611
}
605612

606613
Arguments.push_back("-platform_version");
@@ -617,6 +624,18 @@ toolchains::Darwin::addDeploymentTargetArgs(ArgStringList &Arguments,
617624
}
618625
}
619626

627+
void toolchains::Darwin::addCommonFrontendArgs(
628+
const OutputInfo &OI, const CommandOutput &output,
629+
const llvm::opt::ArgList &inputArgs,
630+
llvm::opt::ArgStringList &arguments) const {
631+
ToolChain::addCommonFrontendArgs(OI, output, inputArgs, arguments);
632+
633+
if (auto sdkVersion = getTargetSDKVersion(getTriple())) {
634+
arguments.push_back("-target-sdk-version");
635+
arguments.push_back(inputArgs.MakeArgString(sdkVersion->getAsString()));
636+
}
637+
}
638+
620639
ToolChain::InvocationInfo
621640
toolchains::Darwin::constructInvocation(const DynamicLinkJobAction &job,
622641
const JobContext &context) const {
@@ -860,9 +879,8 @@ toolchains::Darwin::validateArguments(DiagnosticEngine &diags,
860879
void
861880
toolchains::Darwin::validateOutputInfo(DiagnosticEngine &diags,
862881
const OutputInfo &outputInfo) const {
863-
// If we are linking and have been provided with an SDK, go read the SDK
864-
// information.
865-
if (outputInfo.shouldLink() && !outputInfo.SDKPath.empty()) {
882+
// If we have been provided with an SDK, go read the SDK information.
883+
if (!outputInfo.SDKPath.empty()) {
866884
auto SDKInfoOrErr = clang::driver::parseDarwinSDKInfo(
867885
*llvm::vfs::getRealFileSystem(), outputInfo.SDKPath);
868886
if (SDKInfoOrErr) {

lib/Driver/ToolChains.cpp

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -127,14 +127,10 @@ static bool addOutputsOfType(ArgStringList &Arguments,
127127
return Added;
128128
}
129129

130-
/// Handle arguments common to all invocations of the frontend (compilation,
131-
/// module-merging, LLDB's REPL, etc).
132-
static void addCommonFrontendArgs(const ToolChain &TC, const OutputInfo &OI,
133-
const CommandOutput &output,
134-
const ArgList &inputArgs,
135-
ArgStringList &arguments) {
136-
const llvm::Triple &Triple = TC.getTriple();
137-
130+
void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
131+
const CommandOutput &output,
132+
const ArgList &inputArgs,
133+
ArgStringList &arguments) const {
138134
// Only pass -target to the REPL or immediate modes if it was explicitly
139135
// specified on the command line.
140136
switch (OI.CompilerMode) {
@@ -375,8 +371,7 @@ ToolChain::constructInvocation(const CompileJobAction &job,
375371
if (context.Args.hasArg(options::OPT_parse_stdlib))
376372
Arguments.push_back("-disable-objc-attr-requires-foundation-module");
377373

378-
addCommonFrontendArgs(*this, context.OI, context.Output, context.Args,
379-
Arguments);
374+
addCommonFrontendArgs(context.OI, context.Output, context.Args, Arguments);
380375
addRuntimeLibraryFlags(context.OI, Arguments);
381376

382377
// Pass along an -import-objc-header arg, replacing the argument with the name
@@ -766,8 +761,7 @@ ToolChain::constructInvocation(const InterpretJobAction &job,
766761
if (context.Args.hasArg(options::OPT_parse_stdlib))
767762
Arguments.push_back("-disable-objc-attr-requires-foundation-module");
768763

769-
addCommonFrontendArgs(*this, context.OI, context.Output, context.Args,
770-
Arguments);
764+
addCommonFrontendArgs(context.OI, context.Output, context.Args, Arguments);
771765
addRuntimeLibraryFlags(context.OI, Arguments);
772766

773767
context.Args.AddLastArg(Arguments, options::OPT_import_objc_header);
@@ -986,8 +980,7 @@ ToolChain::constructInvocation(const MergeModuleJobAction &job,
986980
Arguments.push_back("-disable-diagnostic-passes");
987981
Arguments.push_back("-disable-sil-perf-optzns");
988982

989-
addCommonFrontendArgs(*this, context.OI, context.Output, context.Args,
990-
Arguments);
983+
addCommonFrontendArgs(context.OI, context.Output, context.Args, Arguments);
991984
addRuntimeLibraryFlags(context.OI, Arguments);
992985

993986
addOutputsOfType(Arguments, context.Output, context.Args,
@@ -1080,8 +1073,7 @@ ToolChain::constructInvocation(const REPLJobAction &job,
10801073
for (auto &s : getDriver().getSwiftProgramArgs())
10811074
FrontendArgs.push_back(s.c_str());
10821075

1083-
addCommonFrontendArgs(*this, context.OI, context.Output, context.Args,
1084-
FrontendArgs);
1076+
addCommonFrontendArgs(context.OI, context.Output, context.Args, FrontendArgs);
10851077
addRuntimeLibraryFlags(context.OI, FrontendArgs);
10861078

10871079
context.Args.AddLastArg(FrontendArgs, options::OPT_import_objc_header);
@@ -1166,8 +1158,7 @@ ToolChain::constructInvocation(const GeneratePCHJobAction &job,
11661158
Arguments.push_back(s.c_str());
11671159
Arguments.push_back("-frontend");
11681160

1169-
addCommonFrontendArgs(*this, context.OI, context.Output, context.Args,
1170-
Arguments);
1161+
addCommonFrontendArgs(context.OI, context.Output, context.Args, Arguments);
11711162
addRuntimeLibraryFlags(context.OI, Arguments);
11721163

11731164
addOutputsOfType(Arguments, context.Output, context.Args,

lib/Driver/ToolChains.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,11 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
4848
void addDeploymentTargetArgs(llvm::opt::ArgStringList &Arguments,
4949
const JobContext &context) const;
5050

51+
void addCommonFrontendArgs(
52+
const OutputInfo &OI, const CommandOutput &output,
53+
const llvm::opt::ArgList &inputArgs,
54+
llvm::opt::ArgStringList &arguments) const override;
55+
5156
InvocationInfo constructInvocation(const InterpretJobAction &job,
5257
const JobContext &context) const override;
5358
InvocationInfo constructInvocation(const DynamicLinkJobAction &job,
@@ -66,6 +71,10 @@ class LLVM_LIBRARY_VISIBILITY Darwin : public ToolChain {
6671

6772
bool shouldStoreInvocationInDebugInfo() const override;
6873

74+
/// Retrieve the target SDK version for the given target triple.
75+
Optional<llvm::VersionTuple>
76+
getTargetSDKVersion(const llvm::Triple &triple) const ;
77+
6978
/// Information about the SDK that the application is being built against.
7079
/// This information is only used by the linker, so it is only populated
7180
/// when there will be a linker job.

lib/Frontend/CompilerInvocation.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,18 @@ static bool ParseLangArgs(LangOptions &Opts, ArgList &Args,
594594
Diags.diagnose(SourceLoc(), diag::error_unsupported_target_os, TargetArgOS);
595595
}
596596

597+
// Parse the SDK version.
598+
if (Arg *A = Args.getLastArg(options::OPT_target_sdk_version)) {
599+
auto vers = version::Version::parseVersionString(
600+
A->getValue(), SourceLoc(), &Diags);
601+
if (vers.hasValue()) {
602+
Opts.SDKVersion = *vers;
603+
} else {
604+
Diags.diagnose(SourceLoc(), diag::error_invalid_arg_value,
605+
A->getAsString(Args), A->getValue());
606+
}
607+
}
608+
597609
return HadError || UnsupportedOS || UnsupportedArch;
598610
}
599611

@@ -1434,6 +1446,7 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
14341446
Opts.AutolinkRuntimeCompatibilityDynamicReplacementLibraryVersion =
14351447
getRuntimeCompatVersion();
14361448
}
1449+
14371450
return false;
14381451
}
14391452

lib/IRGen/IRGen.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -890,6 +890,13 @@ static void initLLVMModule(const IRGenModule &IGM, ModuleDecl &M) {
890890

891891
Module->setTargetTriple(IGM.Triple.str());
892892

893+
if (IGM.Context.LangOpts.SDKVersion) {
894+
if (Module->getSDKVersion().empty())
895+
Module->setSDKVersion(*IGM.Context.LangOpts.SDKVersion);
896+
else
897+
assert(Module->getSDKVersion() == *IGM.Context.LangOpts.SDKVersion);
898+
}
899+
893900
// Set the module's string representation.
894901
Module->setDataLayout(IGM.DataLayout.getStringRepresentation());
895902

test/Driver/sdk-version.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Check reading the SDKSettings.json from an SDK
2+
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -sdk %S/Inputs/MacOSX10.15.versioned.sdk %s 2>&1 | %FileCheck -check-prefix MACOS_10_15 %s
3+
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -sdk %S/Inputs/MacOSX10.15.4.versioned.sdk %s 2>&1 | %FileCheck -check-prefix MACOS_10_15_4 %s
4+
// RUN: %swiftc_driver -driver-print-jobs -target x86_64-apple-macosx10.9 -sdk %S/Inputs/MacOSX10.15.sdk %s 2>&1 | %FileCheck -check-prefix MACOS_UNVERSIONED %s
5+
6+
// MACOS_10_15: -target-sdk-version 10.15
7+
// MACOS_10_15_4: -target-sdk-version 10.15.4
8+
// MACOS_UNVERSIONED-NOT: -target-sdk-version

0 commit comments

Comments
 (0)