xref: /aosp_15_r20/build/soong/docs/map_files.md (revision 333d2b3687b3a337dbcca9d65000bca186795e39)
1# Native API Map Files
2
3Native APIs such as those exposed by the NDK, LL-NDK, or APEX are described by
4map.txt files. These files are [linker version scripts] with comments that are
5semantically meaningful to [gen_stub_libs.py]. For an example of a map file, see
6[libc.map.txt].
7
8[gen_stub_libs.py]: https://cs.android.com/android/platform/superproject/+/main:build/soong/cc/gen_stub_libs.py
9[libc.map.txt]: https://cs.android.com/android/platform/superproject/+/main:bionic/libc/libc.map.txt
10[linker version scripts]: https://www.gnu.org/software/gnulib/manual/html_node/LD-Version-Scripts.html
11
12## Basic format
13
14A linker version script defines at least one alphanumeric "version" definition,
15each of which contain a list of symbols. For example:
16
17```txt
18MY_API_R { # introduced=R
19  global:
20    api_foo;
21    api_bar;
22  local:
23    *;
24};
25
26MY_API_S { # introduced=S
27  global:
28    api_baz;
29} MY_API_R;
30```
31
32Comments on the same line as either a version definition or a symbol name have
33meaning. If you need to add any comments that should not be interpreted by the
34stub generator, keep them on their own line. For a list of supported comments,
35see the "Tags" section.
36
37Here, `api_foo` and `api_bar` are exposed in the generated stubs with the
38`MY_API_R` version and `api_baz` is exposed with the `MY_API_S` version. No
39other symbols are defined as public by this API. `MY_API_S` inherits all symbols
40defined by `MY_API_R`.
41
42When generating NDK API stubs from this version script, the stub library for R
43will define `api_foo` and `api_bar`. The stub library for S will define all
44three APIs.
45
46Note that, with few exceptions (see "Special version names" below), the name of
47the version has no inherent meaning.
48
49These map files can (and should) also be used as version scripts for building
50the implementation library rather than just defining the stub interface by using
51the `version_script` property of `cc_library`. This has the effect of limiting
52symbol visibility of the library to expose only the interface named by the map
53file. Without this, APIs that you have not explicitly exposed will still be
54available to users via `dlsym`. Note: All comments are ignored in this case. Any
55symbol named in any `global:` group will be visible in the implementation
56library. Annotations in comments only affect what is exposed by the stubs.
57
58## Special version names
59
60Version names that end with `_PRIVATE` or `_PLATFORM` will not be exposed in any
61stubs, but will be exposed in the implementation library. Using either of these
62naming schemes is equivalent to marking the version with the `platform-only`
63tag. See the docs for `platform-only` for more information.
64
65## Tags
66
67Comments on the same line as a version definition or a symbol name are
68interpreted by the stub generator. Multiple space-delimited tags may be used on
69the same line. The supported tags are:
70
71### apex
72
73Indicates that the version or symbol is to be exposed by an APEX rather than the
74NDK. For APIs exposed by the platform *for* APEX, use `systemapi`.
75
76May be used in combination with `llndk` if the symbol is exposed to both APEX
77and the LL-NDK.
78
79### future
80
81Indicates that the version or symbol is first introduced in the "future" API
82level. This is an arbitrarily high API level used to define APIs that have not
83yet been added to a specific release.
84
85Warning: APIs marked `future` will be usable in any module with `sdk: "current"`
86but **will not be included in the NDK**. `future` should generally not be used,
87but is useful when developing APIs for an unknown future release.
88
89### introduced
90
91Indicates the version in which an API was first introduced in the NDK. For
92example, `introduced=21` specifies that the API was first added (or first made
93public) in API level 21. This tag can be applied to either a version definition
94or an individual symbol. If applied to a version, all symbols contained in the
95version will have the tag applied. An `introduced` tag on a symbol overrides the
96value set for the version, if both are defined.
97
98The `introduced` tag should only be used with NDK APIs. Other API surface tags
99(such as `apex`) will override `introduced`. APIs that are in the NDK should
100never use tags like `apex`, and APIs that are not in the NDK should never use
101`introduced`.
102
103Note: The map file alone does not contain all the information needed to
104determine which API level an API was added in. The `first_version` property of
105`ndk_library` will dictate which API levels stubs are generated for. If the
106module sets `first_version: "21"`, no symbols were introduced before API 21.
107**Symbol names for which no other rule applies will implicitly be introduced in
108`first_version`.**
109
110Code names can (and typically should) be used when defining new APIs. This
111allows the actual number of the API level to remain vague during development of
112that release. For example, `introduced=S` can be used to define APIs added in S.
113Any code name known to the build system can be used. For a list of versions
114known to the build system, see `out/soong/api_levels.json` (if not present, run
115`m out/soong/api_levels.json` to generate it).
116
117Architecture-specific variants of this tag exist:
118
119* `introduced-arm=VERSION`
120* `introduced-arm64=VERSION`
121* `introduced-x86=VERSION`
122* `introduced-x86_64=VERSION`
123
124The architecture-specific tag will take precedence over the architecture-generic
125tag when generating stubs for that architecture if both are present. If the
126symbol is defined with only architecture-specific tags, it will not be present
127for architectures that are not named.
128
129Note: The architecture-specific tags should, in general, not be used. These are
130primarily needed for APIs that were wrongly inconsistently exposed by libc/libm
131in old versions of Android before the stubs were well maintained. Think hard
132before using an architecture-specific tag for a new API.
133
134### llndk
135
136Indicates that the version or symbol is to be exposed in the LL-NDK stubs rather
137than the NDK. May be used in combination with `apex` if the symbol is exposed to
138both APEX and the LL-NDK.
139
140Historically this annotation was spelled `vndk`, but it has always meant LL-NDK.
141
142When an llndk API is deprecated, the `llndk` tag is dropped and
143`llndk-deprecate=<V>` is added.
144
145### platform-only
146
147Indicates that the version or symbol is public in the implementation library but
148should not be exposed in the stub library. Developers can still access them via
149`dlsym`, but they will not be exposed in the stubs so it should at least be
150clear to the developer that they are up to no good.
151
152The typical use for this tag is for exposing an API to the platform that is not
153for use by the NDK, LL-NDK, or APEX (similar to Java's `@SystemAPI`). It is
154preferable to keep such APIs in an entirely separate library to protect them
155from access via `dlsym`, but this is not always possible.
156
157### systemapi
158
159Indicates that the symbol is exposed by the platform for an apex. Whereas `apex`
160should be used for APIs exposed by an APEX to the platform or another APEX.
161
162May be used in combination with `llndk` if the symbol is exposed to both APEX
163and the LL-NDK.
164
165Since a single library can be installed ether in platform or an apex, but not
166both, a single map.txt file should not contain _both_ # apex and # systemapi symbols.
167
168The granularity between # apex and # systemapi exists to help the API review
169process (b/191371676). These two symbols have very similar lifetime "in
170practice". A #systemapi symbol can be dropped from the next release if we are
171confident that no one is using it. Similarily, #apex can be dropped if we are
172sure that the old platform which used the symbol has reached EOL and thus is no
173longer accepting new APEX updates. Unlike the APIs for apps where we have zero
174control over how APIs are used, we are in a much more controllable environment
175when talking about #systemapi and #apex symbols. So, we have some flexibility
176here when determining the lifetime of a symbol.
177
178### var
179
180Used to define a public global variable. By default all symbols are exposed as
181functions. In the uncommon situation of exposing a global variable, the `var`
182tag may be used.
183
184### versioned=VERSION
185
186Behaves similarly to `introduced` but defines the first version that the stub
187library should apply symbol versioning. For example:
188
189```txt
190R { # introduced=R
191  global:
192    foo;
193    bar; # versioned=S
194  local:
195    *;
196};
197```
198
199The stub library for R will contain symbols for both `foo` and `bar`, but only
200`foo` will include a versioned symbol `foo@R`. The stub library for S will
201contain both symbols, as well as the versioned symbols `foo@R` and `bar@R`.
202
203This tag is not commonly needed and is only used to hide symbol versioning
204mistakes that shipped as part of the platform.
205
206Note: Like `introduced`, the map file does not tell the whole story. The
207`ndk_library` Soong module may define a `unversioned_until` property that sets
208the default for the entire map file.
209
210### weak
211
212Indicates that the symbol should be [weak] in the stub library.
213
214[weak]: https://gcc.gnu.org/onlinedocs/gcc-4.7.2/gcc/Function-Attributes.html
215