# Migrate from Libnative 21.0 and prior
Important
The Libnative application programming interface has changed substantially.
Read this chapter before upgrading!
Libnative 23.0 is the first Libnative version to support multiple architectures
simultaneously. It is strongly advised that users currently using old versions of
Libnative – especially older toolchain releases which no longer receive active
support – upgrade.
## Summary of breaking changes
| Change | Action required | Reference |
| --- | --- | --- |
| A C++ compiler is required to include the intrinsic headers. | Compile intrinsic-calling translation units as C++, or use the deprecated
C header. | [Build C sources as C++](https://docs.qualcomm.com/doc/80-N3040-23/topic/libnative-ug-migration.html#libnative-migration-cpp) |
| On Linux x86, SLES12 machines must use a separate library | Replace references to `lib/libnative.a` with `lib/sles12/libnative.a` on
affected SLES12 machines. | [SLES12 Support Deprecated](https://docs.qualcomm.com/doc/80-N3040-23/topic/libnative-ug-migration.html#libnative-sles12) |
| Headers no longer implicitly include `hexagon_types.h` | Include `hexagon_types.h` above any references to `hexagon_protos.h` or
`*_hexagon_protos.h`. | [Removed Headers](https://docs.qualcomm.com/doc/80-N3040-23/topic/libnative-ug-migration.html#libnative-migration-headers) |
| Vector inputs are passed by `const` reference. | Usually none. Fix code that took the address of an intrinsic or assumed
by-value parameters. | [Adjust for by-reference operands](https://docs.qualcomm.com/doc/80-N3040-23/topic/libnative-ug-migration.html#libnative-migration-by-reference) |
| Architecture version is selected at run time, not by choosing a build. | Set `arch` in configuration instead of picking a tools release. | [Stop selecting the architecture by tools release](https://docs.qualcomm.com/doc/80-N3040-23/topic/libnative-ug-migration.html#libnative-migration-arch) |
| Configuration is by TOML; several configuration functions are deprecated
or now abort. | Replace the old calls with `libnative_configure()`. | [Replace configuration calls](https://docs.qualcomm.com/doc/80-N3040-23/topic/libnative-ug-migration.html#libnative-migration-config) |
## Build C sources as C++
Using the C++ `*_hexagon_protos.h` files should require no modification if you
are already using C++. If you are using C, your code which calls intrinsics will
need to be made compatible with C++. The C++ intrinsics make use of constant
references and other C++ features which are incompatible with C.
To assist with migration where necessary, C-compatible intrinsics are provided in
`c_hexagon_protos.h`. This header will be removed in 25.0. To use it, remove
references to the other `*_hexagon_protos.h` files and replace them with a
single reference to `c_hexagon_protos.h`, which contains intrinsics for scalar
as well as all extensions, such as HVX. More information is provided in the
[Build C sources as C++](https://docs.qualcomm.com/doc/80-N3040-23/topic/libnative-ug-migration.html#libnative-c-compatibility) section.
Common snags when recompiling C as C++:
- Implicit conversions that C allowed – notably from `void*` – now need an
explicit cast.
- Designated or compound initializers used on vector types may need rewriting.
## SLES12 Support Deprecated
Machines running SLES12 have very old versions of glibc and the C++ standard
library. Libnative requires newer versions with support for C++17, which do not
come with the host toolchain included in SLES12. Users on SLES12 should migrate
to a newer toolchain to maintain compatibility with Libnative.
To assist with migration, in version 23.0, we have included a separate SLES12
compatible version of libnative.a. To use it, replace references to `lib/libnative.a`
with `lib/sles12/libnative.a`. The include and share directories should remain the
same. This version of Libnative is built against an older glibc for compatibility,
and comes bundled with libc++, libc++abi, and libunwind.
Important
Because this version of Libnative includes C++ standard library symbols, users
must not link against it themselves, including libstdc++, which is done by
default on some compilers!
Important
On GCC 4.8, the default SLES12 host compiler, users must specify `-std=c++11`,
which is not the default of `-std=c++98`. Newer toolchains should use C++17 when
supported, and ideally avoid using the SLES12-compatible libnative.a, favoring
the normal library.
## Removed Headers
Libnative 21.0 included multiple headers which are no longer required for 23.0 and
have been removed:
- `arch/arch_types.h`
- `arch/max.h`
- `arch/xlate_info.h`
- `arch_options_calc.h`
- `extif.h`
- `hexagon_circ_brev_intrinsics.h`
- `hlx.h`
- `hvx.h`
- `thread_t.h`
- `utils/global_types.h`
These headers were all previously used internally for Libnative and are not necessary
for any function or intrinsic defined in the Libnative API. They should not be referenced.
Libnative 21.0 also implicitly included `hexagon_types.h` as a part of `hexagon_protos.h`
and similar feature-specific `*_hexagon_protos.h` files. This was removed in 23.0 to
better match other Hexagon tools. If you are not doing so already, include `hexagon_types.h`
above any reference to `hexagon_protos.h` or other headers.
## Adjust for by-reference operands
In most code this needs no change, because passing a value to a `const`
reference parameter is source-compatible.
Be advised that the following may require attention:
- Taking the address of an intrinsic.
- Storing an intrinsic in a function pointer.
- Wrapping an intrinsic in a macro or template that assumed by-value parameters.
## Replace configuration calls
The new TOML configuration has led to the deprecation or removal of some existing
Libnative configuration methods.
| Old function | Replacement | Behavior in 23.0 |
| --- | --- | --- |
| `enable_qfloat_strict_ieee_mode()` | `libnative_configure("[general]\nstrict_ieee = true")` | **Deprecated.** Still works; forwards to the configuration setting. |
| `disable_qfloat_strict_ieee_mode()` | `libnative_configure("[general]\nstrict_ieee = false")` | **Deprecated.** Still works; forwards to the configuration setting. |
| `libnative_use_hmx_v1()` | None; no longer required for any use. | **Removed.** Prints a diagnostic and aborts. |
| `libnative_use_hmx_v2()` | None; no longer required for any use. | **Removed.** Prints a diagnostic and aborts. |
| `libnative_config_hmx()` | `libnative_configure()` with an `[hmx_arch_proc_options]` block. | **Removed.** Prints a diagnostic and aborts. |
The defaults for the parameters which were previously set in
`libnative_config_hmx()` can be found in `defaults.toml`, which is provided
with the Libnative release.
## Replace the old TLS configuration
Configuring TLS state with `libnative_tls.conf` has been removed. TLS should, as all
other settings are, be controlled with `libnative_configure()` or
`libnative.toml`:
[general]
use_tls = false
Copy to clipboard
The `LIBNATIVE_CONFIG` environment variable is also no longer supported.
Note
Neither mechanism fails quietly. Attempting to use the old interfaces for
TLS control will cause an assertion, to prevent silent failures.
## Stop selecting the architecture by tools release
Previously a given library build supported exactly one architecture version, and
using a different version meant using a different tools release.
This is no longer necessary. One library serves every supported version; set the
version in configuration instead:
[general]
arch = 89
Copy to clipboard
See [Selecting the version](https://docs.qualcomm.com/doc/80-N3040-23/topic/libnative-ug-architecture-versions.html#libnative-arch-selecting).
Last Published: Oct 06, 2026
[Previous Topic
Emulation model](https://docs.qualcomm.com/bundle/publicresource/80-N3040-23/topics/libnative-ug-overview.md) [Next Topic
Build and link an application](https://docs.qualcomm.com/bundle/publicresource/80-N3040-23/topics/libnative-ug-build-and-link.md)