Skip to content

Commit 394a509

Browse files
committed
[doc] add documentation for IDS
1 parent b14bf55 commit 394a509

File tree

2 files changed

+197
-1
lines changed

2 files changed

+197
-1
lines changed

Docs/ExportMacroDefinitions.md

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
## Export Macro Definitions
2+
3+
A common approach for annotating project’s public interface is by defining a
4+
set of preprocessor macros that are used instead of adding annotations directly
5+
to the source. This approach allows supporting visibility annotations
6+
(`[[gnu::visibility]]`, `__visibility__`) when building for Linux and MacOS and
7+
DLL import/export annotations (`__declspec(dllimport)`,
8+
`__declspec(dllexport)`) when building for Windows.
9+
10+
For example, the `PUBLIC_ABI` macro defined below can be added to symbols in a
11+
project’s header files files that should be externally visible.
12+
13+
```cpp
14+
#ifdef _WIN32
15+
#ifdef EXPORTING_ABI
16+
// When building the Windows DLL, the public API must be annotated for exported.
17+
#define PUBLIC_ABI __declspec(dllexport)
18+
#else
19+
// When building clients of the Windows DLL, the public API must be annotated for import.
20+
#define PUBLIC_ABI __declspec(dllimport)
21+
#endif
22+
#elif defined(__cplusplus) && defined(__has_cpp_attribute) && \
23+
__has_cpp_attribute(gnu::visibility) && defined(__GNUC__) && !defined(__clang__)
24+
// When supported, use the gnu::visibility C++ attribute to set visibility to default.
25+
#define PUBLIC_API [[gnu::visibility("default")]]
26+
#elif defined(__has_attribute) && __has_attribute(visibility)
27+
// Otherwise, use the __attribute__ to set visibility to default.
28+
#define PUBLIC_ABI __attribute__((visibility("default")))
29+
#else
30+
#error "Required visibility attribute are not supported by compiler!"
31+
#endif
32+
```
33+
34+
A Windows project using these macros must be built with `EXPORTING_ABI` defined
35+
so that public symbols are annotated for export with `__declspec(dllexport)`.
36+
When building the client, however, `EXPORTING_ABI` must not be defined so the
37+
same set of public symbols will be properly annotated for import with
38+
`__declspec(dllimport)`.
39+
40+
An ELF shared library or Mach-O dylib project will have all symbols publicly
41+
visible by default so annotations are not strictly required. However, when a
42+
project is built with default hidden symbol visibility using
43+
`-fvisibility-default=hidden`, individual symbols must be explicitly exported
44+
using a visibility annotations.

README.md

