You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 31844eb
Browse filesBrowse the repository at this point in the historyBrowse files
Leave private and frameworks headers out of the C++ API snapshots (#58837)
Summary:
Pull Request resolved: #58837
The C++ API snapshots now cover only the public tier of the C++ stable API. Symbols declared in headers that include `PrivateGuard.h` or `FrameworksGuard.h` are left out, unless a public header reaches them directly or transitively, in which case they are public in practice. Unclassified headers are kept. In verbose mode the generator reports how many private or frameworks headers are kept that way.
The snapshots are regenerated, and the README and snapshot docs describe the filtering.
Changelog: [Internal]
Reviewed By: coado
Differential Revision: D123001770
Copy file name to clipboardExpand all lines: scripts/cxx-api/README.md
+36-6Lines changed: 36 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -4,7 +4,7 @@ Python build pipeline for React Native's C++ (and Objective-C) API snapshots.
4
4
5
5
## Overview
6
6
7
-
`scripts/cxx-api` generates human-readable snapshots of React Native's public C++ API surface. It uses [Doxygen](https://www.doxygen.nl/) to parse C/C++/Objective-C headers and a custom Python parser to produce a simplified, sorted representation of every public symbol.
7
+
`scripts/cxx-api` generates human-readable snapshots of React Native's public C++ API surface. It uses [Doxygen](https://www.doxygen.nl/) to parse C/C++/Objective-C headers and a custom Python parser to produce a simplified, sorted representation of every public symbol. Symbols declared in headers that the C++ stable API classifies as private or "for frameworks" are left out (see [Tier filtering](#tier-filtering)).
8
8
9
9
The pipeline produces one `.api` snapshot file per configured **API view × variant** combination:
If any snapshot differs, a unified diff is printed and the process exits with a non-zero status. To fix a failing validation, regenerate the snapshots with `python -m scripts.cxx-api.parser` and commit the updated `.api` files.
43
43
44
+
#### Log tier boundary breaks
45
+
46
+
Pass `--log-boundary-breaks` (in either mode) to print every header whose includes cross a tier boundary, with the include chain that causes it:
Every header in a view's inputs is classified by the C++ stable API guard it includes:
47
59
48
-
### 1. Doxygen XML generation
60
+
| Guard | Tier |
61
+
|---|---|
62
+
|`react/cxxstableapi/UmbrellaGuard.h`| public |
63
+
|`react/cxxstableapi/FrameworksGuard.h`| for frameworks |
64
+
|`react/cxxstableapi/PrivateGuard.h`| private |
65
+
| none | unclassified |
66
+
67
+
The headers' `#include`/`#import` directives are resolved into an include graph of the view.
68
+
69
+
### 2. Doxygen XML generation
49
70
50
71
Doxygen is configured via a generated config file (built from `.doxygen.config.template`) with the input directories, exclude patterns, and preprocessor definitions specified in `config.yml`. It outputs XML describing every symbol found in the headers.
51
72
52
-
### 2. Snapshot parsing
73
+
### 3. Snapshot parsing
74
+
75
+
The Python parser (`parser/`) reads the Doxygen XML output and builds a scope tree of the public API surface, leaving out symbols declared in skipped headers. The tree is then serialized to a deterministically sorted, human-readable `.api` text format.
53
76
54
-
The Python parser (`parser/`) reads the Doxygen XML output and builds a scope tree of the public API surface. The tree is then serialized to a deterministically sorted, human-readable `.api` text format.
77
+
## Tier filtering
78
+
79
+
A private or for-frameworks header is skipped unless a public header reaches it, directly or through other includes: anything a public header includes is public in practice, whatever its own guard says. Unclassified headers are never skipped.
80
+
81
+
A boundary break is a public header that reaches a for-frameworks or private header, or a for-frameworks header that reaches a private one. `--log-boundary-breaks` reports them at the edge where visibility drops.
55
82
56
83
## When to use it
57
84
@@ -73,7 +100,10 @@ All API views and their variants are defined in `config.yml`. Each view specifie
73
100
|`definitions`| Preprocessor macros to define |
74
101
|`variants`| Named build variants (e.g. debug/release) with extra definitions |
75
102
|`codegen`| Optional codegen platform (`android`, `ios`) to generate TurboModule/Component headers before scanning |
76
-
|`private_directories`| Directories whose headers are scanned (they may be transitively included) but should not contribute public symbols. If any public API entity is defined in a private directory, a warning is printed to help catch accidental API exposure. |
103
+
|`exclude_symbols`| Regex patterns for symbols to skip |
104
+
|`input_filter`| Whether to run Doxygen through the input filters in `parser/input_filters/`|
105
+
106
+
`exclude_patterns` and `exclude_symbols` can also be set at the top level, in which case they apply to every view.
0 commit comments