Skip to content

Commit 91791e0

Browse files
cyndyishidasr-tream
authored andcommitted
[readtapi] Add Merge functionality (llvm#72656)
Merge allows a user to merge different files (tbds for now or dylibs in the future) to emit out a single tbd with all input contents. This does require that all inputs represent the same library.
1 parent e97f1c1 commit 91791e0

File tree

10 files changed

+398
-45
lines changed

10 files changed

+398
-45
lines changed

llvm/include/llvm/TextAPI/TextAPIWriter.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
#ifndef LLVM_TEXTAPI_TEXTAPIWRITER_H
1010
#define LLVM_TEXTAPI_TEXTAPIWRITER_H
1111

12+
#include "llvm/ADT/StringSwitch.h"
1213
#include "llvm/TextAPI/InterfaceFile.h"
1314

1415
namespace llvm {
@@ -32,6 +33,19 @@ class TextAPIWriter {
3233
static Error writeToStream(raw_ostream &OS, const InterfaceFile &File,
3334
const FileType FileKind = FileType::Invalid,
3435
bool Compact = false);
36+
37+
/// Get TAPI FileType from the input string.
38+
///
39+
/// \param FT String of input to map to FileType.
40+
static FileType parseFileType(const StringRef FT) {
41+
return StringSwitch<FileType>(FT)
42+
.Case("tbd-v1", FileType::TBD_V1)
43+
.Case("tbd-v2", FileType::TBD_V2)
44+
.Case("tbd-v3", FileType::TBD_V3)
45+
.Case("tbd-v4", FileType::TBD_V4)
46+
.Case("tbd-v5", FileType::TBD_V5)
47+
.Default(FileType::Invalid);
48+
}
3549
};
3650

3751
} // end namespace MachO.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,13 @@
11
; RUN: llvm-readtapi --help 2>&1 | FileCheck %s
22
; RUN: llvm-readtapi -help 2>&1 | FileCheck %s
3+
; RUN: not llvm-readtapi -merge -compare -compact %t/tmp.tbd %t/tmp2.tbd 2>&1 | FileCheck %s --check-prefix MULTI_ACTION
4+
; RUN: not llvm-readtapi -merge -compact %t/tmp.tbd %t/tmp2.tbd --filetype=tbd-v2 2>&1 | FileCheck %s --check-prefix FILE_FORMAT
35

46
CHECK: OVERVIEW: LLVM TAPI file reader and manipulator
57
CHECK: USAGE: llvm-readtapi [options] <inputs>
68
CHECK: OPTIONS:
79
CHECK: -help display this help
10+
11+
MULTI_ACTION: error: only one of the following actions can be specified: -merge -compare
12+
FILE_FORMAT: error: deprecated filetype 'tbd-v2' is not supported to write
13+

llvm/test/tools/llvm-readtapi/compare-incorrect-format.test

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@
22
; RUN: yaml2obj %S/Inputs/macho.yaml -o %t/macho.dylib
33
; RUN: not llvm-readtapi --compare %S/Inputs/v4A.tbd %t/macho.dylib 2>&1 | FileCheck %s
44

5-
; CHECK: error: {{.*}}macho.dylib' unsupported file format
5+
; CHECK: error: {{.*}}macho.dylib' unsupported file type
66
; CHECK-NOT: error:
77
; CHECK-NOT: warning:
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
; RUN: rm -rf %t
2+
; RUN: split-file %s %t
3+
; RUN: not llvm-readtapi -merge %t/libfoo.tbd %t/libbar.tbd 2>&1 | FileCheck %s --allow-empty --check-prefix DIFF
4+
; RUN: not llvm-readtapi -merge %t/libfoo.tbd 2>&1 | FileCheck %s --allow-empty --check-prefix INPUT
5+
6+
; DIFF: install names do not match
7+
; INPUT: merge requires at least two input files
8+
9+
;--- libfoo.tbd
10+
{
11+
"main_library": {
12+
"allowable_clients": [
13+
{
14+
"clients": [
15+
"ClientAll"
16+
]
17+
}
18+
],
19+
"install_names": [
20+
{
21+
"name": "/usr/lib/libfoo.dylib"
22+
}
23+
],
24+
"target_info": [
25+
{
26+
"min_deployment": "13.1",
27+
"target": "x86_64-macos"
28+
}
29+
]
30+
},
31+
"tapi_tbd_version": 5
32+
}
33+
34+
;--- libbar.tbd
35+
--- !tapi-tbd
36+
tbd-version: 4
37+
targets: [ arm64-macos ]
38+
install-name: '/usr/lib/libbar.dylib'
39+
allowable-clients:
40+
- targets: [ arm64-macos ]
41+
clients: [ ClientAll ]
42+
reexported-libraries:
43+
- targets: [ arm64-macos ]
44+
libraries: [ '/usr/lib/liball.dylib' ]
45+
exports:
46+
- targets: [ arm64-macos ]
47+
symbols: [ _sym1 ]
48+
objc-classes: [ _A ]
49+
objc-ivars: [ _A._ivar1 ]
50+
weak-symbols: [ _weak1 ]
51+
thread-local-symbols: [ _tlv1 ]
52+
...
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
; RUN: rm -rf %t
2+
; RUN: split-file %s %t
3+
; RUN: llvm-readtapi -merge %t/i386.tbd %t/x86_64.tbd %t/arm64.tbd --filetype tbd-v5 -o %t/out.tbd -compact 2>&1 | FileCheck %s --allow-empty
4+
; RUN: llvm-readtapi -merge %t/i386.tbd %t/x86_64.tbd %t/arm64.tbd --filetype=tbd-v5 --o %t/out.tbd -compact 2>&1 | FileCheck %s --allow-empty
5+
; RUN: llvm-readtapi -compare %t/out.tbd %t/expected.tbd 2>&1 | FileCheck %s --allow-empty
6+
7+
; CHECK-NOT: error
8+
; CHECK-NOT: warning
9+
10+
;--- expected.tbd
11+
{
12+
"main_library": {
13+
"allowable_clients": [{ "clients": ["ClientAll"] }],
14+
"exported_symbols": [
15+
{
16+
"data": {
17+
"global": ["_sym1"],
18+
"objc_class": ["_A"],
19+
"thread_local": ["_tlv1"],
20+
"weak": ["_weak1"]
21+
}
22+
},
23+
{
24+
"data": {
25+
"objc_ivar": ["_A._ivar1"]
26+
},
27+
"targets": [ "x86_64-macos", "arm64-macos" ]
28+
}
29+
],
30+
"install_names": [
31+
{ "name": "/usr/lib/libfat.dylib" }
32+
],
33+
"reexported_libraries": [
34+
{
35+
"names": [ "/usr/lib/liball.dylib" ]
36+
}
37+
],
38+
"target_info": [
39+
{ "target": "i386-macos" },
40+
{
41+
"min_deployment": "13.1",
42+
"target": "x86_64-macos"
43+
},
44+
{
45+
"target": "arm64-macos"
46+
}
47+
]
48+
},
49+
"tapi_tbd_version": 5
50+
}
51+
52+
53+
;--- i386.tbd
54+
--- !tapi-tbd-v3
55+
archs: [ i386 ]
56+
platform: macosx
57+
install-name: /usr/lib/libfat.dylib
58+
exports:
59+
- archs: [ i386 ]
60+
allowable-clients: [ ClientAll ]
61+
re-exports: [ /usr/lib/liball.dylib ]
62+
symbols: [ _sym1 ]
63+
objc-classes: [ _A ]
64+
weak-def-symbols: [ _weak1 ]
65+
thread-local-symbols: [ _tlv1 ]
66+
...
67+
68+
;--- x86_64.tbd
69+
{
70+
"main_library": {
71+
"allowable_clients": [
72+
{
73+
"clients": [
74+
"ClientAll"
75+
]
76+
}
77+
],
78+
"exported_symbols": [
79+
{
80+
"data": {
81+
"global": [
82+
"_sym1"
83+
],
84+
"objc_class": [
85+
"_A"
86+
],
87+
"objc_ivar": [
88+
"_A._ivar1"
89+
],
90+
"thread_local": [
91+
"_tlv1"
92+
],
93+
"weak": [
94+
"_weak1"
95+
]
96+
}
97+
}
98+
],
99+
"install_names": [
100+
{
101+
"name": "/usr/lib/libfat.dylib"
102+
}
103+
],
104+
"reexported_libraries": [
105+
{
106+
"names": [
107+
"/usr/lib/liball.dylib"
108+
]
109+
}
110+
],
111+
"target_info": [
112+
{
113+
"min_deployment": "13.1",
114+
"target": "x86_64-macos"
115+
}
116+
]
117+
},
118+
"tapi_tbd_version": 5
119+
}
120+
121+
;--- arm64.tbd
122+
--- !tapi-tbd
123+
tbd-version: 4
124+
targets: [ arm64-macos ]
125+
install-name: '/usr/lib/libfat.dylib'
126+
allowable-clients:
127+
- targets: [ arm64-macos ]
128+
clients: [ ClientAll ]
129+
reexported-libraries:
130+
- targets: [ arm64-macos ]
131+
libraries: [ '/usr/lib/liball.dylib' ]
132+
exports:
133+
- targets: [ arm64-macos ]
134+
symbols: [ _sym1 ]
135+
objc-classes: [ _A ]
136+
objc-ivars: [ _A._ivar1 ]
137+
weak-symbols: [ _weak1 ]
138+
thread-local-symbols: [ _tlv1 ]
139+
...
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
; RUN: rm -rf %t
2+
; RUN: split-file %s %t
3+
; RUN: llvm-readtapi %t/arm64.tbd 2>&1 | FileCheck %s
4+
5+
; CHECK-NOT: error
6+
; CHECK-NOT: warning
7+
; CHECK: {
8+
; CHECK-NEXT: "main_library": {
9+
; CHECK-NEXT: "allowable_clients": [
10+
; CHECK-NEXT: {
11+
; CHECK-NEXT: "clients": [
12+
; CHECK-NEXT: "ClientAll"
13+
; CHECK-NEXT: ]
14+
; CHECK-NEXT: }
15+
; CHECK-NEXT: ],
16+
; CHECK-NEXT: "exported_symbols": [
17+
; CHECK-NEXT: {
18+
; CHECK-NEXT: "data": {
19+
; CHECK-NEXT: "global": [
20+
; CHECK-NEXT: "_sym1"
21+
; CHECK-NEXT: ],
22+
; CHECK-NEXT: "objc_class": [
23+
; CHECK-NEXT: "_A"
24+
; CHECK-NEXT: ],
25+
; CHECK-NEXT: "objc_ivar": [
26+
; CHECK-NEXT: "_A._ivar1"
27+
; CHECK-NEXT: ],
28+
; CHECK-NEXT: "thread_local": [
29+
; CHECK-NEXT: "_tlv1"
30+
; CHECK-NEXT: ],
31+
; CHECK-NEXT: "weak": [
32+
; CHECK-NEXT: "_weak1"
33+
; CHECK-NEXT: ]
34+
; CHECK-NEXT: }
35+
; CHECK-NEXT: }
36+
; CHECK-NEXT: ],
37+
; CHECK-NEXT: "install_names": [
38+
; CHECK-NEXT: {
39+
; CHECK-NEXT: "name": "/usr/lib/libfat.dylib"
40+
; CHECK-NEXT: }
41+
; CHECK-NEXT: ],
42+
; CHECK-NEXT: "reexported_libraries": [
43+
; CHECK-NEXT: {
44+
; CHECK-NEXT: "names": [
45+
; CHECK-NEXT: "/usr/lib/liball.dylib"
46+
; CHECK-NEXT: ]
47+
; CHECK-NEXT: }
48+
; CHECK-NEXT: ],
49+
; CHECK-NEXT: "target_info": [
50+
; CHECK-NEXT: {
51+
; CHECK-NEXT: "target": "arm64-macos"
52+
; CHECK-NEXT: }
53+
; CHECK-NEXT: ]
54+
; CHECK-NEXT: },
55+
; CHECK-NEXT: "tapi_tbd_version": 5
56+
; CHECK-NEXT: }
57+
58+
59+
;--- arm64.tbd
60+
--- !tapi-tbd
61+
tbd-version: 4
62+
targets: [ arm64-macos ]
63+
install-name: '/usr/lib/libfat.dylib'
64+
allowable-clients:
65+
- targets: [ arm64-macos ]
66+
clients: [ ClientAll ]
67+
reexported-libraries:
68+
- targets: [ arm64-macos ]
69+
libraries: [ '/usr/lib/liball.dylib' ]
70+
exports:
71+
- targets: [ arm64-macos ]
72+
symbols: [ _sym1 ]
73+
objc-classes: [ _A ]
74+
objc-ivars: [ _A._ivar1 ]
75+
weak-symbols: [ _weak1 ]
76+
thread-local-symbols: [ _tlv1 ]
77+
...

llvm/tools/llvm-readtapi/DiffEngine.cpp

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -560,13 +560,11 @@ void DiffEngine::printDifferences(raw_ostream &OS,
560560
}
561561

562562
bool DiffEngine::compareFiles(raw_ostream &OS) {
563-
const auto *IFLHS = &(FileLHS->getInterfaceFile());
564-
const auto *IFRHS = &(FileRHS->getInterfaceFile());
565-
if (*IFLHS == *IFRHS)
563+
if (*FileLHS == *FileRHS)
566564
return false;
567-
OS << "< " << std::string(IFLHS->getPath().data()) << "\n> "
568-
<< std::string(IFRHS->getPath().data()) << "\n\n";
569-
std::vector<DiffOutput> Diffs = findDifferences(IFLHS, IFRHS);
565+
OS << "< " << std::string(FileLHS->getPath().data()) << "\n> "
566+
<< std::string(FileRHS->getPath().data()) << "\n\n";
567+
std::vector<DiffOutput> Diffs = findDifferences(FileLHS, FileRHS);
570568
printDifferences(OS, Diffs, 0);
571569
return true;
572570
}

llvm/tools/llvm-readtapi/DiffEngine.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -141,14 +141,14 @@ class InlineDoc : public AttributeDiff {
141141
/// output of the differences found in the files.
142142
class DiffEngine {
143143
public:
144-
DiffEngine(object::TapiUniversal *InputFileNameLHS,
145-
object::TapiUniversal *InputFileNameRHS)
144+
DiffEngine(MachO::InterfaceFile *InputFileNameLHS,
145+
MachO::InterfaceFile *InputFileNameRHS)
146146
: FileLHS(InputFileNameLHS), FileRHS(InputFileNameRHS){};
147147
bool compareFiles(raw_ostream &);
148148

149149
private:
150-
object::TapiUniversal *FileLHS;
151-
object::TapiUniversal *FileRHS;
150+
MachO::InterfaceFile *FileLHS;
151+
MachO::InterfaceFile *FileRHS;
152152

153153
/// Function that prints the differences found in the files.
154154
void printDifferences(raw_ostream &, const std::vector<DiffOutput> &, int);

llvm/tools/llvm-readtapi/TapiOpts.td

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,16 @@ multiclass JS<string name, string help, string var = ""> {
88
}
99

1010
//
11-
// General Driver options
11+
// Top level operations
1212
//
13-
def help : FF<"help", "display this help">;
14-
defm output: JS<"o", "write output to <file>","<file>">;
13+
def action_group : OptionGroup<"action group">;
14+
def compare : FF<"compare", "compare tapi files for library differences">, Group<action_group>;
15+
def merge : FF<"merge", "merge the input files that represent the same library">, Group<action_group>;
1516

1617
//
17-
// Compare options
18+
// General Driver options
1819
//
19-
def compare : FF<"compare", "compare tapi files for library differences">;
20+
def help : FF<"help", "display this help">;
21+
defm output: JS<"o", "write output to <file>","<file>">;
22+
def compact: FF<"compact", "write compact tapi output file">;
23+
defm filetype: JS<"filetype", "specify the output file type (tbd-v3, tbd-v4 or tbd-v5)","<value>">;

0 commit comments

Comments
 (0)