[lld/mac] Implement -reexport_framework, -reexport_library, -reexport-l

These are slightly easier-to-use versions of -sub_library and -sub_umbrella.

Differential Revision: https://reviews.llvm.org/D103497
This commit is contained in:
Nico Weber 2021-06-01 20:17:04 -04:00
parent 2368170a8d
commit 78ce89bb1e
3 changed files with 58 additions and 21 deletions

View File

@ -324,24 +324,34 @@ static InputFile *addFile(StringRef path, bool forceLoadArchive,
return newFile;
}
static void addLibrary(StringRef name, bool isWeak, bool isExplicit = true) {
static void addLibrary(StringRef name, bool isWeak, bool isReexport,
bool isExplicit) {
if (Optional<StringRef> path = findLibrary(name)) {
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(addFile(*path, false))) {
dylibFile->explicitlyLinked = isExplicit;
if (isWeak)
dylibFile->forceWeakImport = true;
if (isReexport) {
config->hasReexports = true;
dylibFile->reexport = true;
}
}
return;
}
error("library not found for -l" + name);
}
static void addFramework(StringRef name, bool isWeak, bool isExplicit = true) {
static void addFramework(StringRef name, bool isWeak, bool isReexport,
bool isExplicit) {
if (Optional<std::string> path = findFramework(name)) {
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(addFile(*path, false))) {
dylibFile->explicitlyLinked = isExplicit;
if (isWeak)
dylibFile->forceWeakImport = true;
if (isReexport) {
config->hasReexports = true;
dylibFile->reexport = true;
}
}
return;
}
@ -371,10 +381,12 @@ void macho::parseLCLinkerOption(InputFile *f, unsigned argc, StringRef data) {
for (const Arg *arg : args) {
switch (arg->getOption().getID()) {
case OPT_l:
addLibrary(arg->getValue(), /*isWeak=*/false, /*isExplicit=*/false);
addLibrary(arg->getValue(), /*isWeak=*/false, /*isReexport=*/false,
/*isExplicit=*/false);
break;
case OPT_framework:
addFramework(arg->getValue(), /*isWeak=*/false, /*isExplicit=*/false);
addFramework(arg->getValue(), /*isWeak=*/false, /*isReexport=*/false,
/*isExplicit=*/false);
break;
default:
error(arg->getSpelling() + " is not allowed in LC_LINKER_OPTION");
@ -866,6 +878,13 @@ void createFiles(const InputArgList &args) {
case OPT_INPUT:
addFile(rerootPath(arg->getValue()), false);
break;
case OPT_reexport_library:
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
addFile(rerootPath(arg->getValue()), false))) {
config->hasReexports = true;
dylibFile->reexport = true;
}
break;
case OPT_weak_library:
if (auto *dylibFile = dyn_cast_or_null<DylibFile>(
addFile(rerootPath(arg->getValue()), false)))
@ -878,12 +897,16 @@ void createFiles(const InputArgList &args) {
addFile(rerootPath(arg->getValue()), true);
break;
case OPT_l:
case OPT_reexport_l:
case OPT_weak_l:
addLibrary(arg->getValue(), opt.getID() == OPT_weak_l);
addLibrary(arg->getValue(), opt.getID() == OPT_weak_l,
opt.getID() == OPT_reexport_l, /*isExplicit=*/true);
break;
case OPT_framework:
case OPT_reexport_framework:
case OPT_weak_framework:
addFramework(arg->getValue(), opt.getID() == OPT_weak_framework);
addFramework(arg->getValue(), opt.getID() == OPT_weak_framework,
opt.getID() == OPT_reexport_framework, /*isExplicit=*/true);
break;
default:
break;

View File

@ -117,12 +117,10 @@ def weak_library : Separate<["-"], "weak_library">,
def reexport_l : Joined<["-"], "reexport-l">,
MetaVarName<"<name>">,
HelpText<"Like -l<name>, but export all symbols of <name> from newly created library">,
Flags<[HelpHidden]>,
Group<grp_libs>;
def reexport_library : Separate<["-"], "reexport_library">,
MetaVarName<"<path>">,
HelpText<"Like bare <path>, but export all symbols of <path> from newly created library">,
Flags<[HelpHidden]>,
Group<grp_libs>;
def upward_l : Joined<["-"], "upward-l">,
MetaVarName<"<name>">,
@ -162,7 +160,6 @@ def weak_framework : Separate<["-"], "weak_framework">,
def reexport_framework : Separate<["-"], "reexport_framework">,
MetaVarName<"<name>">,
HelpText<"Like -framework <name>, but export all symbols of <name> from the newly created library">,
Flags<[HelpHidden]>,
Group<grp_libs>;
def upward_framework : Separate<["-"], "upward_framework">,
MetaVarName<"<name>">,

View File

@ -18,14 +18,23 @@
## Check that they have the appropriate LC_REEXPORT_DYLIB commands, and that
## NO_REEXPORTED_DYLIBS is (un)set as appropriate.
# RUN: llvm-objdump --macho --all-headers %t/libhello.dylib | FileCheck %s \
# RUN: --check-prefix=HELLO-HEADERS
# RUN: llvm-otool -hv %t/libhello.dylib | \
# RUN: FileCheck --check-prefix=HELLO-HEADERS %s
# HELLO-HEADERS: NO_REEXPORTED_DYLIBS
# RUN: llvm-objdump --macho --all-headers %t/libgoodbye.dylib | FileCheck %s \
# RUN: llvm-otool -l %t/libgoodbye.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/libhello.dylib
# RUN: llvm-objdump --macho --all-headers %t/libsuper.dylib | FileCheck %s \
# RUN: llvm-otool -l %t/libsuper.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/libgoodbye.dylib
# RUN: %lld -dylib -L%t -reexport-lgoodbye -install_name \
# RUN: @executable_path/libsuper.dylib %t/libsuper.o -o %t/libsuper.dylib
# RUN: llvm-otool -l %t/libsuper.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/libgoodbye.dylib
# RUN: %lld -dylib -reexport_library %t/libgoodbye.dylib -install_name \
# RUN: @executable_path/libsuper.dylib %t/libsuper.o -o %t/libsuper.dylib
# RUN: llvm-otool -l %t/libsuper.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/libgoodbye.dylib
# REEXPORT-HEADERS-NOT: NO_REEXPORTED_DYLIBS
@ -53,16 +62,24 @@
## We can match dylibs without extensions too.
# RUN: mkdir -p %t/Hello.framework/Versions
# RUN: %lld -dylib %t/libhello.o -o %t/Hello.framework/Versions/Hello
# RUN: %lld -dylib -o %t/libgoodbye2.dylib -sub_library Hello %t/Hello.framework/Versions/Hello %t/libgoodbye.o
# RUN: llvm-objdump --macho --all-headers %t/libgoodbye2.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/Hello.framework/Versions/Hello
# RUN: mkdir -p %t/Hello.framework
# RUN: %lld -dylib %t/libhello.o -o %t/Hello.framework/Hello
# RUN: %lld -dylib -o %t/libgoodbye2.dylib -sub_library Hello %t/Hello.framework/Hello %t/libgoodbye.o
# RUN: llvm-otool -l %t/libgoodbye2.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/Hello.framework/Hello
## -sub_umbrella works almost identically...
# RUN: %lld -dylib -o %t/libgoodbye3.dylib -sub_umbrella Hello %t/Hello.framework/Versions/Hello %t/libgoodbye.o
# RUN: llvm-objdump --macho --all-headers %t/libgoodbye3.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/Hello.framework/Versions/Hello
# RUN: %lld -dylib -o %t/libgoodbye3.dylib -sub_umbrella Hello %t/Hello.framework/Hello %t/libgoodbye.o
# RUN: llvm-otool -l %t/libgoodbye3.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/Hello.framework/Hello
# RUN: %lld -dylib -o %t/libgoodbye3.dylib -F %t -framework Hello -sub_umbrella Hello %t/libgoodbye.o
# RUN: llvm-otool -l %t/libgoodbye3.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/Hello.framework/Hello
# RUN: %lld -dylib -o %t/libgoodbye3.dylib -F %t -reexport_framework Hello %t/libgoodbye.o
# RUN: llvm-otool -l %t/libgoodbye3.dylib | FileCheck %s \
# RUN: --check-prefix=REEXPORT-HEADERS -DPATH=%t/Hello.framework/Hello
## But it doesn't match .dylib extensions:
# RUN: not %lld -dylib -L%t -sub_umbrella libhello -lhello %t/libgoodbye.o \