[clang][driver] add clang driver support for emitting macho files with two build version load commands

This patch extends clang driver to pass the right flags to the clang frontend, and ld64,
so that they can emit macho files with two build version load commands. It adds a new
0darwin-target-variant option which complements -target and also can be used to specify different
target variants when multi-arch compilations are invoked with multiple -arch commands.

Differential Revision: https://reviews.llvm.org/D118862
This commit is contained in:
Alex Lorenz 2022-02-14 12:24:43 -08:00
parent e98f6fa1c7
commit d238acd113
9 changed files with 280 additions and 45 deletions

View File

@ -637,4 +637,8 @@ def err_drv_cuda_offload_only_emit_bc : Error<
def warn_drv_jmc_requires_debuginfo : Warning<
"/JMC requires debug info. Use '/Zi', '/Z7' or other debug options; option ignored">,
InGroup<OptionIgnored>;
def err_drv_target_variant_invalid : Error<
"unsupported '%0' value '%1'; use 'ios-macabi' instead">;
}

View File

@ -3994,6 +3994,9 @@ def : Separate<["--"], "no-system-header-prefix">, Alias<no_system_header_prefix
def s : Flag<["-"], "s">, Group<Link_Group>;
def target : Joined<["--"], "target=">, Flags<[NoXarchOption, CoreOption]>,
HelpText<"Generate code for the given target">;
def darwin_target_variant : Separate<["-"], "darwin-target-variant">,
Flags<[NoXarchOption, CoreOption]>,
HelpText<"Generate code for an additional runtime variant of the deployment target">;
def print_supported_cpus : Flag<["-", "--"], "print-supported-cpus">,
Group<CompileOnly_Group>, Flags<[CC1Option, CoreOption]>,
HelpText<"Print supported cpu models for the given target (if target is not specified,"

View File

