diff options
author | Alex Lorenz <arphaman@gmail.com> | 2018-12-17 19:19:15 +0000 |
---|---|---|
committer | Alex Lorenz <arphaman@gmail.com> | 2018-12-17 19:19:15 +0000 |
commit | 228f2c50c5313094fa41671e6ac2d1548db7d19d (patch) | |
tree | 4fa43edefd07bf14fc1f58c62999da5764b8ce9b /lib/Driver/ToolChains/Darwin.cpp | |
parent | dbc63abadbe81029b9f65b6e8160046fa26f1646 (diff) |
[darwin] parse the SDK settings from SDKSettings.json if it exists and
pass in the -target-sdk-version to the compiler and backend
This commit adds support for reading the SDKSettings.json file in the Darwin
driver. This file is used by the driver to determine the SDK's version, and it
uses that information to pass it down to the compiler using the new
-target-sdk-version= option. This option is then used to set the appropriate
SDK Version module metadata introduced in r349119.
Note: I had to adjust the two ast tests as the SDKROOT environment variable
on macOS caused SDK version to be picked up for the compilation of source file
but not the AST.
rdar://45774000
Differential Revision: https://reviews.llvm.org/D55673
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@349380 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/ToolChains/Darwin.cpp')
-rw-r--r-- | lib/Driver/ToolChains/Darwin.cpp | 115 |
1 files changed, 87 insertions, 28 deletions
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp index e5dafa2b09..0cc187ab47 100644 --- a/lib/Driver/ToolChains/Darwin.cpp +++ b/lib/Driver/ToolChains/Darwin.cpp @@ -1287,6 +1287,18 @@ struct DarwinPlatform { return DarwinPlatform(InferredFromArch, getPlatformFromOS(OS), Value); } + /// Constructs an inferred SDKInfo value based on the version inferred from + /// the SDK path itself. Only works for values that were created by inferring + /// the platform from the SDKPath. + DarwinSDKInfo inferSDKInfo() { + assert(Kind == InferredFromSDK && "can infer SDK info only"); + llvm::VersionTuple Version; + bool IsValid = !Version.tryParse(OSVersion); + (void)IsValid; + assert(IsValid && "invalid SDK version"); + return DarwinSDKInfo(Version); + } + private: DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument) : Kind(Kind), Platform(Platform), Argument(Argument) {} @@ -1420,8 +1432,11 @@ getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver, } /// Tries to infer the deployment target from the SDK specified by -isysroot -/// (or SDKROOT). -Optional<DarwinPlatform> inferDeploymentTargetFromSDK(DerivedArgList &Args) { +/// (or SDKROOT). Uses the version specified in the SDKSettings.json file if +/// it's available. +Optional<DarwinPlatform> +inferDeploymentTargetFromSDK(DerivedArgList &Args, + const Optional<DarwinSDKInfo> &SDKInfo) { const Arg *A = Args.getLastArg(options::OPT_isysroot); if (!A) return None; @@ -1429,28 +1444,37 @@ Optional<DarwinPlatform> inferDeploymentTargetFromSDK(DerivedArgList &Args) { StringRef SDK = Darwin::getSDKName(isysroot); if (!SDK.size()) return None; - // Slice the version number out. - // Version number is between the first and the last number. - size_t StartVer = SDK.find_first_of("0123456789"); - size_t EndVer = SDK.find_last_of("0123456789"); - if (StartVer != StringRef::npos && EndVer > StartVer) { - StringRef Version = SDK.slice(StartVer, EndVer + 1); - if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator")) - return DarwinPlatform::createFromSDK( - Darwin::IPhoneOS, Version, - /*IsSimulator=*/SDK.startswith("iPhoneSimulator")); - else if (SDK.startswith("MacOSX")) - return DarwinPlatform::createFromSDK(Darwin::MacOS, - getSystemOrSDKMacOSVersion(Version)); - else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")) - return DarwinPlatform::createFromSDK( - Darwin::WatchOS, Version, - /*IsSimulator=*/SDK.startswith("WatchSimulator")); - else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator")) - return DarwinPlatform::createFromSDK( - Darwin::TvOS, Version, - /*IsSimulator=*/SDK.startswith("AppleTVSimulator")); - } + + std::string Version; + if (SDKInfo) { + // Get the version from the SDKSettings.json if it's available. + Version = SDKInfo->getVersion().getAsString(); + } else { + // Slice the version number out. + // Version number is between the first and the last number. + size_t StartVer = SDK.find_first_of("0123456789"); + size_t EndVer = SDK.find_last_of("0123456789"); + if (StartVer != StringRef::npos && EndVer > StartVer) + Version = SDK.slice(StartVer, EndVer + 1); + } + if (Version.empty()) + return None; + + if (SDK.startswith("iPhoneOS") || SDK.startswith("iPhoneSimulator")) + return DarwinPlatform::createFromSDK( + Darwin::IPhoneOS, Version, + /*IsSimulator=*/SDK.startswith("iPhoneSimulator")); + else if (SDK.startswith("MacOSX")) + return DarwinPlatform::createFromSDK(Darwin::MacOS, + getSystemOrSDKMacOSVersion(Version)); + else if (SDK.startswith("WatchOS") || SDK.startswith("WatchSimulator")) + return DarwinPlatform::createFromSDK( + Darwin::WatchOS, Version, + /*IsSimulator=*/SDK.startswith("WatchSimulator")); + else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator")) + return DarwinPlatform::createFromSDK( + Darwin::TvOS, Version, + /*IsSimulator=*/SDK.startswith("AppleTVSimulator")); return None; } @@ -1525,6 +1549,22 @@ Optional<DarwinPlatform> getDeploymentTargetFromTargetArg( Args.getLastArg(options::OPT_target)); } +Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS, + const ArgList &Args, + const Driver &TheDriver) { + const Arg *A = Args.getLastArg(options::OPT_isysroot); + if (!A) + return None; + StringRef isysroot = A->getValue(); + auto SDKInfoOrErr = driver::parseDarwinSDKInfo(VFS, isysroot); + if (!SDKInfoOrErr) { + llvm::consumeError(SDKInfoOrErr.takeError()); + TheDriver.Diag(diag::warn_drv_darwin_sdk_invalid_settings); + return None; + } + return *SDKInfoOrErr; +} + } // namespace void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { @@ -1549,6 +1589,10 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { } } + // Read the SDKSettings.json file for more information, like the SDK version + // that we can pass down to the compiler. + SDKInfo = parseSDKSettings(getVFS(), Args, getDriver()); + // The OS and the version can be specified using the -target argument. Optional<DarwinPlatform> OSTarget = getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver()); @@ -1594,16 +1638,22 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const { getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple()); if (OSTarget) { // Don't infer simulator from the arch when the SDK is also specified. - Optional<DarwinPlatform> SDKTarget = inferDeploymentTargetFromSDK(Args); + Optional<DarwinPlatform> SDKTarget = + inferDeploymentTargetFromSDK(Args, SDKInfo); if (SDKTarget) OSTarget->setEnvironment(SDKTarget->getEnvironment()); } } // If there is no command-line argument to specify the Target version and // no environment variable defined, see if we can set the default based - // on -isysroot. - if (!OSTarget) - OSTarget = inferDeploymentTargetFromSDK(Args); + // on -isysroot using SDKSettings.json if it exists. + if (!OSTarget) { + OSTarget = inferDeploymentTargetFromSDK(Args, SDKInfo); + /// If the target was successfully constructed from the SDK path, try to + /// infer the SDK info if the SDK doesn't have it. + if (OSTarget && !SDKInfo) + SDKInfo = OSTarget->inferSDKInfo(); + } // If no OS targets have been specified, try to guess platform from -target // or arch name and compute the version from the triple. if (!OSTarget) @@ -2046,6 +2096,15 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs, options::OPT_fno_aligned_allocation) && isAlignedAllocationUnavailable()) CC1Args.push_back("-faligned-alloc-unavailable"); + + if (SDKInfo) { + /// Pass the SDK version to the compiler when the SDK information is + /// available. + std::string Arg; + llvm::raw_string_ostream OS(Arg); + OS << "-target-sdk-version=" << SDKInfo->getVersion(); + CC1Args.push_back(DriverArgs.MakeArgString(OS.str())); + } } DerivedArgList * |