build: make Zephyr stdint convention enforcing configurable

There are  few cases where removing this enforcement is desirable:

- linking against binary C++ libs with incompatible type mangling

- linking against system provided headers i.e. native_posix

- compiling with legacy code that assumes a different convention

So let's create a Kconfig symbol for it. This is IMHO a good compromize
compared to using the %"PRId32" abomination everywhere otherwise.

Signed-off-by: Nicolas Pitre <npitre@baylibre.com>
This commit is contained in:
Nicolas Pitre 2022-06-20 13:18:14 -04:00 committed by Carles Cufí
parent e06359f616
commit 0a386dbe6c
4 changed files with 38 additions and 4 deletions

View file

@ -283,10 +283,7 @@ zephyr_compile_options($<$<COMPILE_LANGUAGE:ASM>:$<TARGET_PROPERTY:asm,required>
# @Intent: Enforce standard integer type correspondence to match Zephyr usage.
# (must be after compiler specific flags)
if(NOT CONFIG_ARCH_POSIX)
# `zephyr_stdint.h` is not included for the POSIX (native) arch because it
# compiles with the host toolchain/headers and there can be conflicts if we
# arbitrarily redefine our own type system (see #37718).
if(CONFIG_ENFORCE_ZEPHYR_STDINT)
zephyr_compile_options("SHELL: $<TARGET_PROPERTY:compiler,imacros> ${ZEPHYR_BASE}/include/zephyr/toolchain/zephyr_stdint.h")
endif()

View file

@ -608,6 +608,22 @@ config WARN_EXPERIMENTAL
Print a warning when the Kconfig tree is parsed if any experimental
features are enabled.
config ENFORCE_ZEPHYR_STDINT
bool
prompt "Enforce Zephyr convention for stdint"
depends on !ARCH_POSIX
default y
help
This enforces the Zephyr stdint convention where int32_t = int,
int64_t = long long, and intptr_t = long so that short string
format length modifiers can be used universally across ILP32
and LP64 architectures. Sometimes this is not possible e.g. when
linking against a binary-only C++ library whose type mangling
is incompatible with the Zephyr convention, or if the build
environment doesn't allow such enforcement, in which case this
should be turned off with the caveat that argument type validation
on Zephyr code will be skipped.
endmenu

View file

@ -25,6 +25,14 @@
extern "C" {
#endif
/*
* Zephyr currently assumes the size of a couple standard types to simplify
* print string formats. Let's make sure this doesn't change without notice.
*/
BUILD_ASSERT(sizeof(int32_t) == sizeof(int));
BUILD_ASSERT(sizeof(int64_t) == sizeof(long long));
BUILD_ASSERT(sizeof(intptr_t) == sizeof(long));
/**
* @brief Kernel APIs
* @defgroup kernel_apis Kernel APIs

View file

@ -213,7 +213,20 @@ do { \
#define __may_alias __attribute__((__may_alias__))
#ifndef __printf_like
#ifdef CONFIG_ENFORCE_ZEPHYR_STDINT
#define __printf_like(f, a) __attribute__((format (printf, f, a)))
#else
/*
* The Zephyr stdint convention enforces int32_t = int, int64_t = long long,
* and intptr_t = long so that short string format length modifiers can be
* used universally across ILP32 and LP64 architectures. Without that it
* is possible for ILP32 toolchains to have int32_t = long and intptr_t = int
* clashing with the Zephyr convention and generating pointless warnings
* as they're still the same size. Inhibit the format argument type
* validation in that case and let the other configs do it.
*/
#define __printf_like(f, a)
#endif
#endif
#define __used __attribute__((__used__))