Skip to content

Commit f575f37

Browse files
committed
[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
1 parent 437e37d commit f575f37

File tree

4 files changed

+118
-19
lines changed

4 files changed

+118
-19
lines changed

clang/include/clang/Basic/DiagnosticDriverKinds.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ def warn_invalid_ios_deployment_target : Warning<
235235
DefaultError;
236236
def err_invalid_macos_32bit_deployment_target : Error<
237237
"32-bit targets are not supported when building for Mac Catalyst">;
238+
def err_drv_invalid_os_in_arg : Error<"invalid OS value '%0' in '%1'">;
238239
def err_drv_conflicting_deployment_targets : Error<
239240
"conflicting deployment targets, both '%0' and '%1' are present in environment">;
240241
def err_arc_unsupported_on_runtime : Error<

clang/include/clang/Driver/Options.td

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3144,6 +3144,8 @@ def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
31443144
MarshallingInfoEnum<TargetOpts<"EABIVersion">, "Default">,
31453145
NormalizedValuesScope<"llvm::EABI">,
31463146
NormalizedValues<["Default", "EABI4", "EABI5", "GNU"]>;
3147+
def mtargetos_EQ : Joined<["-"], "mtargetos=">, Group<m_Group>,
3148+
HelpText<"Set the deployment target to be the specified OS and OS version">;
31473149

31483150
def mno_constant_cfstrings : Flag<["-"], "mno-constant-cfstrings">, Group<m_Group>;
31493151
def mno_global_merge : Flag<["-"], "mno-global-merge">, Group<m_Group>, Flags<[CC1Option]>,

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 89 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,8 @@ struct DarwinPlatform {
13791379
enum SourceKind {
13801380
/// The OS was specified using the -target argument.
13811381
TargetArg,
1382+
/// The OS was specified using the -mtargetos= argument.
1383+
MTargetOSArg,
13821384
/// The OS was specified using the -m<os>-version-min argument.
13831385
OSVersionArg,
13841386
/// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
@@ -1430,7 +1432,8 @@ struct DarwinPlatform {
14301432
void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
14311433
if (Argument)
14321434
return;
1433-
assert(Kind != TargetArg && Kind != OSVersionArg && "Invalid kind");
1435+
assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
1436+
"Invalid kind");
14341437
options::ID Opt;
14351438
switch (Platform) {
14361439
case DarwinPlatformKind::MacOS:
@@ -1455,6 +1458,7 @@ struct DarwinPlatform {
14551458
std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
14561459
switch (Kind) {
14571460
case TargetArg:
1461+
case MTargetOSArg:
14581462
case OSVersionArg:
14591463
case InferredFromSDK:
14601464
case InferredFromArch:
@@ -1466,40 +1470,54 @@ struct DarwinPlatform {
14661470
llvm_unreachable("Unsupported Darwin Source Kind");
14671471
}
14681472

1469-
static DarwinPlatform
1470-
createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A,
1471-
const Optional<DarwinSDKInfo> &SDKInfo) {
1472-
DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
1473-
A);
1474-
unsigned Major, Minor, Micro;
1475-
TT.getOSVersion(Major, Minor, Micro);
1476-
if (Major == 0)
1477-
Result.HasOSVersion = false;
1478-
1479-
switch (TT.getEnvironment()) {
1473+
void setEnvironment(llvm::Triple::EnvironmentType EnvType,
1474+
const VersionTuple &OSVersion,
1475+
const Optional<DarwinSDKInfo> &SDKInfo) {
1476+
switch (EnvType) {
14801477
case llvm::Triple::Simulator:
1481-
Result.Environment = DarwinEnvironmentKind::Simulator;
1478+
Environment = DarwinEnvironmentKind::Simulator;
14821479
break;
14831480
case llvm::Triple::MacABI: {
1481+
Environment = DarwinEnvironmentKind::MacCatalyst;
14841482
// The minimum native macOS target for MacCatalyst is macOS 10.15.
1485-
auto NativeTargetVersion = VersionTuple(10, 15);
1486-
if (Result.HasOSVersion && SDKInfo) {
1483+
NativeTargetVersion = VersionTuple(10, 15);
1484+
if (HasOSVersion && SDKInfo) {
14871485
if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
14881486
DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
14891487
if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
1490-
VersionTuple(Major, Minor, Micro), NativeTargetVersion,
1491-
None)) {
1488+
OSVersion, NativeTargetVersion, None)) {
14921489
NativeTargetVersion = *MacOSVersion;
14931490
}
14941491
}
14951492
}
1496-
Result.Environment = DarwinEnvironmentKind::MacCatalyst;
1497-
Result.NativeTargetVersion = NativeTargetVersion;
14981493
break;
14991494
}
15001495
default:
15011496
break;
15021497
}
1498+
}
1499+
1500+
static DarwinPlatform
1501+
createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A,
1502+
const Optional<DarwinSDKInfo> &SDKInfo) {
1503+
DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
1504+
A);
1505+
unsigned Major, Minor, Micro;
1506+
TT.getOSVersion(Major, Minor, Micro);
1507+
if (Major == 0)
1508+
Result.HasOSVersion = false;
1509+
Result.setEnvironment(TT.getEnvironment(),
1510+
VersionTuple(Major, Minor, Micro), SDKInfo);
1511+
return Result;
1512+
}
1513+
static DarwinPlatform
1514+
createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion,
1515+
llvm::Triple::EnvironmentType Environment, Arg *A,
1516+
const Optional<DarwinSDKInfo> &SDKInfo) {
1517+
DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS),
1518+
OSVersion.getAsString(), A);
1519+
Result.InferSimulatorFromArch = false;
1520+
Result.setEnvironment(Environment, OSVersion, SDKInfo);
15031521
return Result;
15041522
}
15051523
static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform,
@@ -1813,6 +1831,39 @@ Optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
18131831
Triple, OSVersion, Args.getLastArg(options::OPT_target), SDKInfo);
18141832
}
18151833

