package: gcc-arm-none-eabi

Hi,

I can confirm this bug is still reproducible on current Ubuntu (26.04) with
a
newer toolchain. The same root cause documented here is hit by our CI build
of
an embedded firmware project (STM32 Cortex-M, libudpard/cyphal based)
whenever
the code uses the base-64-bit format macros from <inttypes.h>.

Environment:

   $ arm-none-eabi-gcc --version
   arm-none-eabi-gcc (15:14.2.rel1-1) 14.2.1 20241119

   $ grep PRETTY /etc/os-release
   PRETTY_NAME="Ubuntu 26.04 LTS"

Minimal reproducer (test.c):

   #include <stdint.h>
   #include <inttypes.h>
   #include <stdio.h>
   int main(void){ uint64_t x = 0x0123456789abcdefULL; printf("%016" PRIx64
"\n", x); return 0; }

Compile with the same flags we use for firmware:

   $ arm-none-eabi-gcc -std=c2x -Werror -mthumb -mcpu=cortex-m7 -c test.c
   test.c: In function 'main':
   test.c:4:66: error: expected ')' before 'PRIx64'
       4 | ... printf("%016" PRIx64 ...
         |                          ^~~~~~~
   test.c:4:1: note: 'PRIx64' is defined in header '<inttypes.h>'; this is
probably fixable by adding '#include <inttypes.h>'

(The compiler suggestion is misleading: PRIx64 IS defined in inttypes.h but
only conditionally.)

Root cause is exactly as described above: the header search picks up GCC's
own self-contained <stdint.h> ahead of the newlib one:

   $ arm-none-eabi-gcc -E -v -x c /dev/null 2>&1 | sed -n "/#include <...>
search/,/End of search list/p"
   /usr/lib/gcc/arm-none-eabi/14.2.1/include
   /usr/lib/gcc/arm-none-eabi/14.2.1/include-fixed
   /usr/lib/gcc/arm-none-eabi/14.2.1/../../../arm-none-eabi/include

so `#include <stdint.h>` resolves to
/usr/lib/gcc/arm-none-eabi/14.2.1/include/stdint.h (guarded by
`_GCC_STDINT_H`), which does not include_next <stdint.h>. newlib's
`sys/_stdint.h` (which defines `__int64_t_defined` at line 63) is therefore
never reached, and `/usr/include/newlib/inttypes.h` gates all the
PRI64/SCN64
macros behind `#if __int64_t_defined` at line 216, so none of them are
emitted.

Confirming the include resolution:

   $ printf "#include <stdint.h>\n" | arm-none-eabi-gcc -MM -H -x c -o
/dev/null -
   . /usr/lib/gcc/arm-none-eabi/14.2.1/include/stdint.h

Workaround, for other people hitting the same CI failure: we chain GCC's
stdint.h into newlib's by appending `#include_next <stdint.h>` to
$(arm-none-eabi-gcc -print-file-name=include/stdint.h), which restores the
behavior of the old wrapper and makes PRIx64/PRId64/PRIu64 all compile.

It would be great if the packaging could either restore the `#include_next
<stdint.h>` wrapper that Debian's `provide-stdint-for-embedded` used to
carry,
or coordinate with libnewlib so that `inttypes.h` does not depend on a macro
that only newlib's own <stdint.h> can define.

Thanks for the excellent analysis already in this bug; please let me know if
you need anything else reproduced.

*Erik Rainey*
[email protected]

Reply via email to