Skip to content

Commit

Permalink
[clang][macho] add clang frontend support for emitting macho files wi…
Browse files Browse the repository at this point in the history
…th two build version load commands

This patch extends clang frontend to add metadata that can be used to emit macho files with two build version load commands.
It utilizes "darwin.target_variant.triple" and "darwin.target_variant.SDK Version" metadata names for that.

MachO uses two build version load commands to represent an object file / binary that is targeting both the macOS target,
and the Mac Catalyst target. At runtime, a dynamic library that supports both targets can be loaded from either a native
macOS or a Mac Catalyst app on a macOS system. We want to add support to this to upstream to LLVM to be able to build
compiler-rt for both targets, to finish the complete support for the Mac Catalyst platform, which is right now targetable
by upstream clang, but the compiler-rt bits aren't supported because of the lack of this multiple build version support.

Differential Revision: https://reviews.llvm.org/D115415
  • Loading branch information
hyp committed Feb 2, 2022
1 parent 6440197 commit 116c1be
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 3 deletions.
17 changes: 17 additions & 0 deletions clang/include/clang/Basic/TargetInfo.h
Expand Up @@ -235,6 +235,8 @@ class TargetInfo : public virtual TransferrableTargetInfo,

unsigned MaxOpenCLWorkGroupSize;

Optional<llvm::Triple> DarwinTargetVariantTriple;

// TargetInfo Constructor. Default initializes all fields.
TargetInfo(const llvm::Triple &T);

Expand Down Expand Up @@ -1608,6 +1610,21 @@ class TargetInfo : public virtual TransferrableTargetInfo,
/// Whether target allows debuginfo types for decl only variables/functions.
virtual bool allowDebugInfoForExternalRef() const { return false; }

/// Returns the darwin target variant triple, the variant of the deployment
/// target for which the code is being compiled.
const llvm::Triple *getDarwinTargetVariantTriple() const {
return DarwinTargetVariantTriple ? DarwinTargetVariantTriple.getPointer()
: nullptr;
}

/// Returns the version of the darwin target variant SDK which was used during
/// the compilation if one was specified, or an empty version otherwise.
const Optional<VersionTuple> getDarwinTargetVariantSDKVersion() const {
return !getTargetOpts().DarwinTargetVariantSDKVersion.empty()
? getTargetOpts().DarwinTargetVariantSDKVersion
: Optional<VersionTuple>();
}

protected:
/// Copy type and layout related info.
void copyAuxTarget(const TargetInfo *Aux);
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Basic/TargetOptions.h
Expand Up @@ -91,6 +91,13 @@ class TargetOptions {
/// * CUDA compilation uses it to control parts of CUDA compilation
/// in clang that depend on specific version of the CUDA SDK.
llvm::VersionTuple SDKVersion;

/// The name of the darwin target- ariant triple to compile for.
std::string DarwinTargetVariantTriple;

/// The version of the darwin target variant SDK which was used during the
/// compilation.
llvm::VersionTuple DarwinTargetVariantSDKVersion;
};

} // end namespace clang
Expand Down
7 changes: 7 additions & 0 deletions clang/include/clang/Driver/Options.td
Expand Up @@ -4777,6 +4777,13 @@ def target_abi : Separate<["-"], "target-abi">,
MarshallingInfoString<TargetOpts<"ABI">>;
def target_sdk_version_EQ : Joined<["-"], "target-sdk-version=">,
HelpText<"The version of target SDK used for compilation">;
def darwin_target_variant_triple : Separate<["-"], "darwin-target-variant-triple">,
HelpText<"Specify the darwin target variant triple">,
MarshallingInfoString<TargetOpts<"DarwinTargetVariantTriple">>,
Normalizer<"normalizeTriple">;
def darwin_target_variant_sdk_version_EQ : Joined<["-"],
"darwin-target-variant-sdk-version=">,
HelpText<"The version of darwin target variant SDK used for compilation">;

}