Lines changed: 153 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,154 @@
11
# Interface Definition Scanner (IDS)
2-
Interface Analysis Utility
2+
3+
IDS is tool for automatically identifying and annotating the public interface of
4+
a C++ project. It is built on Clang’s
5+
[LibTooling](https://clang.llvm.org/docs/LibTooling.html) framework. It is
6+
primarily designed for adding import/export annotations to a Windows DLL
7+
project, but can also be used to add visibility annotations for ELF shared
8+
library or Mach-O dylib projects.
9+
10+
## Building IDS
11+
12+
IDS can be built either as an LLVM external project or as a stand-alone project.
13+
14+
### LLVM External Project
15+
16+
IDS can be built as a sub-project of LLVM by setting `LLVM_EXTERNAL_PROJECTS`.
17+
This greatly improves the editing and debugging experience in Visual Studio when
18+
navigating to Clang code from the IDS code. Please see [Getting Started with the
19+
LLVM
20+
Project](https://llvm.org/docs/GettingStarted.html#getting-the-source-code-and-building-llvm)
21+
for more info on building LLVM and Clang.
22+
23+
The CMake variables `LLVM_EXTERNAL_PROJECTS` and `LLVM_EXTERNAL_IDS_SOURCE_DIR`
24+
variables must be set for IDS to build as part of the LLVM build.
25+
26+
Testing IDS also requires `LIT_EXECUTABLE` and `FILECHECK_EXECUTABLE` to specify
27+
the locations of `lit.py` and `FileCheck`, which are located in the LLVM source
28+
and LLVM build output directory.
29+
30+
```bash
31+
cmake -G Ninja \
32+
-B /home/user/src/llvm-project/build \
33+
-S /home/user/src/llvm-project/llvm \
34+
-DCMAKE_BUILD_TYPE=Release \
35+
-DLLVM_ENABLE_PROJECTS="llvm;clang" \
36+
-DLLVM_EXTERNAL_PROJECTS="IDS" \
37+
-DLLVM_EXTERNAL_IDS_SOURCE_DIR="/home/user/src/ids" \
38+
-DLIT_EXECUTABLE=/home/user/src/llvm-project/llvm/utils/lit/lit.py \
39+
-DFILECHECK_EXECUTABLE=/home/user/src/llvm-project/build/bin/FileCheck
40+
41+
cmake --build /home/user/src/llvm-project/build --target idt
42+
cmake --build /home/user/src/llvm-project/build --target check-ids
43+
```
44+
45+
### Stand-Alone Build
46+
47+
To build IDS as a stand-alone project, `LLVM_DIR` and `Clang_DIR` variables must
48+
be provided to specify the locations of local LLVM and Clang libraries. These
49+
can refer to locally built LLVM and Clang libraries, or to pre-built LLVM
50+
package that includes the Clang development libraries.
51+
52+
Testing IDS also requires `LIT_EXECUTABLE` and `FILECHECK_EXECUTABLE` to specify
53+
the locations of `lit.py` and `FileCheck` , which are not typically included in
54+
a pre-built LLVM package.
55+
56+
```bash
57+
cmake -G Ninja \
58+
-B /home/user/src/ids/build \
59+
-S home/user/src/ids \
60+
-DCMAKE_BUILD_TYPE=Release \
61+
-DLIT_EXECUTABLE=/home/user/src/llvm-project/llvm/utils/lit/lit.py \
62+
-DFILECHECK_EXECUTABLE=/home/user/src/llvm-project/build/bin/FileCheck \
63+
-DLLVM_DIR=/home/user/src/llvm-project/build/lib/cmake/llvm \
64+
-DClang_DIR=/home/user/src/llvm-project/build/lib/cmake/clang
65+
66+
cmake --build S:\ids\build --target idt
67+
cmake --build S:\ids\build --target check-ids
68+
```
69+
70+
## Running IDS
71+
72+
There are a number of command-line arguments to IDS that dictate its behavior.
73+
74+
```bash
75+
USAGE: idt [options] <source0> [... <sourceN>]
76+
77+
OPTIONS:
78+
79+
Generic Options:
80+
81+
--help - Display available options (--help-hidden for more)
82+
--help-list - Display list of available options (--help-list-hidden for more)
83+
--version - Display the version of this program
84+
85+
interface definition scanner options:
86+
87+
--apply-fixits - Apply suggested changes to decorate interfaces
88+
--export-macro=<define> - The macro to decorate interfaces with
89+
--extra-arg=<string> - Additional argument to append to the compiler command line
90+
--extra-arg-before=<string> - Additional argument to prepend to the compiler command line
91+
--ignore=<function-name[,function-name...]> - Ignore one or more functions
92+
--include-header=<header> - Header required for export macro
93+
--inplace - Apply suggested changes in-place
94+
-p <string> - Build path
95+
```
96+
97+
At a minimum, the `--export-macro` argument must be provided to specify the
98+
macro used to annotate public symbols. See [Export Macro
99+
Definitions](Docs/ExportMacroDefinitions.md) for details. Additionally, at
100+
least one source file must be specified as a positional argument.
101+
102+
While it is possible to specify a number of source files, IDS generally works
103+
better when invoked to process one file at a time.
104+
105+
### Windows Example
106+
107+
```powershell
108+
S:\Source\ids\build\bin\idt.exe `
109+
-p S:\Source\MyProject\build `
110+
--apply-fixits `
111+
--inplace `
112+
--export-macro=PUBLIC_ABI `
113+
--include-header="include/MyAnnotations.h" `
114+
--extra-arg="-DPUBLIC_ABI=__declspec(dllexport)" `
115+
--extra-arg="-Wno-macro-redefined" `
116+
--extra-arg="-fno-delayed-template-parsing" `
117+
S:\Source\MyProject\include\ProjectHeader1.h `
118+
S:\Source\MyProject\include\ProjectHeader2.h
119+
```
120+
121+
### Linux Example
122+
123+
```bash
124+
/home/user/src/ids/out/bin/idt \
125+
-p /home/user/src/MyProject/build \
126+
--apply-fixits \
127+
--inplace \
128+
--export-macro=PUBLIC_ABI \
129+
--include-header="include/MyAnnotations.h" \
130+
--extra-arg="-DLLVM_ABI=[[gnu::visibility(\"default\")]]" \
131+
--extra-arg="-Wno-macro-redefined" \
132+
S:\Source\MyProject\include\ProjectHeader1.h \
133+
S:\Source\MyProject\include\ProjectHeader2.h
134+
```
135+
136+
The arguments in the above examples have the following effects:
137+
- `-p` refers to the build directory for the project containing a
138+
`compile_commands.json` file used by IDS to configure build options
139+
- `--apply-fixits` and `--inplace` instruct IDS to modify the source file in
140+
place
141+
- `--export-macro` indicates that the `PUBLIC_ABI` macro will be used to
142+
annotate public symbols
143+
- `--include-header` specifies a local header file that will be added as a
144+
`#include` in the processed source files if needed. This would typically
145+
refer to the header file containing the export macro definition.
146+
- The first two `--extra-arg` arguments ensure that `PUBLIC_ABI` is always
147+
defined (differently for Windows and Linux), and suppress the warning emitted
148+
if it already is. These arguments ensure the `PUBLIC_ABI` annotation is not
149+
mistakenly added to a symbol that already has it.
150+
- The third `--extra-arg` argument is Windows-specific and ensures that
151+
templates are always expanded while parsing. It is ensures overloaded private
152+
methods get properly exported when referenced only from inline templates.
153+
- The trailing positional arguments are the names of source files for IDS to
154+
scan.

0 commit comments

Comments
 (0)