@ -1496,6 +1496,10 @@ struct DarwinPlatform {
/// Returns true if the simulator environment can be inferred from the arch.
bool canInferSimulatorFromArch() const { return InferSimulatorFromArch; }
const Optional<llvm::Triple> &getTargetVariantTriple() const {
return TargetVariantTriple;
}
/// Adds the -m<os>-version-min argument to the compiler invocation.
void addOSVersionMinArgument(DerivedArgList &Args, const OptTable &Opts) {
if (Argument)
@ -1558,6 +1562,16 @@ struct DarwinPlatform {
}
}
}
// In a zippered build, we could be building for a macOS target that's
// lower than the version that's implied by the OS version. In that case
// we need to use the minimum version as the native target version.
if (TargetVariantTriple) {
auto TargetVariantVersion = TargetVariantTriple->getOSVersion();
if (TargetVariantVersion.getMajor()) {
if (TargetVariantVersion < NativeTargetVersion)
NativeTargetVersion = TargetVariantVersion;
}
}
break;
}
default:
@ -1567,12 +1581,14 @@ struct DarwinPlatform {
static DarwinPlatform
createFromTarget(const llvm::Triple &TT, StringRef OSVersion, Arg *A,
Optional<llvm::Triple> TargetVariantTriple,
const Optional<DarwinSDKInfo> &SDKInfo) {
DarwinPlatform Result(TargetArg, getPlatformFromOS(TT.getOS()), OSVersion,
A);
VersionTuple OsVersion = TT.getOSVersion();
if (OsVersion.getMajor() == 0)
Result.HasOSVersion = false;
Result.TargetVariantTriple = TargetVariantTriple;
Result.setEnvironment(TT.getEnvironment(), OsVersion, SDKInfo);
return Result;
}
@ -1656,6 +1672,7 @@ private:
bool HasOSVersion = true, InferSimulatorFromArch = true;
Arg *Argument;
StringRef EnvVarName;
Optional<llvm::Triple> TargetVariantTriple;
};
/// Returns the deployment target that's specified using the -m<os>-version-min
@ -1881,7 +1898,6 @@ inferDeploymentTargetFromArch(DerivedArgList &Args, const Darwin &Toolchain,
else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
MachOArchName != "armv7em")
OSTy = llvm::Triple::MacOSX;
if (OSTy == llvm::Triple::UnknownOS)
return None;
return DarwinPlatform::createFromArch(OSTy,
@ -1898,8 +1914,34 @@ Optional<DarwinPlatform> getDeploymentTargetFromTargetArg(
Triple.getOS() == llvm::Triple::UnknownOS)
return None;
std::string OSVersion = getOSVersion(Triple.getOS(), Triple, TheDriver);
return DarwinPlatform::createFromTarget(
Triple, OSVersion, Args.getLastArg(options::OPT_target), SDKInfo);
Optional<llvm::Triple> TargetVariantTriple;
for (const Arg *A : Args.filtered(options::OPT_darwin_target_variant)) {
llvm::Triple TVT(A->getValue());
// Find a matching <arch>-<vendor> target variant triple that can be used.
if ((Triple.getArch() == llvm::Triple::aarch64 ||
TVT.getArchName() == Triple.getArchName()) &&
TVT.getArch() == Triple.getArch() &&
TVT.getSubArch() == Triple.getSubArch() &&
TVT.getVendor() == Triple.getVendor()) {
if (TargetVariantTriple)
continue;
A->claim();
// Accept a -target-variant triple when compiling code that may run on
// macOS or Mac Catalust.
if ((Triple.isMacOSX() && TVT.getOS() == llvm::Triple::IOS &&
TVT.isMacCatalystEnvironment()) ||
(TVT.isMacOSX() && Triple.getOS() == llvm::Triple::IOS &&
Triple.isMacCatalystEnvironment())) {
TargetVariantTriple = TVT;
continue;
}
TheDriver.Diag(diag::err_drv_target_variant_invalid)
<< A->getSpelling() << A->getValue();
}
}
return DarwinPlatform::createFromTarget(Triple, OSVersion,
Args.getLastArg(options::OPT_target),
TargetVariantTriple, SDKInfo);
}
/// Returns the deployment target that's specified using the -mtargetos option.
@ -2134,6 +2176,7 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
if (Environment == MacCatalyst)
NativeTargetVersion = OSTarget->getNativeTargetVersion();
setTarget(Platform, Environment, Major, Minor, Micro, NativeTargetVersion);
TargetVariantTriple = OSTarget->getTargetVariantTriple();
if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) {
StringRef SDK = getSDKName(A->getValue());
@ -2653,6 +2696,12 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
isAlignedAllocationUnavailable())
CC1Args.push_back("-faligned-alloc-unavailable");
if (TargetVariantTriple) {
CC1Args.push_back("-darwin-target-variant-triple");
CC1Args.push_back(
DriverArgs.MakeArgString(TargetVariantTriple->getTriple()));
}
if (SDKInfo) {
/// Pass the SDK version to the compiler when the SDK information is
/// available.
@ -2674,6 +2723,28 @@ void Darwin::addClangTargetOptions(const llvm::opt::ArgList &DriverArgs,
} else {
EmitTargetSDKVersionArg(SDKInfo->getVersion());
}
/// Pass the target variant SDK version to the compiler when the SDK
/// information is available and is required for target variant.
if (TargetVariantTriple) {
if (isTargetMacCatalyst()) {
std::string Arg;
llvm::raw_string_ostream OS(Arg);
OS << "-darwin-target-variant-sdk-version=" << SDKInfo->getVersion();
CC1Args.push_back(DriverArgs.MakeArgString(OS.str()));
} else if (const auto *MacOStoMacCatalystMapping =
SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
if (Optional<VersionTuple> SDKVersion = MacOStoMacCatalystMapping->map(
SDKInfo->getVersion(), minimumMacCatalystDeploymentTarget(),
None)) {
std::string Arg;
llvm::raw_string_ostream OS(Arg);
OS << "-darwin-target-variant-sdk-version=" << *SDKVersion;
CC1Args.push_back(DriverArgs.MakeArgString(OS.str()));
}
}
}
}
// Enable compatibility mode for NSItemProviderCompletionHandler in
@ -2834,6 +2905,25 @@ void Darwin::addMinVersionArgs(const ArgList &Args,
if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
TargetVersion = MinTgtVers;
CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
if (TargetVariantTriple) {
assert(isTargetMacOSBased() && "unexpected target");
VersionTuple VariantTargetVersion;
if (TargetVariantTriple->isMacOSX()) {
CmdArgs.push_back("-macosx_version_min");
TargetVariantTriple->getMacOSXVersion(VariantTargetVersion);
} else {
assert(TargetVariantTriple->isiOS() &&
TargetVariantTriple->isMacCatalystEnvironment() &&
"unexpected target variant triple");
CmdArgs.push_back("-maccatalyst_version_min");
VariantTargetVersion = TargetVariantTriple->getiOSVersion();
}
VersionTuple MinTgtVers =
TargetVariantTriple->getMinimumSupportedOSVersion();
if (MinTgtVers.getMajor() && MinTgtVers > VariantTargetVersion)
VariantTargetVersion = MinTgtVers;
CmdArgs.push_back(Args.MakeArgString(VariantTargetVersion.getAsString()));
}
}
static const char *getPlatformName(Darwin::DarwinPlatformKind Platform,
@ -2855,52 +2945,88 @@ static const char *getPlatformName(Darwin::DarwinPlatformKind Platform,
void Darwin::addPlatformVersionArgs(const llvm::opt::ArgList &Args,
llvm::opt::ArgStringList &CmdArgs) const {
// -platform_version <platform> <target_version> <sdk_version>
// Both the target and SDK version support only up to 3 components.
CmdArgs.push_back("-platform_version");
std::string PlatformName = getPlatformName(TargetPlatform, TargetEnvironment);
if (TargetEnvironment == Darwin::Simulator)
PlatformName += "-simulator";
CmdArgs.push_back(Args.MakeArgString(PlatformName));
VersionTuple TargetVersion = getTripleTargetVersion().withoutBuild();
VersionTuple MinTgtVers = getEffectiveTriple().getMinimumSupportedOSVersion();
if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
TargetVersion = MinTgtVers;
CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
auto EmitPlatformVersionArg =
[&](const VersionTuple &TV, Darwin::DarwinPlatformKind TargetPlatform,
Darwin::DarwinEnvironmentKind TargetEnvironment,
const llvm::Triple &TT) {
// -platform_version <platform> <target_version> <sdk_version>
// Both the target and SDK version support only up to 3 components.
CmdArgs.push_back("-platform_version");
std::string PlatformName =
getPlatformName(TargetPlatform, TargetEnvironment);
if (TargetEnvironment == Darwin::Simulator)
PlatformName += "-simulator";
CmdArgs.push_back(Args.MakeArgString(PlatformName));
VersionTuple TargetVersion = TV.withoutBuild();
if ((TargetPlatform == Darwin::IPhoneOS ||
TargetPlatform == Darwin::TvOS) &&
getTriple().getArchName() == "arm64e" &&
TargetVersion.getMajor() < 14) {
// arm64e slice is supported on iOS/tvOS 14+ only.
TargetVersion = VersionTuple(14, 0);
}
VersionTuple MinTgtVers = TT.getMinimumSupportedOSVersion();
if (!MinTgtVers.empty() && MinTgtVers > TargetVersion)
TargetVersion = MinTgtVers;
CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
if (isTargetMacCatalyst()) {
// Mac Catalyst programs must use the appropriate iOS SDK version
// that corresponds to the macOS SDK version used for the compilation.
Optional<VersionTuple> iOSSDKVersion;
if (SDKInfo) {
if (const auto *MacOStoMacCatalystMapping = SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
iOSSDKVersion = MacOStoMacCatalystMapping->map(
SDKInfo->getVersion().withoutBuild(),
minimumMacCatalystDeploymentTarget(), None);
}
}
CmdArgs.push_back(Args.MakeArgString(
(iOSSDKVersion ? *iOSSDKVersion : minimumMacCatalystDeploymentTarget())
.getAsString()));
if (TargetPlatform == IPhoneOS && TargetEnvironment == MacCatalyst) {
// Mac Catalyst programs must use the appropriate iOS SDK version
// that corresponds to the macOS SDK version used for the compilation.
Optional<VersionTuple> iOSSDKVersion;
if (SDKInfo) {
if (const auto *MacOStoMacCatalystMapping =
SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair::macOStoMacCatalystPair())) {
iOSSDKVersion = MacOStoMacCatalystMapping->map(
SDKInfo->getVersion().withoutBuild(),
minimumMacCatalystDeploymentTarget(), None);
}
}
CmdArgs.push_back(Args.MakeArgString(
(iOSSDKVersion ? *iOSSDKVersion
: minimumMacCatalystDeploymentTarget())
.getAsString()));
return;
}
if (SDKInfo) {
VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild();
CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString()));
} else {
// Use an SDK version that's matching the deployment target if the SDK
// version is missing. This is preferred over an empty SDK version
// (0.0.0) as the system's runtime might expect the linked binary to
// contain a valid SDK version in order for the binary to work
// correctly. It's reasonable to use the deployment target version as
// a proxy for the SDK version because older SDKs don't guarantee
// support for deployment targets newer than the SDK versions, so that
// rules out using some predetermined older SDK version, which leaves
// the deployment target version as the only reasonable choice.
CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
}
};
EmitPlatformVersionArg(getTripleTargetVersion(), TargetPlatform,
TargetEnvironment, getEffectiveTriple());
if (!TargetVariantTriple)
return;
}
if (SDKInfo) {
VersionTuple SDKVersion = SDKInfo->getVersion().withoutBuild();
CmdArgs.push_back(Args.MakeArgString(SDKVersion.getAsString()));
Darwin::DarwinPlatformKind Platform;
Darwin::DarwinEnvironmentKind Environment;
VersionTuple TargetVariantVersion;
if (TargetVariantTriple->isMacOSX()) {
TargetVariantTriple->getMacOSXVersion(TargetVariantVersion);
Platform = Darwin::MacOS;
Environment = Darwin::NativeEnvironment;
} else {
// Use an SDK version that's matching the deployment target if the SDK
// version is missing. This is preferred over an empty SDK version (0.0.0)
// as the system's runtime might expect the linked binary to contain a
// valid SDK version in order for the binary to work correctly. It's
// reasonable to use the deployment target version as a proxy for the
// SDK version because older SDKs don't guarantee support for deployment
// targets newer than the SDK versions, so that rules out using some
// predetermined older SDK version, which leaves the deployment target
// version as the only reasonable choice.
CmdArgs.push_back(Args.MakeArgString(TargetVersion.getAsString()));
assert(TargetVariantTriple->isiOS() &&
TargetVariantTriple->isMacCatalystEnvironment() &&
"unexpected target variant triple");
TargetVariantVersion = TargetVariantTriple->getiOSVersion();
Platform = Darwin::IPhoneOS;
Environment = Darwin::MacCatalyst;
}
EmitPlatformVersionArg(TargetVariantVersion, Platform, Environment,
*TargetVariantTriple);
}
// Add additional link args for the -dynamiclib option.

