xref: /dpdk/doc/guides/contributing/abi_versioning.rst (revision 98afdb15626841dd6580816678a6df63d12f22b9)
1ced6b2d1SRay Kinsella..  SPDX-License-Identifier: BSD-3-Clause
2ced6b2d1SRay Kinsella    Copyright 2018 The DPDK contributors
3ced6b2d1SRay Kinsella
4144beafcSRay Kinsella.. _abi_versioning:
5ced6b2d1SRay Kinsella
6144beafcSRay KinsellaABI Versioning
7144beafcSRay Kinsella==============
8144beafcSRay Kinsella
9144beafcSRay KinsellaThis document details the mechanics of ABI version management in DPDK.
10144beafcSRay Kinsella
11144beafcSRay Kinsella.. _what_is_soname:
12144beafcSRay Kinsella
13144beafcSRay KinsellaWhat is a library's soname?
14144beafcSRay Kinsella---------------------------
15144beafcSRay Kinsella
16144beafcSRay KinsellaSystem libraries usually adopt the familiar major and minor version naming
1723b4fd82SRay Kinsellaconvention, where major versions (e.g. ``librte_eal 21.x, 22.x``) are presumed
18144beafcSRay Kinsellato be ABI incompatible with each other and minor versions (e.g. ``librte_eal
1923b4fd82SRay Kinsella21.1, 21.2``) are presumed to be ABI compatible. A library's `soname
20144beafcSRay Kinsella<https://en.wikipedia.org/wiki/Soname>`_. is typically used to provide backward
21144beafcSRay Kinsellacompatibility information about a given library, describing the lowest common
22144beafcSRay Kinselladenominator ABI supported by the library. The soname or logical name for the
23144beafcSRay Kinsellalibrary, is typically comprised of the library's name and major version e.g.
2423b4fd82SRay Kinsella``librte_eal.so.21``.
25144beafcSRay Kinsella
26144beafcSRay KinsellaDuring an application's build process, a library's soname is noted as a runtime
27144beafcSRay Kinselladependency of the application. This information is then used by the `dynamic
28144beafcSRay Kinsellalinker <https://en.wikipedia.org/wiki/Dynamic_linker>`_ when resolving the
29144beafcSRay Kinsellaapplications dependencies at runtime, to load a library supporting the correct
30144beafcSRay KinsellaABI version. The library loaded at runtime therefore, may be a minor revision
3123b4fd82SRay Kinsellasupporting the same major ABI version (e.g. ``librte_eal.21.2``), as the library
3223b4fd82SRay Kinsellaused to link the application (e.g ``librte_eal.21.0``).
33144beafcSRay Kinsella
34144beafcSRay Kinsella.. _major_abi_versions:
35144beafcSRay Kinsella
36144beafcSRay KinsellaMajor ABI versions
37ced6b2d1SRay Kinsella------------------
38ced6b2d1SRay Kinsella
39144beafcSRay KinsellaAn ABI version change to a given library, especially in core libraries such as
40144beafcSRay Kinsella``librte_mbuf``, may cause an implicit ripple effect on the ABI of it's
41144beafcSRay Kinsellaconsuming libraries, causing ABI breakages. There may however be no explicit
42144beafcSRay Kinsellareason to bump a dependent library's ABI version, as there may have been no
43144beafcSRay Kinsellaobvious change to the dependent library's API, even though the library's ABI
44144beafcSRay Kinsellacompatibility will have been broken.
45ced6b2d1SRay Kinsella
46144beafcSRay KinsellaThis interdependence of DPDK libraries, means that ABI versioning of libraries
47144beafcSRay Kinsellais more manageable at a project level, with all project libraries sharing a
48144beafcSRay Kinsella**single ABI version**. In addition, the need to maintain a stable ABI for some
49144beafcSRay Kinsellanumber of releases as described in the section :doc:`abi_policy`, means
50144beafcSRay Kinsellathat ABI version increments need to carefully planned and managed at a project
51144beafcSRay Kinsellalevel.
52ced6b2d1SRay Kinsella
53144beafcSRay KinsellaMajor ABI versions are therefore declared typically aligned with an LTS release
54144beafcSRay Kinsellaand is then supported some number of subsequent releases, shared across all
55144beafcSRay Kinsellalibraries. This means that a single project level ABI version, reflected in all
56144beafcSRay Kinsellaindividual library's soname, library filenames and associated version maps
57144beafcSRay Kinsellapersists over multiple releases.
58ced6b2d1SRay Kinsella
59144beafcSRay Kinsella.. code-block:: none
60ced6b2d1SRay Kinsella
6199a2dd95SBruce Richardson $ head ./lib/acl/version.map
6223b4fd82SRay Kinsella DPDK_21 {
63144beafcSRay Kinsella        global:
64144beafcSRay Kinsella ...
65ced6b2d1SRay Kinsella
6699a2dd95SBruce Richardson $ head ./lib/eal/version.map
6723b4fd82SRay Kinsella DPDK_21 {
68144beafcSRay Kinsella        global:
69144beafcSRay Kinsella ...
70ced6b2d1SRay Kinsella
71144beafcSRay KinsellaWhen an ABI change is made between major ABI versions to a given library, a new
72144beafcSRay Kinsellasection is added to that library's version map describing the impending new ABI
73144beafcSRay Kinsellaversion, as described in the section :ref:`example_abi_macro_usage`. The
7423b4fd82SRay Kinsellalibrary's soname and filename however do not change, e.g. ``libacl.so.21``, as
75144beafcSRay KinsellaABI compatibility with the last major ABI version continues to be preserved for
76144beafcSRay Kinsellathat library.
77ced6b2d1SRay Kinsella
78144beafcSRay Kinsella.. code-block:: none
79144beafcSRay Kinsella
8099a2dd95SBruce Richardson $ head ./lib/acl/version.map
8123b4fd82SRay Kinsella DPDK_21 {
82144beafcSRay Kinsella        global:
83144beafcSRay Kinsella ...
84144beafcSRay Kinsella
8523b4fd82SRay Kinsella DPDK_22 {
86144beafcSRay Kinsella        global:
87144beafcSRay Kinsella
8823b4fd82SRay Kinsella } DPDK_21;
89144beafcSRay Kinsella ...
90144beafcSRay Kinsella
9199a2dd95SBruce Richardson $ head ./lib/eal/version.map
9223b4fd82SRay Kinsella DPDK_21 {
93144beafcSRay Kinsella        global:
94144beafcSRay Kinsella ...
95144beafcSRay Kinsella
9623b4fd82SRay KinsellaHowever when a new ABI version is declared, for example DPDK ``22``, old
97*98afdb15SStephen Colemandeprecated functions may be safely removed at this point and the entire old
98144beafcSRay Kinsellamajor ABI version removed, see the section :ref:`deprecating_entire_abi` on
99144beafcSRay Kinsellahow this may be done.
100144beafcSRay Kinsella
101144beafcSRay Kinsella.. code-block:: none
102144beafcSRay Kinsella
10399a2dd95SBruce Richardson $ head ./lib/acl/version.map
10423b4fd82SRay Kinsella DPDK_22 {
105144beafcSRay Kinsella        global:
106144beafcSRay Kinsella ...
107144beafcSRay Kinsella
10899a2dd95SBruce Richardson $ head ./lib/eal/version.map
10923b4fd82SRay Kinsella DPDK_22 {
110144beafcSRay Kinsella        global:
111144beafcSRay Kinsella ...
112144beafcSRay Kinsella
113144beafcSRay KinsellaAt the same time, the major ABI version is changed atomically across all
114cba806e0SMarcin Baranlibraries by incrementing the major version in the ABI_VERSION file. This is
1157762e013SDavid Marchanddone globally for all libraries.
116144beafcSRay Kinsella
117cba806e0SMarcin BaranMinor ABI versions
118cba806e0SMarcin Baran~~~~~~~~~~~~~~~~~~
119144beafcSRay Kinsella
120cba806e0SMarcin BaranEach non-LTS release will also increment minor ABI version, to permit multiple
121cba806e0SMarcin BaranDPDK versions being installed alongside each other. Both stable and
122cba806e0SMarcin Baranexperimental ABI's are versioned using the global version file that is updated
123cba806e0SMarcin Baranat the start of each release cycle, and are managed at the project level.
124ced6b2d1SRay Kinsella
125ced6b2d1SRay KinsellaVersioning Macros
126144beafcSRay Kinsella-----------------
127ced6b2d1SRay Kinsella
128ced6b2d1SRay KinsellaWhen a symbol is exported from a library to provide an API, it also provides a
129ced6b2d1SRay Kinsellacalling convention (ABI) that is embodied in its name, return type and
130ced6b2d1SRay Kinsellaarguments. Occasionally that function may need to change to accommodate new
131144beafcSRay Kinsellafunctionality or behavior. When that occurs, it is may be required to allow for
132ced6b2d1SRay Kinsellabackward compatibility for a time with older binaries that are dynamically
133ced6b2d1SRay Kinsellalinked to the DPDK.
134ced6b2d1SRay Kinsella
135ced6b2d1SRay KinsellaTo support backward compatibility the ``rte_function_versioning.h``
136ced6b2d1SRay Kinsellaheader file provides macros to use when updating exported functions. These
1376b3848e2SDavid Marchandmacros are used in conjunction with the ``version.map`` file for
138ced6b2d1SRay Kinsellaa given library to allow multiple versions of a symbol to exist in a shared
139ced6b2d1SRay Kinsellalibrary so that older binaries need not be immediately recompiled.
140ced6b2d1SRay Kinsella
141ced6b2d1SRay KinsellaThe macros exported are:
142ced6b2d1SRay Kinsella
143ced6b2d1SRay Kinsella* ``VERSION_SYMBOL(b, e, n)``: Creates a symbol version table entry binding
144ced6b2d1SRay Kinsella  versioned symbol ``b@DPDK_n`` to the internal function ``be``.
145ced6b2d1SRay Kinsella
146ced6b2d1SRay Kinsella* ``BIND_DEFAULT_SYMBOL(b, e, n)``: Creates a symbol version entry instructing
147ced6b2d1SRay Kinsella  the linker to bind references to symbol ``b`` to the internal symbol
148ced6b2d1SRay Kinsella  ``be``.
149ced6b2d1SRay Kinsella
150ced6b2d1SRay Kinsella* ``MAP_STATIC_SYMBOL(f, p)``: Declare the prototype ``f``, and map it to the
151ced6b2d1SRay Kinsella  fully qualified function ``p``, so that if a symbol becomes versioned, it
152ced6b2d1SRay Kinsella  can still be mapped back to the public symbol name.
153ced6b2d1SRay Kinsella
154ced6b2d1SRay Kinsella* ``__vsym``:  Annotation to be used in a declaration of the internal symbol
155ced6b2d1SRay Kinsella  ``be`` to signal that it is being used as an implementation of a particular
156ced6b2d1SRay Kinsella  version of symbol ``b``.
157ced6b2d1SRay Kinsella
15805a38d7cSFerruh Yigit* ``VERSION_SYMBOL_EXPERIMENTAL(b, e)``: Creates a symbol version table entry
15905a38d7cSFerruh Yigit  binding versioned symbol ``b@EXPERIMENTAL`` to the internal function ``be``.
16005a38d7cSFerruh Yigit  The macro is used when a symbol matures to become part of the stable ABI, to
16106df45afSRay Kinsella  provide an alias to experimental until the next major ABI version.
16205a38d7cSFerruh Yigit
163144beafcSRay Kinsella.. _example_abi_macro_usage:
164144beafcSRay Kinsella
165ced6b2d1SRay KinsellaExamples of ABI Macro use
166144beafcSRay Kinsella~~~~~~~~~~~~~~~~~~~~~~~~~
167ced6b2d1SRay Kinsella
168ced6b2d1SRay KinsellaUpdating a public API
169ced6b2d1SRay Kinsella_____________________
170ced6b2d1SRay Kinsella
171ced6b2d1SRay KinsellaAssume we have a function as follows
172ced6b2d1SRay Kinsella
173ced6b2d1SRay Kinsella.. code-block:: c
174ced6b2d1SRay Kinsella
175ced6b2d1SRay Kinsella /*
176ced6b2d1SRay Kinsella  * Create an acl context object for apps to
177ced6b2d1SRay Kinsella  * manipulate
178ced6b2d1SRay Kinsella  */
179ced6b2d1SRay Kinsella struct rte_acl_ctx *
180ced6b2d1SRay Kinsella rte_acl_create(const struct rte_acl_param *param)
181ced6b2d1SRay Kinsella {
182ced6b2d1SRay Kinsella        ...
183ced6b2d1SRay Kinsella }
184ced6b2d1SRay Kinsella
185ced6b2d1SRay Kinsella
186ced6b2d1SRay KinsellaAssume that struct rte_acl_ctx is a private structure, and that a developer
187ced6b2d1SRay Kinsellawishes to enhance the acl api so that a debugging flag can be enabled on a
188ced6b2d1SRay Kinsellaper-context basis.  This requires an addition to the structure (which, being
189ced6b2d1SRay Kinsellaprivate, is safe), but it also requires modifying the code as follows
190ced6b2d1SRay Kinsella
191ced6b2d1SRay Kinsella.. code-block:: c
192ced6b2d1SRay Kinsella
193ced6b2d1SRay Kinsella /*
194ced6b2d1SRay Kinsella  * Create an acl context object for apps to
195ced6b2d1SRay Kinsella  * manipulate
196ced6b2d1SRay Kinsella  */
197ced6b2d1SRay Kinsella struct rte_acl_ctx *
198ced6b2d1SRay Kinsella rte_acl_create(const struct rte_acl_param *param, int debug)
199ced6b2d1SRay Kinsella {
200ced6b2d1SRay Kinsella        ...
201ced6b2d1SRay Kinsella }
202ced6b2d1SRay Kinsella
203ced6b2d1SRay Kinsella
204ced6b2d1SRay KinsellaNote also that, being a public function, the header file prototype must also be
205ced6b2d1SRay Kinsellachanged, as must all the call sites, to reflect the new ABI footprint.  We will
206ced6b2d1SRay Kinsellamaintain previous ABI versions that are accessible only to previously compiled
20745a4103eSRay Kinsellabinaries.
208ced6b2d1SRay Kinsella
209ced6b2d1SRay KinsellaThe addition of a parameter to the function is ABI breaking as the function is
210ced6b2d1SRay Kinsellapublic, and existing application may use it in its current form. However, the
211ced6b2d1SRay Kinsellacompatibility macros in DPDK allow a developer to use symbol versioning so that
212ced6b2d1SRay Kinsellamultiple functions can be mapped to the same public symbol based on when an
213ced6b2d1SRay Kinsellaapplication was linked to it. To see how this is done, we start with the
214144beafcSRay Kinsellarequisite libraries version map file. Initially the version map file for the acl
215144beafcSRay Kinsellalibrary looks like this
216ced6b2d1SRay Kinsella
217ced6b2d1SRay Kinsella.. code-block:: none
218ced6b2d1SRay Kinsella
21923b4fd82SRay Kinsella   DPDK_21 {
220ced6b2d1SRay Kinsella        global:
221ced6b2d1SRay Kinsella
222ced6b2d1SRay Kinsella        rte_acl_add_rules;
223ced6b2d1SRay Kinsella        rte_acl_build;
224ced6b2d1SRay Kinsella        rte_acl_classify;
225ced6b2d1SRay Kinsella        rte_acl_classify_alg;
226ced6b2d1SRay Kinsella        rte_acl_classify_scalar;
227ced6b2d1SRay Kinsella        rte_acl_create;
228ced6b2d1SRay Kinsella        rte_acl_dump;
229ced6b2d1SRay Kinsella        rte_acl_find_existing;
230ced6b2d1SRay Kinsella        rte_acl_free;
231ced6b2d1SRay Kinsella        rte_acl_ipv4vlan_add_rules;
232ced6b2d1SRay Kinsella        rte_acl_ipv4vlan_build;
233ced6b2d1SRay Kinsella        rte_acl_list_dump;
234ced6b2d1SRay Kinsella        rte_acl_reset;
235ced6b2d1SRay Kinsella        rte_acl_reset_rules;
236ced6b2d1SRay Kinsella        rte_acl_set_ctx_classify;
237ced6b2d1SRay Kinsella
238ced6b2d1SRay Kinsella        local: *;
239ced6b2d1SRay Kinsella   };
240ced6b2d1SRay Kinsella
241ced6b2d1SRay KinsellaThis file needs to be modified as follows
242ced6b2d1SRay Kinsella
243ced6b2d1SRay Kinsella.. code-block:: none
244ced6b2d1SRay Kinsella
24523b4fd82SRay Kinsella   DPDK_21 {
246ced6b2d1SRay Kinsella        global:
247ced6b2d1SRay Kinsella
248ced6b2d1SRay Kinsella        rte_acl_add_rules;
249ced6b2d1SRay Kinsella        rte_acl_build;
250ced6b2d1SRay Kinsella        rte_acl_classify;
251ced6b2d1SRay Kinsella        rte_acl_classify_alg;
252ced6b2d1SRay Kinsella        rte_acl_classify_scalar;
253ced6b2d1SRay Kinsella        rte_acl_create;
254ced6b2d1SRay Kinsella        rte_acl_dump;
255ced6b2d1SRay Kinsella        rte_acl_find_existing;
256ced6b2d1SRay Kinsella        rte_acl_free;
257ced6b2d1SRay Kinsella        rte_acl_ipv4vlan_add_rules;
258ced6b2d1SRay Kinsella        rte_acl_ipv4vlan_build;
259ced6b2d1SRay Kinsella        rte_acl_list_dump;
260ced6b2d1SRay Kinsella        rte_acl_reset;
261ced6b2d1SRay Kinsella        rte_acl_reset_rules;
262ced6b2d1SRay Kinsella        rte_acl_set_ctx_classify;
263ced6b2d1SRay Kinsella
264ced6b2d1SRay Kinsella        local: *;
265ced6b2d1SRay Kinsella   };
266ced6b2d1SRay Kinsella
26723b4fd82SRay Kinsella   DPDK_22 {
268ced6b2d1SRay Kinsella        global:
269ced6b2d1SRay Kinsella        rte_acl_create;
270ced6b2d1SRay Kinsella
27123b4fd82SRay Kinsella   } DPDK_21;
272ced6b2d1SRay Kinsella
27345a4103eSRay KinsellaThe addition of the new block tells the linker that a new version node
27423b4fd82SRay Kinsella``DPDK_22`` is available, which contains the symbol rte_acl_create, and inherits
27523b4fd82SRay Kinsellathe symbols from the DPDK_21 node. This list is directly translated into a
27645a4103eSRay Kinsellalist of exported symbols when DPDK is compiled as a shared library.
277ced6b2d1SRay Kinsella
27845a4103eSRay KinsellaNext, we need to specify in the code which function maps to the rte_acl_create
279ced6b2d1SRay Kinsellasymbol at which versions.  First, at the site of the initial symbol definition,
280ced6b2d1SRay Kinsellawe need to update the function so that it is uniquely named, and not in conflict
281ced6b2d1SRay Kinsellawith the public symbol name
282ced6b2d1SRay Kinsella
283ced6b2d1SRay Kinsella.. code-block:: c
284ced6b2d1SRay Kinsella
285ced6b2d1SRay Kinsella -struct rte_acl_ctx *
286ced6b2d1SRay Kinsella -rte_acl_create(const struct rte_acl_param *param)
287ced6b2d1SRay Kinsella +struct rte_acl_ctx * __vsym
28823b4fd82SRay Kinsella +rte_acl_create_v21(const struct rte_acl_param *param)
289ced6b2d1SRay Kinsella {
290ced6b2d1SRay Kinsella        size_t sz;
291ced6b2d1SRay Kinsella        struct rte_acl_ctx *ctx;
292ced6b2d1SRay Kinsella        ...
293ced6b2d1SRay Kinsella
294ced6b2d1SRay KinsellaNote that the base name of the symbol was kept intact, as this is conducive to
29545a4103eSRay Kinsellathe macros used for versioning symbols and we have annotated the function as
29645a4103eSRay Kinsella``__vsym``, an implementation of a versioned symbol . That is our next step,
29723b4fd82SRay Kinsellamapping this new symbol name to the initial symbol name at version node 21.
29845a4103eSRay KinsellaImmediately after the function, we add the VERSION_SYMBOL macro.
299ced6b2d1SRay Kinsella
300ced6b2d1SRay Kinsella.. code-block:: c
301ced6b2d1SRay Kinsella
30245a4103eSRay Kinsella   #include <rte_function_versioning.h>
30345a4103eSRay Kinsella
30445a4103eSRay Kinsella   ...
30523b4fd82SRay Kinsella   VERSION_SYMBOL(rte_acl_create, _v21, 21);
306ced6b2d1SRay Kinsella
307144beafcSRay KinsellaRemembering to also add the rte_function_versioning.h header to the requisite c
30845a4103eSRay Kinsellafile where these changes are being made. The macro instructs the linker to
30923b4fd82SRay Kinsellacreate a new symbol ``rte_acl_create@DPDK_21``, which matches the symbol created
310144beafcSRay Kinsellain older builds, but now points to the above newly named function. We have now
311144beafcSRay Kinsellamapped the original rte_acl_create symbol to the original function (but with a
312144beafcSRay Kinsellanew name).
313ced6b2d1SRay Kinsella
31445a4103eSRay KinsellaPlease see the section :ref:`Enabling versioning macros
31545a4103eSRay Kinsella<enabling_versioning_macros>` to enable this macro in the meson/ninja build.
31623b4fd82SRay KinsellaNext, we need to create the new ``v22`` version of the symbol. We create a new
31723b4fd82SRay Kinsellafunction name, with the ``v22`` suffix, and implement it appropriately.
318ced6b2d1SRay Kinsella
319ced6b2d1SRay Kinsella.. code-block:: c
320ced6b2d1SRay Kinsella
321ced6b2d1SRay Kinsella   struct rte_acl_ctx * __vsym
32223b4fd82SRay Kinsella   rte_acl_create_v22(const struct rte_acl_param *param, int debug);
323ced6b2d1SRay Kinsella   {
32423b4fd82SRay Kinsella        struct rte_acl_ctx *ctx = rte_acl_create_v21(param);
325ced6b2d1SRay Kinsella
326ced6b2d1SRay Kinsella        ctx->debug = debug;
327ced6b2d1SRay Kinsella
328ced6b2d1SRay Kinsella        return ctx;
329ced6b2d1SRay Kinsella   }
330ced6b2d1SRay Kinsella
331144beafcSRay KinsellaThis code serves as our new API call. Its the same as our old call, but adds the
33245a4103eSRay Kinsellanew parameter in place. Next we need to map this function to the new default
33323b4fd82SRay Kinsellasymbol ``rte_acl_create@DPDK_22``. To do this, immediately after the function,
33445a4103eSRay Kinsellawe add the BIND_DEFAULT_SYMBOL macro.
33545a4103eSRay Kinsella
33645a4103eSRay Kinsella.. code-block:: c
33745a4103eSRay Kinsella
33845a4103eSRay Kinsella   #include <rte_function_versioning.h>
33945a4103eSRay Kinsella
34045a4103eSRay Kinsella   ...
34123b4fd82SRay Kinsella   BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22);
34245a4103eSRay Kinsella
34345a4103eSRay KinsellaThe macro instructs the linker to create the new default symbol
34423b4fd82SRay Kinsella``rte_acl_create@DPDK_22``, which points to the above newly named function.
34545a4103eSRay Kinsella
34645a4103eSRay KinsellaWe finally modify the prototype of the call in the public header file,
34745a4103eSRay Kinsellasuch that it contains both versions of the symbol and the public API.
348ced6b2d1SRay Kinsella
349ced6b2d1SRay Kinsella.. code-block:: c
350ced6b2d1SRay Kinsella
351ced6b2d1SRay Kinsella   struct rte_acl_ctx *
35245a4103eSRay Kinsella   rte_acl_create(const struct rte_acl_param *param);
353ced6b2d1SRay Kinsella
35445a4103eSRay Kinsella   struct rte_acl_ctx * __vsym
35523b4fd82SRay Kinsella   rte_acl_create_v21(const struct rte_acl_param *param);
356ced6b2d1SRay Kinsella
35745a4103eSRay Kinsella   struct rte_acl_ctx * __vsym
35823b4fd82SRay Kinsella   rte_acl_create_v22(const struct rte_acl_param *param, int debug);
35945a4103eSRay Kinsella
36045a4103eSRay Kinsella
36145a4103eSRay KinsellaAnd that's it, on the next shared library rebuild, there will be two versions of
36223b4fd82SRay Kinsellarte_acl_create, an old DPDK_21 version, used by previously built applications,
36323b4fd82SRay Kinsellaand a new DPDK_22 version, used by future built applications.
36445a4103eSRay Kinsella
36545a4103eSRay Kinsella.. note::
36645a4103eSRay Kinsella
36745a4103eSRay Kinsella   **Before you leave**, please take care reviewing the sections on
36845a4103eSRay Kinsella   :ref:`mapping static symbols <mapping_static_symbols>`,
36945a4103eSRay Kinsella   :ref:`enabling versioning macros <enabling_versioning_macros>`,
37045a4103eSRay Kinsella   and :ref:`ABI deprecation <abi_deprecation>`.
37145a4103eSRay Kinsella
37245a4103eSRay Kinsella
37345a4103eSRay Kinsella.. _mapping_static_symbols:
37445a4103eSRay Kinsella
37545a4103eSRay KinsellaMapping static symbols
37645a4103eSRay Kinsella______________________
37745a4103eSRay Kinsella
37845a4103eSRay KinsellaNow we've taken what was a public symbol, and duplicated it into two uniquely
37945a4103eSRay Kinsellaand differently named symbols. We've then mapped each of those back to the
38045a4103eSRay Kinsellapublic symbol ``rte_acl_create`` with different version tags. This only applies
38145a4103eSRay Kinsellato dynamic linking, as static linking has no notion of versioning. That leaves
38245a4103eSRay Kinsellathis code in a position of no longer having a symbol simply named
38345a4103eSRay Kinsella``rte_acl_create`` and a static build will fail on that missing symbol.
384ced6b2d1SRay Kinsella
385ced6b2d1SRay KinsellaTo correct this, we can simply map a function of our choosing back to the public
386ced6b2d1SRay Kinsellasymbol in the static build with the ``MAP_STATIC_SYMBOL`` macro.  Generally the
387ced6b2d1SRay Kinsellaassumption is that the most recent version of the symbol is the one you want to
38823b4fd82SRay Kinsellamap.  So, back in the C file where, immediately after ``rte_acl_create_v22`` is
389ced6b2d1SRay Kinselladefined, we add this
390ced6b2d1SRay Kinsella
391144beafcSRay Kinsella
392ced6b2d1SRay Kinsella.. code-block:: c
393ced6b2d1SRay Kinsella
394ced6b2d1SRay Kinsella   struct rte_acl_ctx * __vsym
39523b4fd82SRay Kinsella   rte_acl_create_v22(const struct rte_acl_param *param, int debug)
396ced6b2d1SRay Kinsella   {
397ced6b2d1SRay Kinsella        ...
398ced6b2d1SRay Kinsella   }
39923b4fd82SRay Kinsella   MAP_STATIC_SYMBOL(struct rte_acl_ctx *rte_acl_create(const struct rte_acl_param *param, int debug), rte_acl_create_v22);
400ced6b2d1SRay Kinsella
401ced6b2d1SRay KinsellaThat tells the compiler that, when building a static library, any calls to the
40223b4fd82SRay Kinsellasymbol ``rte_acl_create`` should be linked to ``rte_acl_create_v22``
403ced6b2d1SRay Kinsella
404ced6b2d1SRay Kinsella
40545a4103eSRay Kinsella.. _enabling_versioning_macros:
40645a4103eSRay Kinsella
40745a4103eSRay KinsellaEnabling versioning macros
40845a4103eSRay Kinsella__________________________
40945a4103eSRay Kinsella
41045a4103eSRay KinsellaFinally, we need to indicate to the :doc:`meson/ninja build system
41145a4103eSRay Kinsella<../prog_guide/build-sdk-meson>` to enable versioning macros when building the
41245a4103eSRay Kinsellalibrary or driver. In the libraries or driver where we have added symbol
41345a4103eSRay Kinsellaversioning, in the ``meson.build`` file we add the following
41445a4103eSRay Kinsella
415efdda86bSRaslan Darawsheh.. code-block:: none
41645a4103eSRay Kinsella
41745a4103eSRay Kinsella   use_function_versioning = true
41845a4103eSRay Kinsella
41945a4103eSRay Kinsellaat the start of the head of the file. This will indicate to the tool-chain to
42070d2f421SThomas Monjalonenable the function version macros when building.
42145a4103eSRay Kinsella
42205a38d7cSFerruh Yigit
42305a38d7cSFerruh Yigit.. _aliasing_experimental_symbols:
42405a38d7cSFerruh Yigit
42505a38d7cSFerruh YigitAliasing experimental symbols
42605a38d7cSFerruh Yigit_____________________________
42705a38d7cSFerruh Yigit
42805a38d7cSFerruh YigitIn situations in which an ``experimental`` symbol has been stable for some time,
42905a38d7cSFerruh Yigitand it becomes a candidate for promotion to the stable ABI. At this time, when
43006df45afSRay Kinsellapromoting the symbol, the maintainer may choose to provide an alias to the
43105a38d7cSFerruh Yigit``experimental`` symbol version, so as not to break consuming applications.
43206df45afSRay KinsellaThis alias is then dropped in the next major ABI version.
43305a38d7cSFerruh Yigit
43405a38d7cSFerruh YigitThe process to provide an alias to ``experimental`` is similar to that, of
43505a38d7cSFerruh Yigit:ref:`symbol versioning <example_abi_macro_usage>` described above.
43605a38d7cSFerruh YigitAssume we have an experimental function ``rte_acl_create`` as follows:
43705a38d7cSFerruh Yigit
43805a38d7cSFerruh Yigit.. code-block:: c
43905a38d7cSFerruh Yigit
44005a38d7cSFerruh Yigit   #include <rte_compat.h>
44105a38d7cSFerruh Yigit
44205a38d7cSFerruh Yigit   /*
44305a38d7cSFerruh Yigit    * Create an acl context object for apps to
44405a38d7cSFerruh Yigit    * manipulate
44505a38d7cSFerruh Yigit    */
44605a38d7cSFerruh Yigit   __rte_experimental
44705a38d7cSFerruh Yigit   struct rte_acl_ctx *
44805a38d7cSFerruh Yigit   rte_acl_create(const struct rte_acl_param *param)
44905a38d7cSFerruh Yigit   {
45005a38d7cSFerruh Yigit   ...
45105a38d7cSFerruh Yigit   }
45205a38d7cSFerruh Yigit
45305a38d7cSFerruh YigitIn the map file, experimental symbols are listed as part of the ``EXPERIMENTAL``
45405a38d7cSFerruh Yigitversion node.
45505a38d7cSFerruh Yigit
45605a38d7cSFerruh Yigit.. code-block:: none
45705a38d7cSFerruh Yigit
45823b4fd82SRay Kinsella   DPDK_21 {
45905a38d7cSFerruh Yigit        global:
46005a38d7cSFerruh Yigit        ...
46105a38d7cSFerruh Yigit
46205a38d7cSFerruh Yigit        local: *;
46305a38d7cSFerruh Yigit   };
46405a38d7cSFerruh Yigit
46505a38d7cSFerruh Yigit   EXPERIMENTAL {
46605a38d7cSFerruh Yigit        global:
46705a38d7cSFerruh Yigit
46805a38d7cSFerruh Yigit        rte_acl_create;
46905a38d7cSFerruh Yigit   };
47005a38d7cSFerruh Yigit
47105a38d7cSFerruh YigitWhen we promote the symbol to the stable ABI, we simply strip the
47205a38d7cSFerruh Yigit``__rte_experimental`` annotation from the function and move the symbol from the
47305a38d7cSFerruh Yigit``EXPERIMENTAL`` node, to the node of the next major ABI version as follow.
47405a38d7cSFerruh Yigit
47505a38d7cSFerruh Yigit.. code-block:: c
47605a38d7cSFerruh Yigit
47705a38d7cSFerruh Yigit   /*
47805a38d7cSFerruh Yigit    * Create an acl context object for apps to
47905a38d7cSFerruh Yigit    * manipulate
48005a38d7cSFerruh Yigit    */
48105a38d7cSFerruh Yigit   struct rte_acl_ctx *
48205a38d7cSFerruh Yigit   rte_acl_create(const struct rte_acl_param *param)
48305a38d7cSFerruh Yigit   {
48405a38d7cSFerruh Yigit          ...
48505a38d7cSFerruh Yigit   }
48605a38d7cSFerruh Yigit
48705a38d7cSFerruh YigitWe then update the map file, adding the symbol ``rte_acl_create``
48823b4fd82SRay Kinsellato the ``DPDK_22`` version node.
48905a38d7cSFerruh Yigit
49005a38d7cSFerruh Yigit.. code-block:: none
49105a38d7cSFerruh Yigit
49223b4fd82SRay Kinsella   DPDK_21 {
49305a38d7cSFerruh Yigit        global:
49405a38d7cSFerruh Yigit        ...
49505a38d7cSFerruh Yigit
49605a38d7cSFerruh Yigit        local: *;
49705a38d7cSFerruh Yigit   };
49805a38d7cSFerruh Yigit
49923b4fd82SRay Kinsella   DPDK_22 {
50005a38d7cSFerruh Yigit        global:
50105a38d7cSFerruh Yigit
50205a38d7cSFerruh Yigit        rte_acl_create;
50323b4fd82SRay Kinsella   } DPDK_21;
50405a38d7cSFerruh Yigit
50505a38d7cSFerruh Yigit
50605a38d7cSFerruh YigitAlthough there are strictly no guarantees or commitments associated with
50705a38d7cSFerruh Yigit:ref:`experimental symbols <experimental_apis>`, a maintainer may wish to offer
50805a38d7cSFerruh Yigitan alias to experimental. The process to add an alias to experimental,
50905a38d7cSFerruh Yigitis similar to the symbol versioning process. Assuming we have an experimental
51005a38d7cSFerruh Yigitsymbol as before, we now add the symbol to both the ``EXPERIMENTAL``
51123b4fd82SRay Kinsellaand ``DPDK_22`` version nodes.
51205a38d7cSFerruh Yigit
51305a38d7cSFerruh Yigit.. code-block:: c
51405a38d7cSFerruh Yigit
51505a38d7cSFerruh Yigit   #include <rte_compat.h>;
51605a38d7cSFerruh Yigit   #include <rte_function_versioning.h>
51705a38d7cSFerruh Yigit
51805a38d7cSFerruh Yigit   /*
51905a38d7cSFerruh Yigit    * Create an acl context object for apps to
52005a38d7cSFerruh Yigit    * manipulate
52105a38d7cSFerruh Yigit    */
52205a38d7cSFerruh Yigit   struct rte_acl_ctx *
52305a38d7cSFerruh Yigit   rte_acl_create(const struct rte_acl_param *param)
52405a38d7cSFerruh Yigit   {
52505a38d7cSFerruh Yigit   ...
52605a38d7cSFerruh Yigit   }
52705a38d7cSFerruh Yigit
52805a38d7cSFerruh Yigit   __rte_experimental
52905a38d7cSFerruh Yigit   struct rte_acl_ctx *
53005a38d7cSFerruh Yigit   rte_acl_create_e(const struct rte_acl_param *param)
53105a38d7cSFerruh Yigit   {
53205a38d7cSFerruh Yigit      return rte_acl_create(param);
53305a38d7cSFerruh Yigit   }
53405a38d7cSFerruh Yigit   VERSION_SYMBOL_EXPERIMENTAL(rte_acl_create, _e);
53505a38d7cSFerruh Yigit
53605a38d7cSFerruh Yigit   struct rte_acl_ctx *
53723b4fd82SRay Kinsella   rte_acl_create_v22(const struct rte_acl_param *param)
53805a38d7cSFerruh Yigit   {
53905a38d7cSFerruh Yigit      return rte_acl_create(param);
54005a38d7cSFerruh Yigit   }
54123b4fd82SRay Kinsella   BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22);
54205a38d7cSFerruh Yigit
54305a38d7cSFerruh YigitIn the map file, we map the symbol to both the ``EXPERIMENTAL``
54423b4fd82SRay Kinsellaand ``DPDK_22`` version nodes.
54505a38d7cSFerruh Yigit
54605a38d7cSFerruh Yigit.. code-block:: none
54705a38d7cSFerruh Yigit
54823b4fd82SRay Kinsella   DPDK_21 {
54905a38d7cSFerruh Yigit        global:
55005a38d7cSFerruh Yigit        ...
55105a38d7cSFerruh Yigit
55205a38d7cSFerruh Yigit        local: *;
55305a38d7cSFerruh Yigit   };
55405a38d7cSFerruh Yigit
55523b4fd82SRay Kinsella   DPDK_22 {
55605a38d7cSFerruh Yigit        global:
55705a38d7cSFerruh Yigit
55805a38d7cSFerruh Yigit        rte_acl_create;
55923b4fd82SRay Kinsella   } DPDK_21;
56005a38d7cSFerruh Yigit
56105a38d7cSFerruh Yigit   EXPERIMENTAL {
56205a38d7cSFerruh Yigit        global:
56305a38d7cSFerruh Yigit
56405a38d7cSFerruh Yigit        rte_acl_create;
56505a38d7cSFerruh Yigit   };
56605a38d7cSFerruh Yigit
56705a38d7cSFerruh Yigit.. note::
56805a38d7cSFerruh Yigit
56905a38d7cSFerruh Yigit   Please note, similar to :ref:`symbol versioning <example_abi_macro_usage>`,
57005a38d7cSFerruh Yigit   when aliasing to experimental you will also need to take care of
57105a38d7cSFerruh Yigit   :ref:`mapping static symbols <mapping_static_symbols>`.
57205a38d7cSFerruh Yigit
57305a38d7cSFerruh Yigit
57445a4103eSRay Kinsella.. _abi_deprecation:
575ced6b2d1SRay Kinsella
576ced6b2d1SRay KinsellaDeprecating part of a public API
577ced6b2d1SRay Kinsella________________________________
578ced6b2d1SRay Kinsella
57945a4103eSRay KinsellaLets assume that you've done the above updates, and in preparation for the next
580144beafcSRay Kinsellamajor ABI version you decide you would like to retire the old version of the
581144beafcSRay Kinsellafunction. After having gone through the ABI deprecation announcement process,
582144beafcSRay Kinsellaremoval is easy. Start by removing the symbol from the requisite version map
583144beafcSRay Kinsellafile:
584ced6b2d1SRay Kinsella
585ced6b2d1SRay Kinsella.. code-block:: none
586ced6b2d1SRay Kinsella
58723b4fd82SRay Kinsella   DPDK_21 {
588ced6b2d1SRay Kinsella        global:
589ced6b2d1SRay Kinsella
590ced6b2d1SRay Kinsella        rte_acl_add_rules;
591ced6b2d1SRay Kinsella        rte_acl_build;
592ced6b2d1SRay Kinsella        rte_acl_classify;
593ced6b2d1SRay Kinsella        rte_acl_classify_alg;
594ced6b2d1SRay Kinsella        rte_acl_classify_scalar;
595ced6b2d1SRay Kinsella        rte_acl_dump;
596ced6b2d1SRay Kinsella -      rte_acl_create
597ced6b2d1SRay Kinsella        rte_acl_find_existing;
598ced6b2d1SRay Kinsella        rte_acl_free;
599ced6b2d1SRay Kinsella        rte_acl_ipv4vlan_add_rules;
600ced6b2d1SRay Kinsella        rte_acl_ipv4vlan_build;
601ced6b2d1SRay Kinsella        rte_acl_list_dump;
602ced6b2d1SRay Kinsella        rte_acl_reset;
603ced6b2d1SRay Kinsella        rte_acl_reset_rules;
604ced6b2d1SRay Kinsella        rte_acl_set_ctx_classify;
605ced6b2d1SRay Kinsella
606ced6b2d1SRay Kinsella        local: *;
607ced6b2d1SRay Kinsella   };
608ced6b2d1SRay Kinsella
60923b4fd82SRay Kinsella   DPDK_22 {
610ced6b2d1SRay Kinsella        global:
611ced6b2d1SRay Kinsella        rte_acl_create;
61223b4fd82SRay Kinsella   } DPDK_21;
613ced6b2d1SRay Kinsella
614ced6b2d1SRay Kinsella
615ced6b2d1SRay KinsellaNext remove the corresponding versioned export.
616ced6b2d1SRay Kinsella
617ced6b2d1SRay Kinsella.. code-block:: c
618ced6b2d1SRay Kinsella
61923b4fd82SRay Kinsella -VERSION_SYMBOL(rte_acl_create, _v21, 21);
620ced6b2d1SRay Kinsella
621ced6b2d1SRay Kinsella
622ced6b2d1SRay KinsellaNote that the internal function definition could also be removed, but its used
62323b4fd82SRay Kinsellain our example by the newer version ``v22``, so we leave it in place and declare
62445a4103eSRay Kinsellait as static. This is a coding style choice.
625ced6b2d1SRay Kinsella
626144beafcSRay Kinsella.. _deprecating_entire_abi:
627ced6b2d1SRay Kinsella
628ced6b2d1SRay KinsellaDeprecating an entire ABI version
629ced6b2d1SRay Kinsella_________________________________
630ced6b2d1SRay Kinsella
631144beafcSRay KinsellaWhile removing a symbol from an ABI may be useful, it is more practical to
632144beafcSRay Kinsellaremove an entire version node at once, as is typically done at the declaration
633144beafcSRay Kinsellaof a major ABI version. If a version node completely specifies an API, then
634144beafcSRay Kinsellaremoving part of it, typically makes it incomplete. In those cases it is better
635144beafcSRay Kinsellato remove the entire node.
636ced6b2d1SRay Kinsella
637ced6b2d1SRay KinsellaTo do this, start by modifying the version map file, such that all symbols from
638144beafcSRay Kinsellathe node to be removed are merged into the next node in the map.
639ced6b2d1SRay Kinsella
640ced6b2d1SRay KinsellaIn the case of our map above, it would transform to look as follows
641ced6b2d1SRay Kinsella
642ced6b2d1SRay Kinsella.. code-block:: none
643ced6b2d1SRay Kinsella
64423b4fd82SRay Kinsella   DPDK_22 {
645ced6b2d1SRay Kinsella        global:
646ced6b2d1SRay Kinsella
647ced6b2d1SRay Kinsella        rte_acl_add_rules;
648ced6b2d1SRay Kinsella        rte_acl_build;
649ced6b2d1SRay Kinsella        rte_acl_classify;
650ced6b2d1SRay Kinsella        rte_acl_classify_alg;
651ced6b2d1SRay Kinsella        rte_acl_classify_scalar;
652ced6b2d1SRay Kinsella        rte_acl_dump;
653ced6b2d1SRay Kinsella        rte_acl_create
654ced6b2d1SRay Kinsella        rte_acl_find_existing;
655ced6b2d1SRay Kinsella        rte_acl_free;
656ced6b2d1SRay Kinsella        rte_acl_ipv4vlan_add_rules;
657ced6b2d1SRay Kinsella        rte_acl_ipv4vlan_build;
658ced6b2d1SRay Kinsella        rte_acl_list_dump;
659ced6b2d1SRay Kinsella        rte_acl_reset;
660ced6b2d1SRay Kinsella        rte_acl_reset_rules;
661ced6b2d1SRay Kinsella        rte_acl_set_ctx_classify;
662ced6b2d1SRay Kinsella
663ced6b2d1SRay Kinsella        local: *;
664ced6b2d1SRay Kinsella };
665ced6b2d1SRay Kinsella
666ced6b2d1SRay KinsellaThen any uses of BIND_DEFAULT_SYMBOL that pointed to the old node should be
667ced6b2d1SRay Kinsellaupdated to point to the new version node in any header files for all affected
668ced6b2d1SRay Kinsellasymbols.
669ced6b2d1SRay Kinsella
670ced6b2d1SRay Kinsella.. code-block:: c
671ced6b2d1SRay Kinsella
67223b4fd82SRay Kinsella -BIND_DEFAULT_SYMBOL(rte_acl_create, _v21, 21);
67323b4fd82SRay Kinsella +BIND_DEFAULT_SYMBOL(rte_acl_create, _v22, 22);
674ced6b2d1SRay Kinsella
6753eecaba9SRay KinsellaLastly, any VERSION_SYMBOL macros that point to the old version nodes
6763eecaba9SRay Kinsellashould be removed, taking care to preserve any code that is shared
6773eecaba9SRay Kinsellawith the new version node.
678ced6b2d1SRay Kinsella
679ced6b2d1SRay Kinsella
680ced6b2d1SRay KinsellaRunning the ABI Validator
681ced6b2d1SRay Kinsella-------------------------
682ced6b2d1SRay Kinsella
683ced6b2d1SRay KinsellaThe ``devtools`` directory in the DPDK source tree contains a utility program,
68467354349SNeil Horman``check-abi.sh``, for validating the DPDK ABI based on the libabigail
68567354349SNeil Horman`abidiff utility <https://sourceware.org/libabigail/manual/abidiff.html>`_.
686ced6b2d1SRay Kinsella
68767354349SNeil HormanThe syntax of the ``check-abi.sh`` utility is::
688ced6b2d1SRay Kinsella
68967354349SNeil Horman   devtools/check-abi.sh <refdir> <newdir>
690ced6b2d1SRay Kinsella
69167354349SNeil HormanWhere <refdir> specifies the directory housing the reference build of DPDK,
69267354349SNeil Hormanand <newdir> specifies the DPDK build directory to check the ABI of.
693ced6b2d1SRay Kinsella
69467354349SNeil HormanThe ABI compatibility is automatically verified when using a build script
69567354349SNeil Hormanfrom ``devtools``, if the variable ``DPDK_ABI_REF_VERSION`` is set with a tag,
69667354349SNeil Hormanas described in :ref:`ABI check recommendations<integrated_abi_check>`.
697