1834+
/// Returns the deployment target that's specified using the -mtargetos option.
1835+
Optional<DarwinPlatform>
1836+
getDeploymentTargetFromMTargetOSArg(DerivedArgList &Args,
1837+
const Driver &TheDriver,
1838+
const Optional<DarwinSDKInfo> &SDKInfo) {
1839+
auto *A = Args.getLastArg(options::OPT_mtargetos_EQ);
1840+
if (!A)
1841+
return None;
1842+
llvm::Triple TT(llvm::Twine("unknown-apple-") + A->getValue());
1843+
switch (TT.getOS()) {
1844+
case llvm::Triple::MacOSX:
1845+
case llvm::Triple::IOS:
1846+
case llvm::Triple::TvOS:
1847+
case llvm::Triple::WatchOS:
1848+
break;
1849+
default:
1850+
TheDriver.Diag(diag::err_drv_invalid_os_in_arg)
1851+
<< TT.getOSName() << A->getAsString(Args);
1852+
return None;
1853+
}
1854+
1855+
unsigned Major, Minor, Micro;
1856+
TT.getOSVersion(Major, Minor, Micro);
1857+
if (!Major) {
1858+
TheDriver.Diag(diag::err_drv_invalid_version_number)
1859+
<< A->getAsString(Args);
1860+
return None;
1861+
}
1862+
return DarwinPlatform::createFromMTargetOS(TT.getOS(),
1863+
VersionTuple(Major, Minor, Micro),
1864+
TT.getEnvironment(), A, SDKInfo);
1865+
}
1866+
18161867
Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
18171868
const ArgList &Args,
18181869
const Driver &TheDriver) {
@@ -1861,6 +1912,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
18611912
Optional<DarwinPlatform> OSTarget =
18621913
getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
18631914
if (OSTarget) {
1915+
// Disallow mixing -target and -mtargetos=.
1916+
if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {
1917+
std::string TargetArgStr = OSTarget->getAsString(Args, Opts);
1918+
std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);
1919+
getDriver().Diag(diag::err_drv_cannot_mix_options)
1920+
<< TargetArgStr << MTargetOSArgStr;
1921+
}
18641922
Optional<DarwinPlatform> OSVersionArgTarget =
18651923
getDeploymentTargetFromOSVersionArg(Args, getDriver());
18661924
if (OSVersionArgTarget) {
@@ -1892,6 +1950,18 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
18921950
}
18931951
}
18941952
}
1953+
} else if ((OSTarget = getDeploymentTargetFromMTargetOSArg(Args, getDriver(),
1954+
SDKInfo))) {
1955+
// The OS target can be specified using the -mtargetos= argument.
1956+
// Disallow mixing -mtargetos= and -m<os>version-min=.
1957+
Optional<DarwinPlatform> OSVersionArgTarget =
1958+
getDeploymentTargetFromOSVersionArg(Args, getDriver());
1959+
if (OSVersionArgTarget) {
1960+
std::string MTargetOSArgStr = OSTarget->getAsString(Args, Opts);
1961+
std::string OSVersionArgStr = OSVersionArgTarget->getAsString(Args, Opts);
1962+
getDriver().Diag(diag::err_drv_cannot_mix_options)
1963+
<< MTargetOSArgStr << OSVersionArgStr;
1964+
}
18951965
} else {
18961966
// The OS target can be specified using the -m<os>version-min argument.
18971967
OSTarget = getDeploymentTargetFromOSVersionArg(Args, getDriver());

clang/test/Driver/mtargetos-darwin.c

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %clang -mtargetos=macos11 -arch arm64 -arch x86_64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=MACOS %s
2+
// RUN: %clang -mtargetos=ios14 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=IOS %s
3+
// RUN: %clang -mtargetos=ios14-simulator -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=IOS_SIM %s
4+
// RUN: %clang -mtargetos=ios14-macabi -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=MACCATALYST %s
5+
// RUN: %clang -mtargetos=tvos14 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=TVOS %s
6+
// RUN: %clang -mtargetos=watchos7.1 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=WATCHOS %s
7+
8+
// RUN: %clang -target arm64-apple-ios14 -mtargetos=ios14 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=NOMIX1 %s
9+
// RUN: %clang -mtargetos=ios14 -arch arm64 -miphoneos-version-min=14 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=NOMIX2 %s
10+
// RUN: %clang -mtargetos=darwin20 -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=INVALIDOS %s
11+
// RUN: %clang -mtargetos=ios -arch arm64 -c %s -o %t.o -### 2>&1 | FileCheck --check-prefix=NOVERSION %s
12+
13+
// REQUIRES: darwin
14+
15+
// MACOS: "-cc1" "-triple" "arm64-apple-macosx11.0.0"
16+
// MACOS-NEXT: "-cc1" "-triple" "x86_64-apple-macosx11.0.0"
17+
// IOS: "-cc1" "-triple" "arm64-apple-ios14.0.0"
18+
// IOS_SIM: "-cc1" "-triple" "arm64-apple-ios14.0.0-simulator"
19+
// MACCATALYST: "-cc1" "-triple" "arm64-apple-ios14.0.0-macabi"
20+
// TVOS: "-cc1" "-triple" "arm64-apple-tvos14.0.0"
21+
// WATCHOS: "-cc1" "-triple" "arm64-apple-watchos7.1.0"
22+
23+
// NOMIX1: error: cannot specify '-mtargetos=ios14' along with '-target arm64-apple-ios14'
24+
// NOMIX2: error: cannot specify '-miphoneos-version-min=14' along with '-mtargetos=ios14'
25+
// INVALIDOS: error: invalid OS value 'darwin20' in '-mtargetos=darwin20'
26+
// NOVERSION: error: invalid version number in '-mtargetos=ios'

0 commit comments

Comments
 (0)