View File

@ -317,6 +317,9 @@ public:
/// The information about the darwin SDK that was used.
mutable Optional<DarwinSDKInfo> SDKInfo;
/// The target variant triple that was specified (if any).
mutable Optional<llvm::Triple> TargetVariantTriple;
CudaInstallationDetector CudaInstallation;
RocmInstallationDetector RocmInstallation;

View File

@ -0,0 +1,30 @@
// RUN: touch %t.o
// RUN: %clang -target x86_64-apple-ios13.1-macabi -darwin-target-variant x86_64-apple-macos10.15 -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -mlinker-version=520 -### %t.o 2>&1 \
// RUN: | FileCheck %s
// RUN: %clang -target x86_64-apple-macos10.14.3 -darwin-target-variant x86_64-apple-ios13.1-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -mlinker-version=520 -### %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-INV %s
// RUN: %clang -target arm64-apple-ios13.1-macabi -darwin-target-variant arm64-apple-macos10.15 -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -mlinker-version=520 -### %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=ARM64_NEW %s
// RUN: %clang -target arm64-apple-macos10.15 -darwin-target-variant arm64-apple-ios13.1-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -mlinker-version=520 -### %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=ARM64_NEW-INV %s
// RUN: %clang -target arm64-apple-ios13.1-macabi -darwin-target-variant arm64-apple-macos10.15 -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -mlinker-version=400 -### %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=ARM64_OLD %s
// RUN: %clang -target arm64-apple-macos10.15 -darwin-target-variant arm64-apple-ios13.1-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -mlinker-version=400 -### %t.o 2>&1 \
// RUN: | FileCheck --check-prefix=ARM64_OLD-INV %s
// CHECK: "-platform_version" "mac catalyst" "13.1.0" "13.1"
// CHECK-SAME: "-platform_version" "macos" "10.15" "10.15"
// CHECK-INV: "-platform_version" "macos" "10.14.3" "10.15"
// CHECK-INV-SAME: "-platform_version" "mac catalyst" "13.1" "13.1"
// ARM64_NEW: "-platform_version" "mac catalyst" "14.0.0" "13.1"
// ARM64_NEW-SAME: "-platform_version" "macos" "11.0.0" "10.15"
// ARM64_NEW-INV: "-platform_version" "macos" "11.0.0" "10.15"
// ARM64_NEW-INV-SAME: "-platform_version" "mac catalyst" "14.0.0" "13.1"
// ARM64_OLD: "-maccatalyst_version_min" "14.0.0" "-macosx_version_min" "11.0.0"
// ARM64_OLD-INV: "-macosx_version_min" "11.0.0" "-maccatalyst_version_min" "14.0.0"

