[clang][darwin] Add support for the -mtargetos= option to the driver

The new -mtargetos= option is a replacement for the existing, OS-specific options
like -miphoneos-version-min=. This allows us to introduce support for new darwin OSes
easier as they won't require the use of a new option. The older options will be
deprecated and the use of the new option will be encouraged instead.

Differential Revision: https://reviews.llvm.org/D106316
This commit is contained in:
Alex Lorenz 2021-08-02 12:43:54 -07:00
parent 437e37dd55
commit f575f37182
4 changed files with 125 additions and 26 deletions

View File

@ -235,6 +235,7 @@ def warn_invalid_ios_deployment_target : Warning<
DefaultError;
def err_invalid_macos_32bit_deployment_target : Error<
"32-bit targets are not supported when building for Mac Catalyst">;
def err_drv_invalid_os_in_arg : Error<"invalid OS value '%0' in '%1'">;
def err_drv_conflicting_deployment_targets : Error<
"conflicting deployment targets, both '%0' and '%1' are present in environment">;
def err_arc_unsupported_on_runtime : Error<

View File

@ -3144,6 +3144,8 @@ def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
MarshallingInfoEnum<TargetOpts<"EABIVersion">, "Default">,
NormalizedValuesScope<"llvm::EABI">,
NormalizedValues<["Default", "EABI4", "EABI5", "GNU"]>;
def mtargetos_EQ : Joined<["-"], "mtargetos=">, Group<m_Group>,
HelpText<"Set the deployment target to be the specified OS and OS version">;
def mno_constant_cfstrings : Flag<["-"], "mno-constant-cfstrings">, Group<m_Group>;
def mno_global_merge : Flag<["-"], "mno-global-merge">, Group<m_Group>, Flags<[CC1Option]>,

View File

@ -1379,6 +1379,8 @@ struct DarwinPlatform {
enum SourceKind {
/// The OS was specified using the -target argument.
TargetArg,
/// The OS was specified using the -mtargetos= argument.
MTargetOSArg,
/// The OS was specified using the -m<os>-version-min argument.
OSVersionArg,
/// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
@ -1430,7 +1432,8 @@ struct DarwinPlatform {
void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
if (Argument)
return;
assert(Kind != TargetArg && Kind != OSVersionArg && "Invalid kind");
assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
"Invalid kind");
options::ID Opt;
switch (Platform) {
case DarwinPlatformKind::MacOS:
@ -1455,6 +1458,7 @@ struct DarwinPlatform {
std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
switch (Kind) {
case TargetArg:
case MTargetOSArg:
case OSVersionArg:
case InferredFromSDK:
case InferredFromArch:
@ -1466,6 +1470,33 @@ struct DarwinPlatform {
llvm_unreachable("Unsupported Darwin Source Kind");
}
void setEnvironment(llvm::Triple::EnvironmentType EnvType,
const VersionTuple &OSVersion,
const Optional<DarwinSDKInfo> &SDKInfo) {
switch (EnvType) {
case llvm::Triple::Simulator:
Environment = DarwinEnvironmentKind::Simulator;
break;
case llvm::Triple::MacABI: {
Environment = DarwinEnvironmentKind::MacCatalyst;
// The minimum native macOS target for MacCatalyst is macOS 10.15.
NativeTargetVersion = VersionTuple(10, 15);
if (HasOSVersion && SDKInfo) {
if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
OSVersion, NativeTargetVersion, None)) {
NativeTargetVersion = *MacOSVersion;
}
}
}
break;
}
default:
break;
}
}
static DarwinPlatform
createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A,
const Optional<DarwinSDKInfo> &SDKInfo) {
@ -1475,31 +1506,18 @@ struct DarwinPlatform {
TT.getOSVersion(Major, Minor, Micro);
if (Major == 0)
Result.HasOSVersion = false;
switch (TT.getEnvironment()) {
case llvm::Triple::Simulator:
Result.Environment = DarwinEnvironmentKind::Simulator;
break;
case llvm::Triple::MacABI: {
// The minimum native macOS target for MacCatalyst is macOS 10.15.
auto NativeTargetVersion = VersionTuple(10, 15);
if (Result.HasOSVersion && SDKInfo) {
if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
VersionTuple(Major, Minor, Micro), NativeTargetVersion,
None)) {
NativeTargetVersion = *MacOSVersion;
}
}
}
Result.Environment = DarwinEnvironmentKind::MacCatalyst;
Result.NativeTargetVersion = NativeTargetVersion;
break;
}
default:
break;
}
Result.setEnvironment(TT.getEnvironment(),
VersionTuple(Major, Minor, Micro), SDKInfo);
return Result;
}
static DarwinPlatform
createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion,
llvm::Triple::EnvironmentType Environment, Arg *A,
const Optional<DarwinSDKInfo> &SDKInfo) {
DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS),
OSVersion.getAsString(), A);
Result.InferSimulatorFromArch = false;
Result.setEnvironment(Environment, OSVersion, SDKInfo);
return Result;
}
static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform,
@ -1813,6 +1831,39 @@ Optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
Triple, OSVersion, Args.getLastArg(options::OPT_target), SDKInfo);
}
/// Returns the deployment target that's specified using the -mtargetos option.
Optional<DarwinPlatform>
getDeploymentTargetFromMTargetOSArg(DerivedArgList &Args,
const Driver &TheDriver,
const Optional<DarwinSDKInfo> &SDKInfo) {
auto *A = Args.getLastArg(options::OPT_mtargetos_EQ);
if (!A)
return None;
llvm::Triple TT(llvm::Twine("unknown-apple-") + A->getValue());
switch (TT.getOS()) {
case llvm::Triple::MacOSX:
case llvm::Triple::IOS:
case llvm::Triple::TvOS:
case llvm::Triple::WatchOS:
break;
default:
TheDriver.Diag(diag::err_drv_invalid_os_in_arg)
<< TT.getOSName() << A->getAsString(Args);
return None;
}
unsigned Major, Minor, Micro;
TT.getOSVersion(Major, Minor, Micro);
if (!Major) {
TheDriver.Diag(diag::err_drv_invalid_version_number)
<< A->getAsString(Args);
return None;
}
return DarwinPlatform::createFromMTargetOS(TT.getOS(),
VersionTuple(Major, Minor, Micro),
TT.getEnvironment(), A, SDKInfo);
}
Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
const ArgList &Args,
const Driver &TheDriver) {
@ -1861,6 +1912,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
Optional<DarwinPlatform> OSTarget =
getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
if (OSTarget) {
// Disallow mixing -target and -mtargetos=.
if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {
std::string TargetArgStr = OSTarget->getAsString(Args, Opts);
std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);
getDriver().Diag(diag::err_drv_cannot_mix_options)
<< TargetArgStr << MTargetOSArgStr;
}
Optional<DarwinPlatform> OSVersionArgTarget =
getDeploymentTargetFromOSVersionArg(Args, getDriver());
if (OSVersionArgTarget) {
@ -1892,6 +1950,18 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
}
}
} else if ((OSTarget = getDeploymentTargetFromMTargetOSArg(Args, getDriver(),
SDKInfo))) {
// The OS target can be specified using the -mtargetos= argument.
// Disallow mixing -mtargetos= and -m<os>version-min=.
Optional<DarwinPlatform> OSVersionArgTarget =
getDeploymentTargetFromOSVersionArg(Args, getDriver());
if (OSVersionArgTarget) {
std::string MTargetOSArgStr = OSTarget->getAsString(Args, Opts);
std::string OSVersionArgStr = OSVersionArgTarget->getAsString(Args, Opts);
getDriver().Diag(diag::err_drv_cannot_mix_options)
<< MTargetOSArgStr << OSVersionArgStr;
}
} else {
// The OS target can be specified using the -m<os>version-min argument.
OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver());

