[llvm] e1f69b8 - [readtapi] Add Extract & Remove architecture functionality (#72657)
via llvm-commits
llvm-commits at lists.llvm.org
Mon Nov 27 14:24:09 PST 2023
Author: Cyndy Ishida
Date: 2023-11-27T14:24:04-08:00
New Revision: e1f69b863df87227a48f10831b44a2adfba1c80d
URL: https://github.com/llvm/llvm-project/commit/e1f69b863df87227a48f10831b44a2adfba1c80d
DIFF: https://github.com/llvm/llvm-project/commit/e1f69b863df87227a48f10831b44a2adfba1c80d.diff
LOG: [readtapi] Add Extract & Remove architecture functionality (#72657)
This adds functionality to tbd files similar to what `lipo -extract`
and `lipo -remove` does for binaries.
Added:
llvm/test/tools/llvm-readtapi/extract-invalid.test
llvm/test/tools/llvm-readtapi/extract.test
llvm/test/tools/llvm-readtapi/remove-invalid.test
llvm/test/tools/llvm-readtapi/remove.test
Modified:
llvm/test/tools/llvm-readtapi/command-line.test
llvm/tools/llvm-readtapi/TapiOpts.td
llvm/tools/llvm-readtapi/llvm-readtapi.cpp
Removed:
################################################################################
diff --git a/llvm/test/tools/llvm-readtapi/command-line.test b/llvm/test/tools/llvm-readtapi/command-line.test
index 400e0670e5aa067..f12e1da70ec4239 100644
--- a/llvm/test/tools/llvm-readtapi/command-line.test
+++ b/llvm/test/tools/llvm-readtapi/command-line.test
@@ -4,7 +4,7 @@
; RUN: not llvm-readtapi -merge -compact %t/tmp.tbd %t/tmp2.tbd --filetype=tbd-v2 2>&1 | FileCheck %s --check-prefix FILE_FORMAT
CHECK: OVERVIEW: LLVM TAPI file reader and manipulator
-CHECK: USAGE: llvm-readtapi [options] <inputs>
+CHECK: USAGE: llvm-readtapi [options] [-arch <arch>]* <inputs> [-o <output>]*
CHECK: OPTIONS:
CHECK: -help display this help
diff --git a/llvm/test/tools/llvm-readtapi/extract-invalid.test b/llvm/test/tools/llvm-readtapi/extract-invalid.test
new file mode 100644
index 000000000000000..026b782eb00c122
--- /dev/null
+++ b/llvm/test/tools/llvm-readtapi/extract-invalid.test
@@ -0,0 +1,53 @@
+; RUN: rm -rf %t
+; RUN: split-file %s %t
+; RUN: not llvm-readtapi -extract %t/libfoo.tbd %t/libbar.tbd 2>&1 | FileCheck %s --allow-empty --check-prefix EXTRA
+; RUN: not llvm-readtapi -extract %t/libfoo.tbd 2>&1 | FileCheck %s --allow-empty --check-prefix MISSING
+; RUN: not llvm-readtapi -arch x86_64 -extract %t/libfoo.tbd 2>&1 | FileCheck %s --allow-empty --check-prefix MISMATCH
+
+; EXTRA: error: extract only supports one input file
+; MISSING: extract requires -arch <arch>
+; MISMATCH: error: {{.*}}libfoo.tbd' file doesn't have architecture 'x86_64'
+
+;--- libfoo.tbd
+--- !tapi-tbd
+tbd-version: 4
+targets: [ arm64-ios ]
+flags: [ not_app_extension_safe ]
+install-name: '/usr/lib/libfoo.dylib'
+exports:
+ - targets: [ arm64-ios ]
+ symbols: [ _bar ]
+...
+
+;--- libbar.tbd
+{
+ "main_library": {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_bar"
+ ]
+ }
+ }
+ ],
+ "flags": [
+ {
+ "attributes": [
+ "not_app_extension_safe"
+ ]
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/libbar.dylib"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "arm64-ios"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
diff --git a/llvm/test/tools/llvm-readtapi/extract.test b/llvm/test/tools/llvm-readtapi/extract.test
new file mode 100644
index 000000000000000..175efcda2d7cba1
--- /dev/null
+++ b/llvm/test/tools/llvm-readtapi/extract.test
@@ -0,0 +1,201 @@
+; RUN: rm -rf %t
+; RUN: split-file %s %t
+; RUN: llvm-readtapi -arch x86_64 -extract %t/libfat.tbd -compact -o %t/libslim.tbd 2>&1 | FileCheck --allow-empty %s
+; RUN: llvm-readtapi --compare %t/libslim.tbd %t/libslim_expected.tbd 2>&1 | FileCheck --allow-empty %s
+
+; RUN: llvm-readtapi -arch armv7s --extract %t/libfat2.tbd 2>&1 | FileCheck %s --check-prefix OUTPUT
+
+; CHECK-NOT: error
+; CHECK-NOT: warning
+
+; OUTPUT: {
+; OUTPUT-NEXT: "main_library": {
+; OUTPUT-NEXT: "install_names": [
+; OUTPUT-NEXT: {
+; OUTPUT-NEXT: "name": "/usr/lib/libfat.dylib"
+; OUTPUT-NEXT: }
+; OUTPUT-NEXT: ],
+; OUTPUT-NEXT: "target_info": [
+; OUTPUT-NEXT: {
+; OUTPUT-NEXT: "target": "armv7s-ios"
+; OUTPUT-NEXT: }
+; OUTPUT-NEXT: ]
+; OUTPUT-NEXT: },
+; OUTPUT-NEXT: "tapi_tbd_version": 5
+; OUTPUT-NEXT: }
+
+//--- libfat.tbd
+{
+ "libraries": [
+ {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_sym1"
+ ]
+ },
+ "targets": [
+ "x86_64-macos"
+ ]
+ },
+ {
+ "data": {
+ "global": [
+ "_sym2"
+ ]
+ },
+ "targets": [
+ "x86_64h-macos"
+ ]
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/internal/libfat.dylib"
+ }
+ ],
+ "parent_umbrellas": [
+ {
+ "umbrella": "fat"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ },
+ {
+ "target": "x86_64h-macos"
+ }
+ ]
+ }
+ ],
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "/usr/lib/internal/libfat.dylib"
+ ]
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ },
+ {
+ "target": "x86_64h-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
+
+//--- libfat2.tbd
+{
+ "libraries": [
+ {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_sym1"
+ ]
+ }
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/internal/libfat.dylib"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "arm64-ios"
+ }
+ ]
+ }
+ ],
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "/usr/lib/internal/libfat.dylib"
+ ],
+ "targets": [
+ "arm64-ios"
+ ]
+ }
+ ],
+ "target_info": [
+ {
+ "target": "armv7s-ios"
+ },
+ {
+ "target": "arm64-ios"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
+
+//--- libslim_expected.tbd
+{
+ "libraries": [
+ {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_sym1"
+ ]
+ }
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/internal/libfat.dylib"
+ }
+ ],
+ "parent_umbrellas": [
+ {
+ "umbrella": "fat"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ }
+ ]
+ }
+ ],
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "/usr/lib/internal/libfat.dylib"
+ ]
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
diff --git a/llvm/test/tools/llvm-readtapi/remove-invalid.test b/llvm/test/tools/llvm-readtapi/remove-invalid.test
new file mode 100644
index 000000000000000..e9de48c9745bfb6
--- /dev/null
+++ b/llvm/test/tools/llvm-readtapi/remove-invalid.test
@@ -0,0 +1,57 @@
+; RUN: rm -rf %t
+; RUN: split-file %s %t
+; RUN: not llvm-readtapi --remove -arch arm64 %t/libslim.tbd 2>&1 | FileCheck %s
+
+CHECK: {{.*}}libslim.tbd' cannot remove last architecture slice 'arm64'
+
+//--- libslim.tbd
+{
+ "libraries": [
+ {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_sym1"
+ ]
+ }
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/internal/libfat.dylib"
+ }
+ ],
+ "parent_umbrellas": [
+ {
+ "umbrella": "fat"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "arm64-macos"
+ }
+ ]
+ }
+ ],
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "/usr/lib/internal/libfat.dylib"
+ ]
+ }
+ ],
+ "target_info": [
+ {
+ "target": "arm64-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
diff --git a/llvm/test/tools/llvm-readtapi/remove.test b/llvm/test/tools/llvm-readtapi/remove.test
new file mode 100644
index 000000000000000..673634762f3823f
--- /dev/null
+++ b/llvm/test/tools/llvm-readtapi/remove.test
@@ -0,0 +1,274 @@
+; RUN: rm -rf %t
+; RUN: split-file %s %t
+; RUN: llvm-readtapi --remove -arch x86_64h %t/libfat.tbd -o %t/libslim.tbd 2>&1 | FileCheck --allow-empty %s
+; RUN: llvm-readtapi --compare %t/libslim.tbd %t/libslim_expected.tbd
+
+; RUN: llvm-readtapi --remove -arch x86_64h %t/libfat2.tbd -o %t/libslim2.tbd 2>&1 | FileCheck --allow-empty %s
+; RUN: llvm-readtapi --compare %t/libslim2.tbd %t/libslim_expected.tbd
+
+; RUN: llvm-readtapi --remove -arch x86_64 %t/libfat3.tbd -o %t/libslim3.tbd 2>&1 | FileCheck --allow-empty %s
+; RUN: llvm-readtapi --compare %t/libslim3.tbd %t/libslim3_expected.tbd
+
+; CHECK-NOT: error
+; CHECK-NOT: warning
+
+//--- libfat.tbd
+{
+ "libraries": [
+ {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_sym1"
+ ]
+ },
+ "targets": [
+ "x86_64-macos"
+ ]
+ },
+ {
+ "data": {
+ "global": [
+ "_sym2"
+ ]
+ },
+ "targets": [
+ "x86_64h-macos"
+ ]
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/internal/libfat.dylib"
+ }
+ ],
+ "parent_umbrellas": [
+ {
+ "umbrella": "fat"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ },
+ {
+ "target": "x86_64h-macos"
+ }
+ ]
+ }
+ ],
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "/usr/lib/internal/libfat.dylib"
+ ]
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ },
+ {
+ "target": "x86_64h-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
+
+//--- libfat2.tbd
+{
+ "libraries": [
+ {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_sym1"
+ ]
+ },
+ "targets": [
+ "x86_64-macos"
+ ]
+ },
+ {
+ "data": {
+ "global": [
+ "_sym2"
+ ]
+ },
+ "targets": [
+ "x86_64h-macos"
+ ]
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/internal/libfat.dylib"
+ }
+ ],
+ "parent_umbrellas": [
+ {
+ "umbrella": "fat"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ },
+ {
+ "target": "x86_64h-macos"
+ }
+ ]
+ }
+ ],
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "/usr/lib/internal/libfat.dylib"
+ ]
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
+
+//--- libfat3.tbd
+{
+ "libraries": [
+ {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_sym1"
+ ]
+ }
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/internal/libfat.dylib"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ }
+ ]
+ }
+ ],
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "/usr/lib/internal/libfat.dylib"
+ ],
+ "targets": [
+ "x86_64-macos"
+ ]
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ },
+ {
+ "target": "x86_64h-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
+
+//--- libslim_expected.tbd
+{
+ "libraries": [
+ {
+ "exported_symbols": [
+ {
+ "data": {
+ "global": [
+ "_sym1"
+ ]
+ }
+ }
+ ],
+ "install_names": [
+ {
+ "name": "/usr/lib/internal/libfat.dylib"
+ }
+ ],
+ "parent_umbrellas": [
+ {
+ "umbrella": "fat"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ }
+ ]
+ }
+ ],
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "reexported_libraries": [
+ {
+ "names": [
+ "/usr/lib/internal/libfat.dylib"
+ ]
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
+
+//--- libslim3_expected.tbd
+{
+ "main_library": {
+ "install_names": [
+ {
+ "name": "/usr/lib/libfat.dylib"
+ }
+ ],
+ "target_info": [
+ {
+ "target": "x86_64h-macos"
+ }
+ ]
+ },
+ "tapi_tbd_version": 5
+}
diff --git a/llvm/tools/llvm-readtapi/TapiOpts.td b/llvm/tools/llvm-readtapi/TapiOpts.td
index 1efa86ea3ae48d6..8fda035142a2ea0 100644
--- a/llvm/tools/llvm-readtapi/TapiOpts.td
+++ b/llvm/tools/llvm-readtapi/TapiOpts.td
@@ -13,6 +13,8 @@ multiclass JS<string name, string help, string var = ""> {
def action_group : OptionGroup<"action group">;
def compare : FF<"compare", "compare tapi files for library
diff erences">, Group<action_group>;
def merge : FF<"merge", "merge the input files that represent the same library">, Group<action_group>;
+def extract: FF<"extract", "extract architecture from input file">, Group<action_group>;
+def remove: FF<"remove", "remove architecture from input file">, Group<action_group>;
//
// General Driver options
@@ -21,3 +23,4 @@ def help : FF<"help", "display this help">;
defm output: JS<"o", "write output to <file>","<file>">;
def compact: FF<"compact", "write compact tapi output file">;
defm filetype: JS<"filetype", "specify the output file type (tbd-v3, tbd-v4 or tbd-v5)","<value>">;
+defm arch: JS<"arch", "specify the architecture", "<architecture>">;
diff --git a/llvm/tools/llvm-readtapi/llvm-readtapi.cpp b/llvm/tools/llvm-readtapi/llvm-readtapi.cpp
index 44419e8c5c2fceb..cb2b36072a552b1 100644
--- a/llvm/tools/llvm-readtapi/llvm-readtapi.cpp
+++ b/llvm/tools/llvm-readtapi/llvm-readtapi.cpp
@@ -75,9 +75,11 @@ struct Context {
std::unique_ptr<llvm::raw_fd_stream> OutStream;
FileType WriteFT = FileType::TBD_V5;
bool Compact = false;
+ Architecture Arch = AK_unknown;
};
-std::unique_ptr<InterfaceFile> getInterfaceFile(const StringRef Filename) {
+std::unique_ptr<InterfaceFile> getInterfaceFile(const StringRef Filename,
+ bool ResetBanner = true) {
ExitOnErr.setBanner(TOOLNAME + ": error: '" + Filename.str() + "' ");
ErrorOr<std::unique_ptr<MemoryBuffer>> BufferOrErr =
MemoryBuffer::getFile(Filename);
@@ -87,8 +89,8 @@ std::unique_ptr<InterfaceFile> getInterfaceFile(const StringRef Filename) {
TextAPIReader::get((*BufferOrErr)->getMemBufferRef());
if (!IF)
ExitOnErr(IF.takeError());
- // Set Banner back.
- ExitOnErr.setBanner(TOOLNAME + ": error: ");
+ if (ResetBanner)
+ ExitOnErr.setBanner(TOOLNAME + ": error: ");
return std::move(*IF);
}
@@ -139,6 +141,24 @@ bool handleMergeAction(const Context &Ctx) {
return handleWriteAction(Ctx, std::move(Out));
}
+using IFOperation =
+ std::function<llvm::Expected<std::unique_ptr<InterfaceFile>>(
+ const llvm::MachO::InterfaceFile &, Architecture)>;
+bool handleSingleFileAction(const Context &Ctx, const StringRef Action,
+ IFOperation act) {
+ if (Ctx.Inputs.size() != 1)
+ reportError(Action + " only supports one input file");
+ if (Ctx.Arch == AK_unknown)
+ reportError(Action + " requires -arch <arch>");
+
+ auto IF = getInterfaceFile(Ctx.Inputs.front(), /*ResetBanner=*/false);
+ auto OutIF = act(*IF, Ctx.Arch);
+ if (!OutIF)
+ ExitOnErr(OutIF.takeError());
+
+ return handleWriteAction(Ctx, std::move(*OutIF));
+}
+
} // anonymous namespace
int main(int Argc, char **Argv) {
@@ -151,7 +171,9 @@ int main(int Argc, char **Argv) {
opt::InputArgList Args = Tbl.parseArgs(
Argc, Argv, OPT_UNKNOWN, Saver, [&](StringRef Msg) { reportError(Msg); });
if (Args.hasArg(OPT_help)) {
- Tbl.printHelp(outs(), "llvm-readtapi [options] <inputs>",
+ Tbl.printHelp(outs(),
+ "USAGE: llvm-readtapi [options] [-arch <arch>]* <inputs> [-o "
+ "<output>]*",
"LLVM TAPI file reader and manipulator");
return EXIT_SUCCESS;
}
@@ -179,6 +201,12 @@ int main(int Argc, char **Argv) {
reportError("unsupported filetype '" + FT + "'");
}
+ if (opt::Arg *A = Args.getLastArg(OPT_arch_EQ)) {
+ StringRef Arch = A->getValue();
+ Ctx.Arch = getArchitectureFromName(Arch);
+ if (Ctx.Arch == AK_unknown)
+ reportError("unsupported architecture '" + Arch);
+ }
// Handle top level and exclusive operation.
SmallVector<opt::Arg *, 1> ActionArgs(Args.filtered(OPT_action_group));
@@ -200,6 +228,10 @@ int main(int Argc, char **Argv) {
return handleCompareAction(Ctx);
case OPT_merge:
return handleMergeAction(Ctx);
+ case OPT_extract:
+ return handleSingleFileAction(Ctx, "extract", &InterfaceFile::extract);
+ case OPT_remove:
+ return handleSingleFileAction(Ctx, "remove", &InterfaceFile::remove);
}
return EXIT_SUCCESS;
More information about the llvm-commits
mailing list