View File

@ -0,0 +1,9 @@
// RUN: %clang -target x86_64-apple-ios13.2-macabi -darwin-target-variant x86_64-apple-macos10.15.3-macos -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c %s -### 2>&1 \
// RUN: | FileCheck %s
// RUN: %clang -target x86_64-apple-macos10.15.1 -darwin-target-variant x86_64-apple-ios13.2-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c %s -### 2>&1 \
// RUN: | FileCheck %s
// RUN: %clang -target x86_64-apple-ios13.2-macabi -darwin-target-variant x86_64-apple-macos10.15-macos -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c %s -### 2>&1 \
// RUN: | FileCheck --check-prefix=LOWER %s
// CHECK: -fobjc-runtime=macosx-10.15.1
// LOWER: -fobjc-runtime=macosx-10.15

View File

@ -0,0 +1,12 @@
// RUN: %clang -target x86_64-apple-macosx10.15 -darwin-target-variant x86_64-apple-ios13.1-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c -### %s 2>&1 \
// RUN: | FileCheck %s
// RUN: env SDKROOT=%S/Inputs/MacOSX10.15.versioned.sdk %clang -target x86_64-apple-macosx10.15 -darwin-target-variant x86_64-apple-ios13.1-macabi -c -### %s 2>&1 \
// RUN: | FileCheck %s
// RUN: %clang -target x86_64-apple-ios13.1-macabi -darwin-target-variant x86_64-apple-macosx10.15 -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c -### %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-SWAPPED %s
// RUN: %clang -target x86_64-apple-ios13.1-macabi -isysroot %S/Inputs/MacOSX10.15.versioned.sdk -c -### %s 2>&1 \
// RUN: | FileCheck --check-prefix=CHECK-MACCATALYST %s
// CHECK: "-target-sdk-version=10.15" "-darwin-target-variant-sdk-version=13.1"
// CHECK-SWAPPED: "-target-sdk-version=13.1" "-darwin-target-variant-sdk-version=10.15"
// CHECK-MACCATALYST: "-target-sdk-version=13.1"

