forked from OSchip/llvm-project
[lld/mac] Implement -umbrella
I think this is an old way for doing what is done with -reexport_library these days, but it's e.g. still used in libunwind's build (the opensource.apple.com one, not the llvm one). Differential Revision: https://reviews.llvm.org/D105448
This commit is contained in:
parent
718c32175b
commit
db64306d99
|
@ -126,6 +126,7 @@ struct Configuration {
|
|||
llvm::StringRef outputFile;
|
||||
llvm::StringRef ltoObjPath;
|
||||
llvm::StringRef thinLTOJobs;
|
||||
llvm::StringRef umbrella;
|
||||
uint32_t ltoo = 2;
|
||||
bool deadStripDylibs = false;
|
||||
bool demangle = false;
|
||||
|
|
|
@ -1121,6 +1121,11 @@ bool macho::link(ArrayRef<const char *> argsArr, bool canExitEarly,
|
|||
addFile(arg->getValue(), /*forceLoadArchive=*/false, /*isExplicit=*/false,
|
||||
/*isBundleLoader=*/true);
|
||||
}
|
||||
if (const Arg *arg = args.getLastArg(OPT_umbrella)) {
|
||||
if (config->outputType != MH_DYLIB)
|
||||
warn("-umbrella used, but not creating dylib");
|
||||
config->umbrella = arg->getValue();
|
||||
}
|
||||
config->ltoObjPath = args.getLastArgValue(OPT_object_path_lto);
|
||||
config->ltoNewPassManager =
|
||||
args.hasFlag(OPT_no_lto_legacy_pass_manager, OPT_lto_legacy_pass_manager,
|
||||
|
|
|
@ -780,9 +780,8 @@ def client_name : Separate<["-"], "client_name">,
|
|||
Flags<[HelpHidden]>,
|
||||
Group<grp_rare>;
|
||||
def umbrella : Separate<["-"], "umbrella">,
|
||||
MetaVarName<"<<name>>">,
|
||||
HelpText<"Re-export this dylib through the umbrella framework <name>a">,
|
||||
Flags<[HelpHidden]>,
|
||||
MetaVarName<"<name>">,
|
||||
HelpText<"Re-export this dylib through the umbrella framework <name>">,
|
||||
Group<grp_rare>;
|
||||
def headerpad : Separate<["-"], "headerpad">,
|
||||
MetaVarName<"<size>">,
|
||||
|
|
|
@ -128,6 +128,31 @@ public:
|
|||
ExportSection *exportSection;
|
||||
};
|
||||
|
||||
class LCSubFramework final : public LoadCommand {
|
||||
public:
|
||||
LCSubFramework(StringRef umbrella) : umbrella(umbrella) {}
|
||||
|
||||
uint32_t getSize() const override {
|
||||
return alignTo(sizeof(sub_framework_command) + umbrella.size() + 1,
|
||||
target->wordSize);
|
||||
}
|
||||
|
||||
void writeTo(uint8_t *buf) const override {
|
||||
auto *c = reinterpret_cast<sub_framework_command *>(buf);
|
||||
buf += sizeof(sub_framework_command);
|
||||
|
||||
c->cmd = LC_SUB_FRAMEWORK;
|
||||
c->cmdsize = getSize();
|
||||
c->umbrella = sizeof(sub_framework_command);
|
||||
|
||||
memcpy(buf, umbrella.data(), umbrella.size());
|
||||
buf[umbrella.size()] = '\0';
|
||||
}
|
||||
|
||||
private:
|
||||
const StringRef umbrella;
|
||||
};
|
||||
|
||||
class LCFunctionStarts final : public LoadCommand {
|
||||
public:
|
||||
explicit LCFunctionStarts(FunctionStartsSection *functionStartsSection)
|
||||
|
@ -665,6 +690,8 @@ template <class LP> void Writer::createLoadCommands() {
|
|||
in.header->addLoadCommand(make<LCSymtab>(symtabSection, stringTableSection));
|
||||
in.header->addLoadCommand(
|
||||
make<LCDysymtab>(symtabSection, indirectSymtabSection));
|
||||
if (!config->umbrella.empty())
|
||||
in.header->addLoadCommand(make<LCSubFramework>(config->umbrella));
|
||||
if (functionStartsSection)
|
||||
in.header->addLoadCommand(make<LCFunctionStarts>(functionStartsSection));
|
||||
if (dataInCodeSection)
|
||||
|
|
|
@ -0,0 +1,18 @@
|
|||
# REQUIRES: x86
|
||||
|
||||
# RUN: llvm-mc -filetype=obj -triple=x86_64-apple-macos -o %t.o %s
|
||||
# RUN: %lld -dylib -o %t.dylib -umbrella umbrella.dylib %t.o
|
||||
# RUN: llvm-otool -lv %t.dylib | FileCheck %s
|
||||
|
||||
# RUN: %no_fatal_warnings_lld -bundle -o %t.so -umbrella umbrella.dylib %t.o \
|
||||
# RUN: 2>&1 | FileCheck --check-prefix=WARN %s
|
||||
# WARN: warning: -umbrella used, but not creating dylib
|
||||
# RUN: llvm-otool -lv %t.so | FileCheck %s
|
||||
|
||||
# CHECK: cmd LC_SUB_FRAMEWORK
|
||||
# CHECK-NEXT: cmdsize 32
|
||||
# CHECK-NEXT: umbrella umbrella.dylib (offset 12)
|
||||
|
||||
.globl __Z3foo
|
||||
__Z3foo:
|
||||
ret
|
Loading…
Reference in New Issue