How can I use the GCC sysroot for ARM when using Clang?

Hi all!

I’m trying to use a built-from-source clang to compile some C code to bare metal ARM (a Cortex-M4). I’m using specifically this toolchain, but I think the principle should be the same. When compiling, I tried:

~/my/build/path/clang -c \
-mcpu=cortex-m4 -mthumb -mfpu=fpv4-sp-d16 \
-mfloat-abi=hard -target arm-none-eabi \
--sysroot=/usr/lib/gcc/arm-none-eabi/12.2.0 \
// some custom -D and -I definitions \
-Og -Wall -fdata-sections -ffunction-sections -g -gdwarf-2 \
-MMD -MP -MF"build/main.d" Core/Src/main.c -o build/main.o

but it gives me the error:

In file included from /home/alessandro/tesi/LLVM-embedded-toolchain-for-Arm/build/llvm/lib/clang/17/include/stdint.h:52:
/usr/lib/gcc/arm-none-eabi/12.2.0/include/stdint.h:9:16: fatal error: 'stdint.h' file not found
# include_next <stdint.h>
               ^~~~~~~~~~
1 error generated.

So an online search on SO explained the problem: it is missing the header, and it should search on the next dir in some order. Point is, how can I specify this order? Right now, on my host system (Arch), I have:

/usr/lib/gcc
.
├── arm-none-eabi
│   └── 12.2.0
│       ├── arm
│       ├── cc1
│       ├── cc1plus
│       ├── collect2
│       ├── crtbegin.o
│       ├── crtend.o
│       ├── crtfastmath.o
│       ├── crti.o
│       ├── crtn.o
│       ├── g++-mapper-server
│       ├── include
│       ├── include-fixed
│       ├── install-tools
│       ├── libgcc.a
│       ├── libgcov.a
│       ├── liblto_plugin.so
│       ├── lto1
│       ├── lto-wrapper
│       ├── plugin
│       └── thumb
└── x86_64-pc-linux-gnu
    └── 12.2.1
        ├── 32
        ├── cc1
        ├── cc1plus
        ├── collect2
        ├── crtbegin.o
        ├── crtbeginS.o
        ├── crtbeginT.o
        ├── crtend.o
        ├── crtendS.o
        ├── crtfastmath.o
        ├── crtprec32.o
        ├── crtprec64.o
        ├── crtprec80.o
        ├── f951
        ├── finclude
        ├── include
        ├── include-fixed
        ├── install-tools
        ├── libcaf_single.a
        ├── libgcc.a
        ├── libgcc_eh.a
        ├── libgcov.a
        ├── liblto_plugin.so
        ├── lto1
        ├── lto-wrapper
        └── plugin

I suppose using the headers of my host triple (x86_64-pc-linux-gnu) as fallback may solve the problem, since with GCC it works?

Thanks!

Looking at what my distro’s arm-none-eabi-gcc (9.2.1) include path is I get:

 /usr/lib/gcc/arm-none-eabi/9.2.1/include
 /usr/lib/gcc/arm-none-eabi/9.2.1/include-fixed
 /usr/lib/gcc/arm-none-eabi/9.2.1/../../../arm-none-eabi/include

If you have arm-none-eabi-gcc installed then compiling a test file with the -v option will print the search path.

With the last having considerably more headers than the former. It is likely the --sysroot will be insufficient and you’ll need to add additional -Isystem

I’d also be careful about the choice of sysroot. Clang does not (yet) support multilib so it is likely that the link step will fail because it can’t find the libraries.

In the LLVM embedded toolchain for Arm we’ve worked around this with Clang config files. It does mean that the sysroot needs to be directly above the include and lib directories for the target architecture. For example our matching config file has:

--sysroot <CFGDIR>/../lib/clang-runtimes/armv7em_hard_fpv4_sp_d16
<CFGDIR>/../lib/clang-runtimes/armv7em_hard_fpv4_sp_d16/lib/crt0.o

For the libraries I think you’ll need to use /usr/lib/arm-none-eabi/lib/thumb/v7e-m+fp/hard for the library probably with -L as there is no sysroot that will satisfy both includes and libraries in this case.

Apologies that is probably the best I can do. Will point this out to some colleagues to see if they have any suggestions.

I’ve seen this error before, and I think by adding “-resource-dir=/usr/lib/clang//include” might fix it. Note the path is to wherever you have the include directory installed.