Expand Down
4 changes: 4 additions & 0 deletions clang/lib/Basic/Targets.cpp
Expand Up @@ -731,6 +731,10 @@ TargetInfo::CreateTargetInfo(DiagnosticsEngine &Diags,
Target->setCommandLineOpenCLOpts();
Target->setMaxAtomicWidth();

if (!Opts->DarwinTargetVariantTriple.empty())
Target->DarwinTargetVariantTriple =
llvm::Triple(Opts->DarwinTargetVariantTriple);

if (!Target->validateTarget(Diags))
return nullptr;

Expand Down
5 changes: 5 additions & 0 deletions clang/lib/CodeGen/ModuleBuilder.cpp
Expand Up @@ -146,6 +146,11 @@ namespace {
const auto &SDKVersion = Ctx->getTargetInfo().getSDKVersion();
if (!SDKVersion.empty())
M->setSDKVersion(SDKVersion);
if (const auto *TVT = Ctx->getTargetInfo().getDarwinTargetVariantTriple())
M->setDarwinTargetVariantTriple(TVT->getTriple());
if (auto TVSDKVersion =
Ctx->getTargetInfo().getDarwinTargetVariantSDKVersion())
M->setDarwinTargetVariantSDKVersion(*TVSDKVersion);
Builder.reset(new CodeGen::CodeGenModule(Context, HeaderSearchOpts,
PreprocessorOpts, CodeGenOpts,
*M, Diags, CoverageInfo));
Expand Down
12 changes: 12 additions & 0 deletions clang/lib/Frontend/CompilerInvocation.cpp
Expand Up @@ -4404,6 +4404,9 @@ static void GenerateTargetArgs(const TargetOptions &Opts,
if (!Opts.SDKVersion.empty())
GenerateArg(Args, OPT_target_sdk_version_EQ, Opts.SDKVersion.getAsString(),
SA);
if (!Opts.DarwinTargetVariantSDKVersion.empty())
GenerateArg(Args, OPT_darwin_target_variant_sdk_version_EQ,
Opts.DarwinTargetVariantSDKVersion.getAsString(), SA);
}

static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
Expand Down Expand Up @@ -4431,6 +4434,15 @@ static bool ParseTargetArgs(TargetOptions &Opts, ArgList &Args,
else
Opts.SDKVersion = Version;
}
if (Arg *A =
Args.getLastArg(options::OPT_darwin_target_variant_sdk_version_EQ)) {
llvm::VersionTuple Version;
if (Version.tryParse(A->getValue()))
Diags.Report(diag::err_drv_invalid_value)
<< A->getAsString(Args) << A->getValue();
else
Opts.DarwinTargetVariantSDKVersion = Version;
}

return Diags.getNumErrors() == NumErrorsBefore;
}
Expand Down
6 changes: 6 additions & 0 deletions clang/test/CodeGen/darwin-target-variant.c
@@ -0,0 +1,6 @@
// RUN: %clang_cc1 -triple x86_64-apple-macos11 -darwin-target-variant-triple x86_64-apple-ios14-macabi -target-sdk-version=11.1 -darwin-target-variant-sdk-version=14.1 -emit-llvm -o - %s | FileCheck %s

// CHECK: !llvm.module.flags = !{!0, !1, !2
// CHECK: !0 = !{i32 2, !"SDK Version", [2 x i32] [i32 11, i32 1]}
// CHECK: !1 = !{i32 4, !"darwin.target_variant.triple", !"x86_64-apple-ios14-macabi"}
// CHECK: !2 = !{i32 2, !"darwin.target_variant.SDK Version", [2 x i32] [i32 14, i32 1]}
7 changes: 7 additions & 0 deletions llvm/include/llvm/IR/Module.h
Expand Up @@ -939,10 +939,17 @@ class LLVM_EXTERNAL_VISIBILITY Module {
/// @returns a string containing the target variant triple.
StringRef getDarwinTargetVariantTriple() const;

/// Set the target variant triple which is a string describing a variant of
/// the target host platform.
void setDarwinTargetVariantTriple(StringRef T);

/// Get the target variant version build SDK version metadata.
///
/// An empty version is returned if no such metadata is attached.
VersionTuple getDarwinTargetVariantSDKVersion() const;

/// Set the target variant version build SDK version metadata.
void setDarwinTargetVariantSDKVersion(VersionTuple Version);
};

/// Given "llvm.used" or "llvm.compiler.used" as a global name, collect the
Expand Down
19 changes: 16 additions & 3 deletions llvm/lib/IR/Module.cpp
Expand Up @@ -734,7 +734,7 @@ void Module::setOverrideStackAlignment(unsigned Align) {
addModuleFlag(ModFlagBehavior::Error, "override-stack-alignment", Align);
}

void Module::setSDKVersion(const VersionTuple &V) {
static void addSDKVersionMD(const VersionTuple &V, Module &M, StringRef Name) {
SmallVector<unsigned, 3> Entries;
Entries.push_back(V.getMajor());
if (auto Minor = V.getMinor()) {
Expand All @@ -744,8 +744,12 @@ void Module::setSDKVersion(const VersionTuple &V) {
// Ignore the 'build' component as it can't be represented in the object
// file.
}
addModuleFlag(ModFlagBehavior::Warning, "SDK Version",
ConstantDataArray::get(Context, Entries));
M.addModuleFlag(Module::ModFlagBehavior::Warning, Name,
ConstantDataArray::get(M.getContext(), Entries));
}

void Module::setSDKVersion(const VersionTuple &V) {
addSDKVersionMD(V, *this, "SDK Version");
}

static VersionTuple getSDKVersionMD(Metadata *MD) {
Expand Down Expand Up @@ -818,6 +822,15 @@ StringRef Module::getDarwinTargetVariantTriple() const {
return "";
}

void Module::setDarwinTargetVariantTriple(StringRef T) {
addModuleFlag(ModFlagBehavior::Override, "darwin.target_variant.triple",
MDString::get(getContext(), T));
}

VersionTuple Module::getDarwinTargetVariantSDKVersion() const {
return getSDKVersionMD(getModuleFlag("darwin.target_variant.SDK Version"));
}

void Module::setDarwinTargetVariantSDKVersion(VersionTuple Version) {
addSDKVersionMD(Version, *this, "darwin.target_variant.SDK Version");
}

0 comments on commit 116c1be

Please sign in to comment.