View File

@ -0,0 +1,26 @@
// RUN: %clang -mtargetos=macos11 -arch arm64 -arch x86_64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=MACOS %s
// RUN: %clang -mtargetos=ios14 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=IOS %s
// RUN: %clang -mtargetos=ios14-simulator -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=IOS_SIM %s
// RUN: %clang -mtargetos=ios14-macabi -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=MACCATALYST %s
// RUN: %clang -mtargetos=tvos14 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=TVOS %s
// RUN: %clang -mtargetos=watchos7.1 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=WATCHOS %s
// RUN: %clang -target arm64-apple-ios14 -mtargetos=ios14 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=NOMIX1 %s
// RUN: %clang -mtargetos=ios14 -arch arm64 -miphoneos-version-min=14 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=NOMIX2 %s
// RUN: %clang -mtargetos=darwin20 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=INVALIDOS %s
// RUN: %clang -mtargetos=ios -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=NOVERSION %s
// REQUIRES: darwin
// MACOS: "-cc1" "-triple" "arm64-apple-macosx11.0.0"
// MACOS-NEXT: "-cc1" "-triple" "x86_64-apple-macosx11.0.0"
// IOS: "-cc1" "-triple" "arm64-apple-ios14.0.0"
// IOS_SIM: "-cc1" "-triple" "arm64-apple-ios14.0.0-simulator"
// MACCATALYST: "-cc1" "-triple" "arm64-apple-ios14.0.0-macabi"
// TVOS: "-cc1" "-triple" "arm64-apple-tvos14.0.0"
// WATCHOS: "-cc1" "-triple" "arm64-apple-watchos7.1.0"
// NOMIX1: error: cannot specify '-mtargetos=ios14' along with '-target arm64-apple-ios14'
// NOMIX2: error: cannot specify '-miphoneos-version-min=14' along with '-mtargetos=ios14'
// INVALIDOS: error: invalid OS value 'darwin20' in '-mtargetos=darwin20'
// NOVERSION: error: invalid version number in '-mtargetos=ios'