Skip to content

Commit b6cce95

Browse files
authored
Merge pull request #3133 from apple/neg/fixup-mtargetos
[clang][darwin] Add support for the -mtargetos= option to the driver
2 parents 421c89c + 2967f33 commit b6cce95

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
@@ -3193,6 +3193,8 @@ def meabi : Separate<["-"], "meabi">, Group<m_Group>, Flags<[CC1Option]>,
31933193
MarshallingInfoEnum<TargetOpts<"EABIVersion">, "Default">,
31943194
NormalizedValuesScope<"llvm::EABI">,
31953195
NormalizedValues<["Default", "EABI4", "EABI5", "GNU"]>;
3196+
def mtargetos_EQ : Joined<["-"], "mtargetos=">, Group<m_Group>,
3197+
HelpText<"Set the deployment target to be the specified OS and OS version">;
31963198

31973199
def mno_constant_cfstrings : Flag<["-"], "mno-constant-cfstrings">, Group<m_Group>;
31983200
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
@@ -1418,6 +1418,8 @@ struct DarwinPlatform {
14181418
enum SourceKind {
14191419
/// The OS was specified using the -target argument.
14201420
TargetArg,
1421+
/// The OS was specified using the -mtargetos= argument.
1422+
MTargetOSArg,
14211423
/// The OS was specified using the -m<os>-version-min argument.
14221424
OSVersionArg,
14231425
/// The OS was specified using the OS_DEPLOYMENT_TARGET environment.
@@ -1469,7 +1471,8 @@ struct DarwinPlatform {
14691471
void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
14701472
if (Argument)
14711473
return;
1472-
assert(Kind != TargetArg && Kind != OSVersionArg && "Invalid kind");
1474+
assert(Kind != TargetArg && Kind != MTargetOSArg && Kind != OSVersionArg &&
1475+
"Invalid kind");
14731476
options::ID Opt;
14741477
switch (Platform) {
14751478
case DarwinPlatformKind::MacOS:
@@ -1494,6 +1497,7 @@ struct DarwinPlatform {
14941497
std::string getAsString(DerivedArgList &Args, const OptTable &Opts) {
14951498
switch (Kind) {
14961499
case TargetArg:
1500+
case MTargetOSArg:
14971501
case OSVersionArg:
14981502
case InferredFromSDK:
14991503
case InferredFromArch:
@@ -1505,40 +1509,54 @@ struct DarwinPlatform {
15051509
llvm_unreachable("Unsupported Darwin Source Kind");
15061510
}
15071511

1508-
static DarwinPlatform
1509-
createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A,
1510-
const Optional<DarwinSDKInfo> &SDKInfo) {
1511-
DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
1512-
A);
1513-
unsigned Major, Minor, Micro;
1514-
TT.getOSVersion(Major, Minor, Micro);
1515-
if (Major == 0)
1516-
Result.HasOSVersion = false;
1517-
1518-
switch (TT.getEnvironment()) {
1512+
void setEnvironment(llvm::Triple::EnvironmentType EnvType,
1513+
const VersionTuple &OSVersion,
1514+
const Optional<DarwinSDKInfo> &SDKInfo) {
1515+
switch (EnvType) {
15191516
case llvm::Triple::Simulator:
1520-
Result.Environment = DarwinEnvironmentKind::Simulator;
1517+
Environment = DarwinEnvironmentKind::Simulator;
15211518
break;
15221519
case llvm::Triple::MacABI: {
1520+
Environment = DarwinEnvironmentKind::MacCatalyst;
15231521
// The minimum native macOS target for MacCatalyst is macOS 10.15.
1524-
auto NativeTargetVersion = VersionTuple(10, 15);
1525-
if (Result.HasOSVersion && SDKInfo) {
1522+
NativeTargetVersion = VersionTuple(10, 15);
1523+
if (HasOSVersion && SDKInfo) {
15261524
if (const auto *MacCatalystToMacOSMapping = SDKInfo->getVersionMapping(
15271525
DarwinSDKInfo::OSEnvPair::macCatalystToMacOSPair())) {
15281526
if (auto MacOSVersion = MacCatalystToMacOSMapping->map(
1529-
VersionTuple(Major, Minor, Micro), NativeTargetVersion,
1530-
None)) {
1527+
OSVersion, NativeTargetVersion, None)) {
15311528
NativeTargetVersion = *MacOSVersion;
15321529
}
15331530
}
15341531
}
1535-
Result.Environment = DarwinEnvironmentKind::MacCatalyst;
1536-
Result.NativeTargetVersion = NativeTargetVersion;
15371532
break;
15381533
}
15391534
default:
15401535
break;
15411536
}
1537+
}
1538+
1539+
static DarwinPlatform
1540+
createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A,
1541+
const Optional<DarwinSDKInfo> &SDKInfo) {
1542+
DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
1543+
A);
1544+
unsigned Major, Minor, Micro;
1545+
TT.getOSVersion(Major, Minor, Micro);
1546+
if (Major == 0)
1547+
Result.HasOSVersion = false;
1548+
Result.setEnvironment(TT.getEnvironment(),
1549+
VersionTuple(Major, Minor, Micro), SDKInfo);
1550+
return Result;
1551+
}
1552+
static DarwinPlatform
1553+
createFromMTargetOS(llvm::Triple::OSType OS, VersionTuple OSVersion,
1554+
llvm::Triple::EnvironmentType Environment, Arg *A,
1555+
const Optional<DarwinSDKInfo> &SDKInfo) {
1556+
DarwinPlatform Result(MTargetOSArg, getPlatformFromOS(OS),
1557+
OSVersion.getAsString(), A);
1558+
Result.InferSimulatorFromArch = false;
1559+
Result.setEnvironment(Environment, OSVersion, SDKInfo);
15421560
return Result;
15431561
}
15441562
static DarwinPlatform createOSVersionArg(DarwinPlatformKind Platform,
@@ -1852,6 +1870,39 @@ Optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
18521870
Triple, OSVersion, Args.getLastArg(options::OPT_target), SDKInfo);
18531871
}
18541872

1873+
/// Returns the deployment target that's specified using the -mtargetos option.
1874+
Optional<DarwinPlatform>
1875+
getDeploymentTargetFromMTargetOSArg(DerivedArgList &Args,
1876+
const Driver &TheDriver,
1877+
const Optional<DarwinSDKInfo> &SDKInfo) {
1878+
auto *A = Args.getLastArg(options::OPT_mtargetos_EQ);
1879+
if (!A)
1880+
return None;
1881+
llvm::Triple TT(llvm::Twine("unknown-apple-") + A->getValue());
1882+
switch (TT.getOS()) {
1883+
case llvm::Triple::MacOSX:
1884+
case llvm::Triple::IOS:
1885+
case llvm::Triple::TvOS:
1886+
case llvm::Triple::WatchOS:
1887+
break;
1888+
default:
1889+
TheDriver.Diag(diag::err_drv_invalid_os_in_arg)
1890+
<< TT.getOSName() << A->getAsString(Args);
1891+
return None;
1892+
}
1893+
1894+
unsigned Major, Minor, Micro;
1895+
TT.getOSVersion(Major, Minor, Micro);
1896+
if (!Major) {
1897+
TheDriver.Diag(diag::err_drv_invalid_version_number)
1898+
<< A->getAsString(Args);
1899+
return None;
1900+
}
1901+
return DarwinPlatform::createFromMTargetOS(TT.getOS(),
1902+
VersionTuple(Major, Minor, Micro),
1903+
TT.getEnvironment(), A, SDKInfo);
1904+
}
1905+
18551906
Optional<DarwinSDKInfo> parseSDKSettings(llvm::vfs::FileSystem &VFS,
18561907
const ArgList &Args,
18571908
const Driver &TheDriver) {
@@ -1900,6 +1951,13 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
19001951
Optional<DarwinPlatform> OSTarget =
19011952
getDeploymentTargetFromTargetArg(Args, getTriple(), getDriver(), SDKInfo);
19021953
if (OSTarget) {
1954+
// Disallow mixing -target and -mtargetos=.
1955+
if (const auto *MTargetOSArg = Args.getLastArg(options::OPT_mtargetos_EQ)) {
1956+
std::string TargetArgStr = OSTarget->getAsString(Args, Opts);
1957+
std::string MTargetOSArgStr = MTargetOSArg->getAsString(Args);
1958+
getDriver().Diag(diag::err_drv_cannot_mix_options)
1959+
<< TargetArgStr << MTargetOSArgStr;
1960+
}
19031961
Optional<DarwinPlatform> OSVersionArgTarget =
19041962
getDeploymentTargetFromOSVersionArg(Args, getDriver());
19051963
if (OSVersionArgTarget) {
@@ -1931,6 +1989,18 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
19311989
}
19321990
}
19331991
}
1992+
} else if ((OSTarget = getDeploymentTargetFromMTargetOSArg(Args, getDriver(),
1993+
SDKInfo))) {
1994+
// The OS target can be specified using the -mtargetos= argument.
1995+
// Disallow mixing -mtargetos= and -m<os>version-min=.
1996+
Optional<DarwinPlatform> OSVersionArgTarget =
1997+
getDeploymentTargetFromOSVersionArg(Args, getDriver());
1998+
if (OSVersionArgTarget) {
1999+
std::string MTargetOSArgStr = OSTarget->getAsString(Args, Opts);
2000+
std::string OSVersionArgStr = OSVersionArgTarget->getAsString(Args, Opts);
2001+
getDriver().Diag(diag::err_drv_cannot_mix_options)
2002+
<< MTargetOSArgStr << OSVersionArgStr;
2003+
}
19342004
} else {
19352005
// The OS target can be specified using the -m<os>version-min argument.
19362006
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)