View File

@ -0,0 +1,32 @@
// RUN: %clang -target unknown-apple-macos10.15 -arch x86_64 -arch x86_64h -arch i386 \
// RUN: -darwin-target-variant x86_64-apple-ios13.1-macabi -darwin-target-variant x86_64h-apple-ios13.1-macabi \
// RUN: -c %s -### 2>&1 | FileCheck %s
// RUN: %clang -target x86_64-apple-macos10.15 -darwin-target-variant i386-apple-ios13.1-macabi \
// RUN: -c %s -### 2>&1 | FileCheck --check-prefix=UNUSED-TV %s
// RUN: %clang -target x86_64-apple-macos10.15 -darwin-target-variant x86_64-apple-ios13.1-macabi \
// RUN: -darwin-target-variant x86_64-apple-ios13.1-macabi -c %s -### 2>&1 | FileCheck --check-prefix=REDUNDANT-TV %s
// RUN: %clang -target x86_64-apple-macos10.15 -darwin-target-variant x86_64-apple-ios13.1 \
// RUN: -c %s -### 2>&1 | FileCheck --check-prefix=INCORRECT-TV %s
// RUN: %clang -target unknown-apple-ios13.1-macabi -arch x86_64 -arch x86_64h \
// RUN: -darwin-target-variant x86_64-apple-macos10.15 \
// RUN: -c %s -### 2>&1 | FileCheck --check-prefix=INVERTED %s
// CHECK: "-triple" "x86_64-apple-macosx10.15.0"
// CHECK-SAME: "-darwin-target-variant-triple" "x86_64-apple-ios13.1-macabi"
// CHECK: "-triple" "x86_64h-apple-macosx10.15.0"
// CHECK-SAME: "-darwin-target-variant-triple" "x86_64h-apple-ios13.1-macabi"
// CHECK: "-triple" "i386-apple-macosx10.15.0"
// CHECK-NOT: target-variant-triple
// INVERTED: "-triple" "x86_64-apple-ios13.1.0-macabi"
// INVERTED-SAME: "-darwin-target-variant-triple" "x86_64-apple-macos10.15"
// INVERTED: "-triple" "x86_64h-apple-ios13.1.0-macabi"
// INVERTED-NOT: target-variant-triple
// UNUSED-TV: argument unused during compilation: '-darwin-target-variant i386-apple-ios13.1-macabi'
// REDUNDANT-TV: argument unused during compilation: '-darwin-target-variant x86_64-apple-ios13.1-macabi'
// INCORRECT-TV: unsupported '-darwin-target-variant' value 'x86_64-apple-ios13.1'; use 'ios-macabi' instead

