summaryrefslogtreecommitdiffstats
path: root/lib/Driver/ToolChains/Darwin.cpp
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2017-12-09 02:27:11 +0000
committerAlex Lorenz <arphaman@gmail.com>2017-12-09 02:27:11 +0000
commitb3fb7b61929008665fef08dea8752df3a2636e25 (patch)
tree3bdb1f2cc8b8f86c6dc6004cd736b9887bdd3685 /lib/Driver/ToolChains/Darwin.cpp
parent147c0e441526f9407c4db7afb077965d6e9861ff (diff)
[driver][darwin] Refactor the target selection code, NFC
The simulator variant of Darwin's platforms is removed in favor of a new environment field. The code that selects the platform and the version is split into 4 different functions instead of being all in one function. This is an NFC commit, although it slightly improves the "invalid version number" diagnostic by displaying the environment variable instead of -m<os>-version-min if the OS version was derived from the environment. rdar://35813850 Differential Revision: https://reviews.llvm.org/D41035 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@320235 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Driver/ToolChains/Darwin.cpp')
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp601
1 files changed, 356 insertions, 245 deletions
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
index 2b0e59a6b5..f4ed52838d 100644
--- a/lib/Driver/ToolChains/Darwin.cpp
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -941,13 +941,10 @@ StringRef Darwin::getPlatformFamily() const {
case DarwinPlatformKind::MacOS:
return "MacOSX";
case DarwinPlatformKind::IPhoneOS:
- case DarwinPlatformKind::IPhoneOSSimulator:
return "iPhone";
case DarwinPlatformKind::TvOS:
- case DarwinPlatformKind::TvOSSimulator:
return "AppleTV";
case DarwinPlatformKind::WatchOS:
- case DarwinPlatformKind::WatchOSSimulator:
return "Watch";
}
llvm_unreachable("Unsupported platform");
@@ -971,17 +968,11 @@ StringRef Darwin::getOSLibraryNameSuffix() const {
case DarwinPlatformKind::MacOS:
return "osx";
case DarwinPlatformKind::IPhoneOS:
- return "ios";
- case DarwinPlatformKind::IPhoneOSSimulator:
- return "iossim";
+ return TargetEnvironment == NativeEnvironment ? "ios" : "iossim";
case DarwinPlatformKind::TvOS:
- return "tvos";
- case DarwinPlatformKind::TvOSSimulator:
- return "tvossim";
+ return TargetEnvironment == NativeEnvironment ? "tvos" : "tvossim";
case DarwinPlatformKind::WatchOS:
- return "watchos";
- case DarwinPlatformKind::WatchOSSimulator:
- return "watchossim";
+ return TargetEnvironment == NativeEnvironment ? "watchos" : "watchossim";
}
llvm_unreachable("Unsupported platform");
}
@@ -1172,28 +1163,131 @@ static std::string getSystemOrSDKMacOSVersion(StringRef MacOSSDKVersion) {
return MacOSSDKVersion;
}
-void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
- const OptTable &Opts = getDriver().getOpts();
+namespace {
+
+/// The Darwin OS that was selected or inferred from arguments / environment.
+struct DarwinPlatform {
+ enum SourceKind {
+ /// The OS was specified using the -target argument.
+ TargetArg,
+ /// The OS was specified using the -m<os>-version-min argument.
+ OSVersionArg,
+ /// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
+ DeploymentTargetEnv,
+ /// The OS was inferred from the SDK.
+ InferredFromSDK,
+ /// The OS was inferred from the -arch.
+ InferredFromArch
+ };
+
+ using DarwinPlatformKind = Darwin::DarwinPlatformKind;
+
+ DarwinPlatformKind getPlatform() const { return Platform; }
+
+ StringRef getOSVersion() const {
+ if (Kind == OSVersionArg)
+ return Argument->getValue();
+ return OSVersion;
+ }
- // Support allowing the SDKROOT environment variable used by xcrun and other
- // Xcode tools to define the default sysroot, by making it the default for
- // isysroot.
- if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
- // Warn if the path does not exist.
- if (!getVFS().exists(A->getValue()))
- getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
- } else {
- if (char *env = ::getenv("SDKROOT")) {
- // We only use this value as the default if it is an absolute path,
- // exists, and it is not the root path.
- if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
- StringRef(env) != "/") {
- Args.append(Args.MakeSeparateArg(
- nullptr, Opts.getOption(options::OPT_isysroot), env));
- }
+ /// Returns true if the target OS was explicitly specified.
+ bool isExplicitlySpecified() const { return Kind <= DeploymentTargetEnv; }
+
+ /// Adds the -m<os>-version-min argument to the compiler invocation.
+ void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
+ if (Argument)
+ return;
+ assert(Kind != TargetArg && Kind != OSVersionArg && "Invalid kind");
+ options::ID Opt;
+ switch (Platform) {
+ case DarwinPlatformKind::MacOS:
+ Opt = options::OPT_mmacosx_version_min_EQ;
+ break;
+ case DarwinPlatformKind::IPhoneOS:
+ Opt = options::OPT_miphoneos_version_min_EQ;
+ break;
+ case DarwinPlatformKind::TvOS:
+ Opt = options::OPT_mtvos_version_min_EQ;
+ break;
+ case DarwinPlatformKind::WatchOS:
+ Opt = options::OPT_mwatchos_version_min_EQ;
+ break;
+ }
+ Argument = Args.MakeJoinedArg(nullptr, Opts.getOption(Opt), OSVersion);
+ Args.append(Argument);
+ }
+
+ /// Returns the OS version with the argument / environment variable that
+ /// specified it.
+ std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
+ switch (Kind) {
+ case TargetArg:
+ case OSVersionArg:
+ case InferredFromSDK:
+ case InferredFromArch:
+ assert(Argument && "OS version argument not yet inferred");
+ return Argument->getAsString(Args);
+ case DeploymentTargetEnv:
+ return (llvm::Twine(EnvVarName) + "=" + OSVersion).str();
}
}
+ static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform,
+ Arg *A) {
+ return DarwinPlatform(OSVersionArg, Platform, A);
+ }
+ static DarwinPlatform createDeploymentTargetEnv(DarwinPlatformKind Platform,
+ StringRef EnvVarName,
+ StringRef Value) {
+ DarwinPlatform Result(DeploymentTargetEnv, Platform, Value);
+ Result.EnvVarName = EnvVarName;
+ return Result;
+ }
+ static DarwinPlatform createFromSDK(DarwinPlatformKind Platform,
+ StringRef Value) {
+ return DarwinPlatform(InferredFromSDK, Platform, Value);
+ }
+ static DarwinPlatform createFromArch(llvm::Triple::OSType OS,
+ StringRef Value) {
+ DarwinPlatformKind Platform;
+ switch (OS) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ Platform = DarwinPlatformKind::MacOS;
+ break;
+ case llvm::Triple::IOS:
+ Platform = DarwinPlatformKind::IPhoneOS;
+ break;
+ case llvm::Triple::TvOS:
+ Platform = DarwinPlatformKind::TvOS;
+ break;
+ case llvm::Triple::WatchOS:
+ Platform = DarwinPlatformKind::WatchOS;
+ break;
+ default:
+ llvm_unreachable("Unable to infer Darwin variant");
+ }
+ return DarwinPlatform(InferredFromArch, Platform, Value);
+ }
+
+private:
+ DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, Arg *Argument)
+ : Kind(Kind), Platform(Platform), Argument(Argument) {}
+ DarwinPlatform(SourceKind Kind, DarwinPlatformKind Platform, StringRef Value)
+ : Kind(Kind), Platform(Platform), OSVersion(Value), Argument(nullptr) {}
+
+ SourceKind Kind;
+ DarwinPlatformKind Platform;
+ std::string OSVersion;
+ Arg *Argument;
+ StringRef EnvVarName;
+};
+
+/// Returns the deployment target that's specified using the -m<os>-version-min
+/// argument.
+Optional<DarwinPlatform>
+getDeploymentTargetFromOSVersionArg(DerivedArgList &Args,
+ const Driver &TheDriver) {
Arg *OSXVersion = Args.getLastArg(options::OPT_mmacosx_version_min_EQ);
Arg *iOSVersion = Args.getLastArg(options::OPT_miphoneos_version_min_EQ,
options::OPT_mios_simulator_version_min_EQ);
@@ -1203,224 +1297,249 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Arg *WatchOSVersion =
Args.getLastArg(options::OPT_mwatchos_version_min_EQ,
options::OPT_mwatchos_simulator_version_min_EQ);
+ if (OSXVersion) {
+ if (iOSVersion || TvOSVersion || WatchOSVersion) {
+ TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
+ << OSXVersion->getAsString(Args)
+ << (iOSVersion ? iOSVersion
+ : TvOSVersion ? TvOSVersion : WatchOSVersion)
+ ->getAsString(Args);
+ }
+ return DarwinPlatform::createOSVersionArg(Darwin::MacOS, OSXVersion);
+ } else if (iOSVersion) {
+ if (TvOSVersion || WatchOSVersion) {
+ TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
+ << iOSVersion->getAsString(Args)
+ << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
+ }
+ return DarwinPlatform::createOSVersionArg(Darwin::IPhoneOS, iOSVersion);
+ } else if (TvOSVersion) {
+ if (WatchOSVersion) {
+ TheDriver.Diag(diag::err_drv_argument_not_allowed_with)
+ << TvOSVersion->getAsString(Args)
+ << WatchOSVersion->getAsString(Args);
+ }
+ return DarwinPlatform::createOSVersionArg(Darwin::TvOS, TvOSVersion);
+ } else if (WatchOSVersion)
+ return DarwinPlatform::createOSVersionArg(Darwin::WatchOS, WatchOSVersion);
+ return None;
+}
- unsigned Major, Minor, Micro;
- bool HadExtra;
+/// Returns the deployment target that's specified using the
+/// OS_DEPLOYMENT_TARGET environment variable.
+Optional<DarwinPlatform>
+getDeploymentTargetFromEnvironmentVariables(const Driver &TheDriver,
+ const llvm::Triple &Triple) {
+ std::string Targets[Darwin::LastDarwinPlatform + 1];
+ const char *EnvVars[] = {
+ "MACOSX_DEPLOYMENT_TARGET",
+ "IPHONEOS_DEPLOYMENT_TARGET",
+ "TVOS_DEPLOYMENT_TARGET",
+ "WATCHOS_DEPLOYMENT_TARGET",
+ };
+ static_assert(llvm::array_lengthof(EnvVars) == Darwin::LastDarwinPlatform + 1,
+ "Missing platform");
+ for (const auto &I : llvm::enumerate(llvm::makeArrayRef(EnvVars))) {
+ if (char *Env = ::getenv(I.value()))
+ Targets[I.index()] = Env;
+ }
- // The iOS deployment target that is explicitly specified via a command line
- // option or an environment variable.
- std::string ExplicitIOSDeploymentTargetStr;
-
- if (iOSVersion)
- ExplicitIOSDeploymentTargetStr = iOSVersion->getAsString(Args);
-
- if (OSXVersion && (iOSVersion || TvOSVersion || WatchOSVersion)) {
- getDriver().Diag(diag::err_drv_argument_not_allowed_with)
- << OSXVersion->getAsString(Args)
- << (iOSVersion ? iOSVersion :
- TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
- iOSVersion = TvOSVersion = WatchOSVersion = nullptr;
- } else if (iOSVersion && (TvOSVersion || WatchOSVersion)) {
- getDriver().Diag(diag::err_drv_argument_not_allowed_with)
- << iOSVersion->getAsString(Args)
- << (TvOSVersion ? TvOSVersion : WatchOSVersion)->getAsString(Args);
- TvOSVersion = WatchOSVersion = nullptr;
- } else if (TvOSVersion && WatchOSVersion) {
- getDriver().Diag(diag::err_drv_argument_not_allowed_with)
- << TvOSVersion->getAsString(Args)
- << WatchOSVersion->getAsString(Args);
- WatchOSVersion = nullptr;
- } else if (!OSXVersion && !iOSVersion && !TvOSVersion && !WatchOSVersion) {
- // If no deployment target was specified on the command line, check for
- // environment defines.
- std::string OSXTarget;
- std::string iOSTarget;
- std::string TvOSTarget;
- std::string WatchOSTarget;
-
- if (char *env = ::getenv("MACOSX_DEPLOYMENT_TARGET"))
- OSXTarget = env;
- if (char *env = ::getenv("IPHONEOS_DEPLOYMENT_TARGET"))
- iOSTarget = env;
- if (char *env = ::getenv("TVOS_DEPLOYMENT_TARGET"))
- TvOSTarget = env;
- if (char *env = ::getenv("WATCHOS_DEPLOYMENT_TARGET"))
- WatchOSTarget = env;
-
- if (!iOSTarget.empty())
- ExplicitIOSDeploymentTargetStr =
- std::string("IPHONEOS_DEPLOYMENT_TARGET=") + iOSTarget;
-
- // 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 (OSXTarget.empty() && iOSTarget.empty() && WatchOSTarget.empty() &&
- TvOSTarget.empty() && Args.hasArg(options::OPT_isysroot)) {
- if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
- StringRef isysroot = A->getValue();
- StringRef SDK = getSDKName(isysroot);
- if (SDK.size() > 0) {
- // 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"))
- iOSTarget = Version;
- else if (SDK.startswith("MacOSX"))
- OSXTarget = getSystemOrSDKMacOSVersion(Version);
- else if (SDK.startswith("WatchOS") ||
- SDK.startswith("WatchSimulator"))
- WatchOSTarget = Version;
- else if (SDK.startswith("AppleTVOS") ||
- SDK.startswith("AppleTVSimulator"))
- TvOSTarget = Version;
- }
- }
- }
- }
+ // Do not allow conflicts with the watchOS target.
+ if (!Targets[Darwin::WatchOS].empty() &&
+ (!Targets[Darwin::IPhoneOS].empty() || !Targets[Darwin::TvOS].empty())) {
+ TheDriver.Diag(diag::err_drv_conflicting_deployment_targets)
+ << "WATCHOS_DEPLOYMENT_TARGET"
+ << (!Targets[Darwin::IPhoneOS].empty() ? "IPHONEOS_DEPLOYMENT_TARGET"
+ : "TVOS_DEPLOYMENT_TARGET");
+ }
- // If no OS targets have been specified, try to guess platform from -target
- // or arch name and compute the version from the triple.
- if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() &&
- WatchOSTarget.empty()) {
- llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS;
+ // Do not allow conflicts with the tvOS target.
+ if (!Targets[Darwin::TvOS].empty() && !Targets[Darwin::IPhoneOS].empty()) {
+ TheDriver.Diag(diag::err_drv_conflicting_deployment_targets)
+ << "TVOS_DEPLOYMENT_TARGET"
+ << "IPHONEOS_DEPLOYMENT_TARGET";
+ }
- // Set the OSTy based on -target if -arch isn't present.
- if (Args.hasArg(options::OPT_target) && !Args.hasArg(options::OPT_arch)) {
- OSTy = getTriple().getOS();
- } else {
- StringRef MachOArchName = getMachOArchName(Args);
- if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
- MachOArchName == "arm64")
- OSTy = llvm::Triple::IOS;
- else if (MachOArchName == "armv7k")
- OSTy = llvm::Triple::WatchOS;
- else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
- MachOArchName != "armv7em")
- OSTy = llvm::Triple::MacOSX;
- }
+ // Allow conflicts among OSX and iOS for historical reasons, but choose the
+ // default platform.
+ if (!Targets[Darwin::MacOS].empty() &&
+ (!Targets[Darwin::IPhoneOS].empty() ||
+ !Targets[Darwin::WatchOS].empty() || !Targets[Darwin::TvOS].empty())) {
+ if (Triple.getArch() == llvm::Triple::arm ||
+ Triple.getArch() == llvm::Triple::aarch64 ||
+ Triple.getArch() == llvm::Triple::thumb)
+ Targets[Darwin::MacOS] = "";
+ else
+ Targets[Darwin::IPhoneOS] = Targets[Darwin::WatchOS] =
+ Targets[Darwin::TvOS] = "";
+ }
+ for (const auto &Target : llvm::enumerate(llvm::makeArrayRef(Targets))) {
+ if (!Target.value().empty())
+ return DarwinPlatform::createDeploymentTargetEnv(
+ (Darwin::DarwinPlatformKind)Target.index(), EnvVars[Target.index()],
+ Target.value());
+ }
+ return None;
+}
- if (OSTy != llvm::Triple::UnknownOS) {
- unsigned Major, Minor, Micro;
- std::string *OSTarget;
-
- switch (OSTy) {
- case llvm::Triple::Darwin:
- case llvm::Triple::MacOSX:
- if (!getTriple().getMacOSXVersion(Major, Minor, Micro))
- getDriver().Diag(diag::err_drv_invalid_darwin_version)
- << getTriple().getOSName();
- OSTarget = &OSXTarget;
- break;
- case llvm::Triple::IOS:
- getTriple().getiOSVersion(Major, Minor, Micro);
- OSTarget = &iOSTarget;
- break;
- case llvm::Triple::TvOS:
- getTriple().getOSVersion(Major, Minor, Micro);
- OSTarget = &TvOSTarget;
- break;
- case llvm::Triple::WatchOS:
- getTriple().getWatchOSVersion(Major, Minor, Micro);
- OSTarget = &WatchOSTarget;
- break;
- default:
- llvm_unreachable("Unexpected OS type");
- break;
- }
+/// Tries to infer the deployment target from the SDK specified by -isysroot
+/// (or SDKROOT).
+Optional<DarwinPlatform> inferDeploymentTargetFromSDK(DerivedArgList &Args) {
+ const Arg *A = Args.getLastArg(options::OPT_isysroot);
+ if (!A)
+ return None;
+ StringRef isysroot = A->getValue();
+ 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);
+ 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);
+ else if (SDK.startswith("AppleTVOS") || SDK.startswith("AppleTVSimulator"))
+ return DarwinPlatform::createFromSDK(Darwin::TvOS, Version);
+ }
+ return None;
+}
- llvm::raw_string_ostream(*OSTarget) << Major << '.' << Minor << '.'
- << Micro;
- }
- }
+std::string getOSVersion(llvm::Triple::OSType OS, const llvm::Triple &Triple,
+ const Driver &TheDriver) {
+ unsigned Major, Minor, Micro;
+ switch (OS) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ if (!Triple.getMacOSXVersion(Major, Minor, Micro))
+ TheDriver.Diag(diag::err_drv_invalid_darwin_version)
+ << Triple.getOSName();
+ break;
+ case llvm::Triple::IOS:
+ Triple.getiOSVersion(Major, Minor, Micro);
+ break;
+ case llvm::Triple::TvOS:
+ Triple.getOSVersion(Major, Minor, Micro);
+ break;
+ case llvm::Triple::WatchOS:
+ Triple.getWatchOSVersion(Major, Minor, Micro);
+ break;
+ default:
+ llvm_unreachable("Unexpected OS type");
+ break;
+ }
- // Do not allow conflicts with the watchOS target.
- if (!WatchOSTarget.empty() && (!iOSTarget.empty() || !TvOSTarget.empty())) {
- getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
- << "WATCHOS_DEPLOYMENT_TARGET"
- << (!iOSTarget.empty() ? "IPHONEOS_DEPLOYMENT_TARGET" :
- "TVOS_DEPLOYMENT_TARGET");
- }
+ std::string OSVersion;
+ llvm::raw_string_ostream(OSVersion) << Major << '.' << Minor << '.' << Micro;
+ return OSVersion;
+}
- // Do not allow conflicts with the tvOS target.
- if (!TvOSTarget.empty() && !iOSTarget.empty()) {
- getDriver().Diag(diag::err_drv_conflicting_deployment_targets)
- << "TVOS_DEPLOYMENT_TARGET"
- << "IPHONEOS_DEPLOYMENT_TARGET";
- }
+/// Tries to infer the target OS from the -arch.
+Optional<DarwinPlatform>
+inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
+ const llvm::Triple &Triple,
+ const Driver &TheDriver) {
+ llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS;
- // Allow conflicts among OSX and iOS for historical reasons, but choose the
- // default platform.
- if (!OSXTarget.empty() && (!iOSTarget.empty() ||
- !WatchOSTarget.empty() ||
- !TvOSTarget.empty())) {
- if (getTriple().getArch() == llvm::Triple::arm ||
- getTriple().getArch() == llvm::Triple::aarch64 ||
- getTriple().getArch() == llvm::Triple::thumb)
- OSXTarget = "";
- else
- iOSTarget = WatchOSTarget = TvOSTarget = "";
- }
+ // Set the OSTy based on -target if -arch isn't present.
+ if (Args.hasArg(options::OPT_target) && !Args.hasArg(options::OPT_arch)) {
+ OSTy = Triple.getOS();
+ } else {
+ StringRef MachOArchName = Toolchain.getMachOArchName(Args);
+ if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
+ MachOArchName == "arm64")
+ OSTy = llvm::Triple::IOS;
+ else if (MachOArchName == "armv7k")
+ OSTy = llvm::Triple::WatchOS;
+ else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
+ MachOArchName != "armv7em")
+ OSTy = llvm::Triple::MacOSX;
+ }
- if (!OSXTarget.empty()) {
- const Option O = Opts.getOption(options::OPT_mmacosx_version_min_EQ);
- OSXVersion = Args.MakeJoinedArg(nullptr, O, OSXTarget);
- Args.append(OSXVersion);
- } else if (!iOSTarget.empty()) {
- const Option O = Opts.getOption(options::OPT_miphoneos_version_min_EQ);
- iOSVersion = Args.MakeJoinedArg(nullptr, O, iOSTarget);
- Args.append(iOSVersion);
- } else if (!TvOSTarget.empty()) {
- const Option O = Opts.getOption(options::OPT_mtvos_version_min_EQ);
- TvOSVersion = Args.MakeJoinedArg(nullptr, O, TvOSTarget);
- Args.append(TvOSVersion);
- } else if (!WatchOSTarget.empty()) {
- const Option O = Opts.getOption(options::OPT_mwatchos_version_min_EQ);
- WatchOSVersion = Args.MakeJoinedArg(nullptr, O, WatchOSTarget);
- Args.append(WatchOSVersion);
+ if (OSTy == llvm::Triple::UnknownOS)
+ return None;
+ return DarwinPlatform::createFromArch(OSTy,
+ getOSVersion(OSTy, Triple, TheDriver));
+}
+
+} // namespace
+
+void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
+ const OptTable &Opts = getDriver().getOpts();
+
+ // Support allowing the SDKROOT environment variable used by xcrun and other
+ // Xcode tools to define the default sysroot, by making it the default for
+ // isysroot.
+ if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
+ // Warn if the path does not exist.
+ if (!getVFS().exists(A->getValue()))
+ getDriver().Diag(clang::diag::warn_missing_sysroot) << A->getValue();
+ } else {
+ if (char *env = ::getenv("SDKROOT")) {
+ // We only use this value as the default if it is an absolute path,
+ // exists, and it is not the root path.
+ if (llvm::sys::path::is_absolute(env) && getVFS().exists(env) &&
+ StringRef(env) != "/") {
+ Args.append(Args.MakeSeparateArg(
+ nullptr, Opts.getOption(options::OPT_isysroot), env));
+ }
}
}
- DarwinPlatformKind Platform;
- if (OSXVersion)
- Platform = MacOS;
- else if (iOSVersion)
- Platform = IPhoneOS;
- else if (TvOSVersion)
- Platform = TvOS;
- else if (WatchOSVersion)
- Platform = WatchOS;
- else
- llvm_unreachable("Unable to infer Darwin variant");
+ // The OS target can be specified using the -m<os>version-min argument.
+ Optional<DarwinPlatform> OSTarget =
+ getDeploymentTargetFromOSVersionArg(Args, getDriver());
+ // If no deployment target was specified on the command line, check for
+ // environment defines.
+ if (!OSTarget)
+ OSTarget =
+ getDeploymentTargetFromEnvironmentVariables(getDriver(), getTriple());
+ // 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);
+ // 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)
+ OSTarget =
+ inferDeploymentTargetFromArch(Args, *this, getTriple(), getDriver());
+
+ assert(OSTarget && "Unable to infer Darwin variant");
+ OSTarget->addOSVersionMinArgument(Args, Opts);
+ DarwinPlatformKind Platform = OSTarget->getPlatform();
+ unsigned Major, Minor, Micro;
+ bool HadExtra;
// Set the tool chain target information.
if (Platform == MacOS) {
- assert((!iOSVersion && !TvOSVersion && !WatchOSVersion) &&
- "Unknown target platform!");
- if (!Driver::GetReleaseVersion(OSXVersion->getValue(), Major, Minor, Micro,
- HadExtra) ||
+ if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
+ Micro, HadExtra) ||
HadExtra || Major != 10 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << OSXVersion->getAsString(Args);
+ << OSTarget->getAsString(Args, Opts);
} else if (Platform == IPhoneOS) {
- assert(iOSVersion && "Unknown target platform!");
- if (!Driver::GetReleaseVersion(iOSVersion->getValue(), Major, Minor, Micro,
- HadExtra) ||
+ if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
+ Micro, HadExtra) ||
HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << iOSVersion->getAsString(Args);
+ << OSTarget->getAsString(Args, Opts);
+ ;
// For 32-bit targets, the deployment target for iOS has to be earlier than
// iOS 11.
if (getTriple().isArch32Bit() && Major >= 11) {
// If the deployment target is explicitly specified, print a diagnostic.
- if (!ExplicitIOSDeploymentTargetStr.empty()) {
+ if (OSTarget->isExplicitlySpecified()) {
getDriver().Diag(diag::warn_invalid_ios_deployment_target)
- << ExplicitIOSDeploymentTargetStr;
- // Otherwise, set it to 10.99.99.
+ << OSTarget->getAsString(Args, Opts);
+ // Otherwise, set it to 10.99.99.
} else {
Major = 10;
Minor = 99;
@@ -1428,32 +1547,27 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
}
} else if (Platform == TvOS) {
- if (!Driver::GetReleaseVersion(TvOSVersion->getValue(), Major, Minor,
- Micro, HadExtra) || HadExtra ||
- Major >= 100 || Minor >= 100 || Micro >= 100)
+ if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
+ Micro, HadExtra) ||
+ HadExtra || Major >= 100 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << TvOSVersion->getAsString(Args);
+ << OSTarget->getAsString(Args, Opts);
} else if (Platform == WatchOS) {
- if (!Driver::GetReleaseVersion(WatchOSVersion->getValue(), Major, Minor,
- Micro, HadExtra) || HadExtra ||
- Major >= 10 || Minor >= 100 || Micro >= 100)
+ if (!Driver::GetReleaseVersion(OSTarget->getOSVersion(), Major, Minor,
+ Micro, HadExtra) ||
+ HadExtra || Major >= 10 || Minor >= 100 || Micro >= 100)
getDriver().Diag(diag::err_drv_invalid_version_number)
- << WatchOSVersion->getAsString(Args);
+ << OSTarget->getAsString(Args, Opts);
} else
llvm_unreachable("unknown kind of Darwin platform");
+ DarwinEnvironmentKind Environment = NativeEnvironment;
// Recognize iOS targets with an x86 architecture as the iOS simulator.
- if (iOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
- getTriple().getArch() == llvm::Triple::x86_64))
- Platform = IPhoneOSSimulator;
- if (TvOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
- getTriple().getArch() == llvm::Triple::x86_64))
- Platform = TvOSSimulator;
- if (WatchOSVersion && (getTriple().getArch() == llvm::Triple::x86 ||
- getTriple().getArch() == llvm::Triple::x86_64))
- Platform = WatchOSSimulator;
-
- setTarget(Platform, Major, Minor, Micro);
+ if (Platform != MacOS && (getTriple().getArch() == llvm::Triple::x86 ||
+ getTriple().getArch() == llvm::Triple::x86_64))
+ Environment = Simulator;
+
+ setTarget(Platform, Environment, Major, Minor, Micro);
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
StringRef SDK = getSDKName(A->getValue());
@@ -1777,15 +1891,12 @@ bool Darwin::isAlignedAllocationUnavailable() const {
OS = llvm::Triple::MacOSX;
break;
case IPhoneOS:
- case IPhoneOSSimulator:
OS = llvm::Triple::IOS;
break;
- case TvOS:
- case TvOSSimulator: // Earlier than 11.0.
+ case TvOS: // Earlier than 11.0.
OS = llvm::Triple::TvOS;
break;
- case WatchOS:
- case WatchOSSimulator: // Earlier than 4.0.
+ case WatchOS: // Earlier than 4.0.
OS = llvm::Triple::WatchOS;
break;
}