View File

@ -0,0 +1,16 @@
// RUN: %clang -target unknown-apple-macos10.15 -arch x86_64 -arch x86_64h -arch i386 \
// RUN: -darwin-target-variant x86_64-apple-ios13.1-macabi -darwin-target-variant x86_64h-apple-ios13.1-macabi \
// RUN: %s -mlinker-version=400 -### 2>&1 | FileCheck %s
// RUN: %clang -target unknown-apple-ios13.1-macabi -arch x86_64 -arch x86_64h \
// RUN: -darwin-target-variant x86_64-apple-macos10.15 \
// RUN: %s -mlinker-version=400 -### 2>&1 | FileCheck --check-prefix=INVERTED %s
// CHECK: "-arch" "x86_64" "-macosx_version_min" "10.15.0" "-maccatalyst_version_min" "13.1"
// CHECK: "-arch" "x86_64h" "-macosx_version_min" "10.15.0" "-maccatalyst_version_min" "13.1"
// CHECK: "-arch" "i386" "-macosx_version_min" "10.15.0"
// CHECK-NOT: maccatalyst_version_min
// INVERTED: "-arch" "x86_64" "-maccatalyst_version_min" "13.1.0" "-macosx_version_min" "10.15"
// INVERTED: "-arch" "x86_64h" "-maccatalyst_version_min" "13.1.0"
// INVERTED-NOT: macosx_version_min