Compiling for baremetal ARMv4 on Ubuntu Linux

I am currently trying to compile a pretty simple program to work on an experimental board. It contains an (FPGA-version of) an ARMv4 processor.
So basically, I try this (on my Ubuntu 18.04.1 LTS):
clang -v --target=arm-none-eabi -c barehello.c -o barehelloCLANG.o
clang -v --target=arm-none-eabi -c io.c -o io.o
clang -v --target=arm-none-eabi barehelloCLANG.o io.o -o helloCLANGstatic -static -fuse-ld=lld

Which results in

clang version 8.0.0 (https://git.llvm.org/git/clang.git/ a152c7a4b7ba8f4cb9532ead9a38a7121db43d50) (https://git.llvm.org/git/llvm.git/ 1959ce6f3e01241919968ac1911fd45660239d23)
Target: arm-none-unknown-eabi
Thread model: posix
InstalledDir: /usr/local/my_clang/bin
  "/usr/local/my_clang/bin/ld.lld" barehelloCLANG.o io.o -Bstatic -L/usr/local/my_clang/lib/clang/8.0.0/lib/baremetal -lc -lm -lclang_rt.builtins-arm.a -o helloCLANGstatic
ld.lld: error: unable to find library -lc
ld.lld: error: unable to find library -lm
ld.lld: error: unable to find library -lclang_rt.builtins-arm.a
clang-8: error: ld.lld command failed with exit code 1 (use -v to see invocation)

on the linking part. I downloaded a sysroot from https://developer.arm.com/open-source/gnu-toolchain/gnu-a/downloads/8-2-2018-08 and tried to include it via --sysroot=/my/path/to/it, but clang acted unimpressed with the same errors. So I'm missing clang_rt.builtins-arm.a I guess, but that does not exist on my system.
So next, I tried basically every version of "how to cross-compile llvm/clang/compiler-rt" That google came up with, but was not able to get a single one to actually work. Any ideas how to get this running?
Thanks in advance!

Hello,

Just a few quick observations.

  • It looks like you may have downloaded the linux arm toolchain. For bare metal you probably wanted the Arm embedded toolchain, https://developer.arm.com/open-source/gnu-toolchain/gnu-rm
    – That toolchain will have newlib rather than glibc, I don’t know whether it will have one pre-compiled for v4 though. If not you may have to find an older toolchain or build newlib youtself.
  • The bare-metal driver in clang (arm-none-eabi) is not multilib aware and won’t put the paths to the libraries on the link line, the -L flag
    – I have found that following the samples in the gnu embedded toolchain with gcc using the -v flag to get the paths it is using, then use these with lld.

If you can let us know what problems you are seeing building compiler-rt then we may be able to help. I’m not sure there is anyone building it for arm v4 so you may be hitting new problems. I’m away at a conference today and tomorrow but I can try later in the week.

Peter

Hello,

on the problems cross-building compiler-rt: Tried to follow which lead to this cmake:

cmake -G “Ninja” … -DCOMPILER_RT_BUILD_BUILTINS=ON -DCOMPILER_RT_BUILD_SANITIZERS=OFF -DCOMPILER_RT_BUILD_XRAY=OFF -DCOMPILER_RT_BUILD_LIBFUZZER=OFF -DCOMPILER_RT_BUILD_PROFILE=OFF -DCMAKE_C_COMPILER=/usr/local/myclang/bin/clang -DCMAKE_AR=/usr/local/myclang/bin/llvm-ar -DCMAKE_NM=/usr/local/myclang/bin/llvm-nm -DCMAKE_RANLIB=/usr/local/myclang/bin/llvm-ranlib -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_C_COMPILER_TARGET=“arm-linux-gnueabihf” -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DLLVM_CONFIG_PATH=/usr/local/myclang/bin/llvm-config -DCMAKE_C_FLAGS=“–target=arm-linux-gnueabihf -march=armv7a --gcc-toolchain=/usr/arm-linux-gnueabihf --sysroot=/usr/arm-linux-gnueabihf/lib”

Some small notes:

  • Used -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY instead of -DCMAKE_EXE_LINKER_FLAGS=“-fuse-ld=lld” as Peter Smith suggested because it actually is a library and therefore does not need to be linked. If I do not change that, the cmake does not work (see below).

  • used -G “Ninja” although not explicitly stated in the tutorial as they use “ninja builtins” next.

  • had to change --march=armv7a to -march=armv7a as clang did not accept the first one.

the cmake was successful, but the ninja builtins was not (see both outputs below). Am I doing the --gcc-toolchain / --sysroot part right? These are just the places where the result of “apt install arm-linux-gnueabihf” lives.

cmake output with -DCMAKE_EXE_LINKER_FLAGS=“-fuse-ld=lld”:

Hello Christian,

I've put some comments inline

Hello,

on the problems cross-building compiler-rt: Tried to follow How to Cross Compile Compiler-rt Builtins For Arm — LLVM 18.0.0git documentation which lead to this cmake:

cmake -G "Ninja" ../llvm/projects/compiler-rt/ -DCOMPILER_RT_BUILD_BUILTINS=ON -DCOMPILER_RT_BUILD_SANITIZERS=OFF -DCOMPILER_RT_BUILD_XRAY=OFF -DCOMPILER_RT_BUILD_LIBFUZZER=OFF -DCOMPILER_RT_BUILD_PROFILE=OFF -DCMAKE_C_COMPILER=/usr/local/myclang/bin/clang -DCMAKE_AR=/usr/local/myclang/bin/llvm-ar -DCMAKE_NM=/usr/local/myclang/bin/llvm-nm -DCMAKE_RANLIB=/usr/local/myclang/bin/llvm-ranlib -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_C_COMPILER_TARGET="arm-linux-gnueabihf" -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DLLVM_CONFIG_PATH=/usr/local/myclang/bin/llvm-config -DCMAKE_C_FLAGS="--target=arm-linux-gnueabihf -march=armv7a --gcc-toolchain=/usr/arm-linux-gnueabihf --sysroot=/usr/arm-linux-gnueabihf/lib"

Some small notes:

- Used -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY instead of -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" as Peter Smith suggested because it actually is a library and therefore does not need to be linked. If I do not change that, the cmake does not work (see below).

- used -G "Ninja" although not explicitly stated in the tutorial as they use "ninja builtins" next.

- had to change --march=armv7a to -march=armv7a as clang did not accept the first one.

the cmake was successful, but the ninja builtins was not (see both outputs below). Am I doing the --gcc-toolchain / --sysroot part right? These are just the places where the result of "apt install arm-linux-gnueabihf" lives.

cmake output with -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld":

Thanks for the comments. I will try and revisit that document next
week and will post an update.

root@christian-forschung-virtual-machine:/home/llvm_all/buildrtonly# cmake -G "Ninja" ../llvm/projects/compiler-rt/ -DCOMPILER_RT_BUILD_BUILTINS=ON -DCOMPILER_RT_BUILD_SANITIZERS=OFF -DCOMPILER_RT_BUILD_XRAY=OFF -DCOMPILER_RT_BUILD_LIBFUZZER=OFF -DCOMPILER_RT_BUILD_PROFILE=OFF -DCMAKE_C_COMPILER=/usr/local/myclang/bin/clang -DCMAKE_AR=/usr/local/myclang/bin/llvm-ar -DCMAKE_NM=/usr/local/myclang/bin/llvm-nm -DCMAKE_RANLIB=/usr/local/myclang/bin/llvm-ranlib -DCMAKE_EXE_LINKER_FLAGS="-fuse-ld=lld" -DCMAKE_C_COMPILER_TARGET="arm-linux-gnueabihf" -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DLLVM_CONFIG_PATH=/usr/local/myclang/bin/llvm-config -DCMAKE_C_FLAGS="--target=arm-linux-gnueabihf -march=armv7a --gcc-toolchain=/usr/arm-linux-gnueabihf --sysroot=/usr/arm-linux-gnueabihf/lib"
-- The C compiler identification is Clang 8.0.0
-- The CXX compiler identification is Clang 8.0.0
-- The ASM compiler identification is unknown
-- Found assembler: /usr/local/myclang/bin/clang
-- Check for working C compiler: /usr/local/myclang/bin/clang
-- Check for working C compiler: /usr/local/myclang/bin/clang -- broken
CMake Error at /usr/share/cmake-3.10/Modules/CMakeTestCCompiler.cmake:52 (message):
  The C compiler

    "/usr/local/myclang/bin/clang"

  is not able to compile a simple test program.

  It fails with the following output:

    Change Dir: /home/llvm_all/buildrtonly/CMakeFiles/CMakeTmp

    Run Build Command:"/usr/bin/ninja" "cmTC_22d97"
    [1/2] Building C object CMakeFiles/cmTC_22d97.dir/testCCompiler.c.o
    [2/2] Linking C executable cmTC_22d97
    FAILED: cmTC_22d97
    : && /usr/local/myclang/bin/clang --target=arm-linux-gnueabihf --target=arm-linux-gnueabihf -march=armv7a --gcc-toolchain=/usr/arm-linux-gnueabihf --sysroot=/usr/arm-linux-gnueabihf/lib -fuse-ld=lld CMakeFiles/cmTC_22d97.dir/testCCompiler.c.o -o cmTC_22d97 && :
    ld.lld: error: cannot open crt1.o: No such file or directory
    ld.lld: error: cannot open crti.o: No such file or directory
    ld.lld: error: cannot open crtbegin.o: No such file or directory
    ld.lld: error: unable to find library -lgcc
    ld.lld: error: unable to find library -lgcc_s
    ld.lld: error: unable to find library -lc
    ld.lld: error: unable to find library -lgcc
    ld.lld: error: unable to find library -lgcc_s
    ld.lld: error: cannot open crtend.o: No such file or directory
    ld.lld: error: cannot open crtn.o: No such file or directory
    clang-8: error: linker command failed with exit code 1 (use -v to see invocation)
    ninja: build stopped: subcommand failed.

CMake will not be able to correctly generate this project.
Call Stack (most recent call first):
  CMakeLists.txt:10 (project)
-- Configuring incomplete, errors occurred!
See also "/home/llvm_all/buildrtonly/CMakeFiles/CMakeOutput.log".
See also "/home/llvm_all/buildrtonly/CMakeFiles/CMakeError.log".

Note: Googling this error suggested installing gcc-multilib or linking "sudo ln -s /usr/lib/x86_64-linux-gnu /usr/lib64" (which both did not fix it). But the crt1.o that lld does not seem to find is probably the one from arm-linux-gnueabihf, right? "Locate" says it's right in /usr/arm-linux-gnueabihf/lib.

The instructions to use --gcc-toolchain and --sysroot work well for a
separate toolchain install directory. They don't seem to work as well
for a debian multiarch style installation. I think it will be worth
trying to compile helloworld outside of cmake. If you can get that to
work then this might help guide us to what flags to use.

On my ubuntu 16.04 machine I've got /usr/arm-linux-gnueabihf and
/usr/include/arm-linux-gnueabihf and /usr/lib/arm-linux-gnueabihf
With this configuration the clang linux driver is able to find the
libraries without the sysroot and gcc-toolchain as it is effectively
root. Can you try with a simple helloworld program:
clang --target=arm-linux-gnueabihf hello.c -o hello -fuse-ld=lld
qemu-arm -L /usr/arm-linux-gnueabihf hello
If all is well you should see qemu-arm print Hello World. You may need
to install the package qemu-user if you've not already done so.

With the -v option clang will tell you where it is searching for
headers and libraries, I've often found that useful in trying to find
out what is going.

Assuming that this has worked for you can you try removing
"--gcc-toolchain=/usr/arm-linux-gnueabihf
--sysroot=/usr/arm-linux-gnueabihf/lib" from your flags in the cmake
build.

For the errors below it looks like clang is using the default target
for assembler, note that --target=arm-linux-gnueabihf is missing. I
have seen that before, and the solution I found was to pass
-DCMAKE_ASM_FLAGS="same as C flags including
--target=arm-linux-gnueabihf and -march=armv7a"

Thanks for reporting the problems. If I get time next week I'll have a
go at improving the documentation.

Peter

Hello again!

Tried out the small Hello World Setup, worked as intended:

root@christian-forschung-virtual-machine:/home/progs# clang -v --target=arm-linux-gnueabihf hello.c -o hello -fuse-ld=lld
clang version 8.0.0 ( a152c7a4b7ba8f4cb9532ead9a38a7121db43d50) ( 1959ce6f3e01241919968ac1911fd45660239d23) Target: arm-unknown-linux-gnueabihf Thread model: posix InstalledDir: /usr/local/myclang/bin Found candidate GCC installation: /usr/lib/gcc-cross/arm-linux-gnueabihf/7 Found candidate GCC installation: /usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0 Selected GCC installation: /usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0 Candidate multilib: .;@m32 Selected multilib: .;@m32 “/usr/local/myclang/bin/clang-8” -cc1 -triple armv6kz-unknown-linux-gnueabihf -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -discard-value-names -main-file-name hello.c -mrelocation-model static -mthread-model posix -mdisable-fp-elim -fmath-errno -masm-verbose -mconstructor-aliases -fuse-init-array -target-cpu arm1176jzf-s -target-feature +strict-align -target-abi aapcs-linux -mfloat-abi hard -fallow-half-arguments-and-returns -dwarf-column-info -debugger-tuning=gdb -v -resource-dir /usr/local/myclang/lib/clang/8.0.0 -internal-isystem /usr/local/include -internal-isystem /usr/local/myclang/lib/clang/8.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/progs -ferror-limit 19 -fmessage-length 202 -fno-signed-char -fobjc-runtime=gcc -fdiagnostics-show-option -fcolor-diagnostics -o /tmp/hello-98a3a7.o -x c hello.c -faddrsig clang -cc1 version 8.0.0 based upon LLVM 8.0.0svn default target x86_64-unknown-linux-gnu ignoring nonexistent directory “/include” #include “…” search starts here: #include <…> search starts here: /usr/local/include /usr/local/myclang/lib/clang/8.0.0/include /usr/include End of search list. “/usr/local/myclang/bin/ld.lld” -EL -z relro -X --hash-style=gnu --eh-frame-hdr -m armelf_linux_eabi -dynamic-linker /lib/ld-linux-armhf.so.3 -o hello …/lib/crt1.o …/lib/crti.o /usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0/crtbegin.o -L/usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0 -L/usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0/…/…/…/…/lib -L/usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0/…/…/…/…/lib -L/usr/local/myclang/bin/…/lib -L/usr/lib/arm-linux-gnueabihf/…/…/lib -L/usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0/…/…/…/…/arm-linux-gnueabihf/lib -L/usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0/…/…/… -L/usr/local/myclang/bin/…/lib -L/lib -L/usr/lib /tmp/hello-98a3a7.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc-cross/arm-linux-gnueabihf/7.3.0/crtend.o …/lib/crtn.o

root@christian-forschung-virtual-machine:/home/progs# qemu-arm -L /usr/arm-linux-gnueabihf hello

Hello, World!

So far, so good. The Paths written more readable seem to be

/usr/local/myclang/lib, /lib, /usr/lib, /usr/arm-linux-gnueabihf/lib, so no surprised there.

Then I added the suggested -DCMAKE_ASM_FLAGS to the cmake for the standalone compiler-rt build while leaving out the --sysroot and --gcc-toolchain:

cmake -G “Ninja” … -DCOMPILER_RT_BUILD_BUILTINS=ON -DCOMPILER_RT_BUILD_SANITIZERS=OFF -DCOMPILER_RT_BUILD_XRAY=OFF -DCOMPILER_RT_BUILD_LIBFUZZER=OFF -DCOMPILER_RT_BUILD_PROFILE=OFF -DCMAKE_C_COMPILER=/usr/local/myclang/bin/clang -DCMAKE_AR=/usr/local/myclang/bin/llvm-ar -DCMAKE_NM=/usr/local/myclang/bin/llvm-nm -DCMAKE_RANLIB=/usr/local/myclang/bin/llvm-ranlib -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_C_COMPILER_TARGET=“arm-linux-gnueabihf” -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DLLVM_CONFIG_PATH=/usr/local/myclang/bin/llvm-config -DCMAKE_ASM_FLAGS=“–target=arm-linux-gnueabihf -march=armv7a” -DCMAKE_C_FLAGS=“–target=arm-linux-gnueabihf -march=armv7a”

now “ninja builtins” at least starts working, but fails after a while (see below). The error seems similar to to me, so it might still be some variant of the problem from before: Using a x86-header where an ARM one would be needed.

The ninja builtins output:

root@christian-forschung-virtual-machine:/home/llvm_all/buildrtonly# ninja builtins
[147/207] Building C object lib/builtins/CMakeFiles/clang_rt.builtins-armhf.dir/emutls.c.o
FAILED: lib/builtins/CMakeFiles/clang_rt.builtins-armhf.dir/emutls.c.o
/usr/local/myclang/bin/clang --target=arm-linux-gnueabihf -DVISIBILITY_HIDDEN --target=arm-linux-gnueabihf -march=armv7a -Wall -Wno-unused-parameter -fno-lto -std=c11 -fPIC -fno-builtin -fvisibility=hidden -fomit-frame-pointer -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET -MD -MT lib/builtins/CMakeFiles/clang_rt.builtins-armhf.dir/emutls.c.o -MF lib/builtins/CMakeFiles/clang_rt.builtins-armhf.dir/emutls.c.o.d -o lib/builtins/CMakeFiles/clang_rt.builtins-armhf.dir/emutls.c.o -c /home/llvm_all/llvm/projects/compiler-rt/lib/builtins/emutls.c
In file included from /home/llvm_all/llvm/projects/compiler-rt/lib/builtins/emutls.c:41:
/usr/include/pthread.h:682:6: error: ‘regparm’ is not valid on this platform
__cleanup_fct_attribute;
^~~~~~~~~~~~~~~~~~~~~~~
/usr/include/bits/pthreadtypes-arch.h:103:50: note: expanded from macro ‘__cleanup_fct_attribute’

define __cleanup_fct_attribute attribute ((regparm (1)))

^ ~
In file included from /home/llvm_all/llvm/projects/compiler-rt/lib/builtins/emutls.c:41:
/usr/include/pthread.h:694:3: error: ‘regparm’ is not valid on this platform
__cleanup_fct_attribute;
^~~~~~~~~~~~~~~~~~~~~~~
/usr/include/bits/pthreadtypes-arch.h:103:50: note: expanded from macro ‘__cleanup_fct_attribute’

define __cleanup_fct_attribute attribute ((regparm (1)))

^ ~
In file included from /home/llvm_all/llvm/projects/compiler-rt/lib/builtins/emutls.c:41:
/usr/include/pthread.h:735:6: error: ‘regparm’ is not valid on this platform
__cleanup_fct_attribute attribute ((noreturn))
^~~~~~~~~~~~~~~~~~~~~~~
/usr/include/bits/pthreadtypes-arch.h:103:50: note: expanded from macro ‘__cleanup_fct_attribute’

define __cleanup_fct_attribute attribute ((regparm (1)))

^ ~
3 errors generated.
[148/207] Building C object lib/builtins/CMakeFiles/clang_rt.builtins-armhf.dir/gcc_personality_v0.c.o
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:148:47: warning: declaration of ‘struct _Unwind_Exception’ will not be visible outside of this function [-Wvisibility]
_Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception *,
^
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:153:23: warning: declaration of ‘struct _Unwind_Exception’ will not be visible outside of this function [-Wvisibility]
continueUnwind(struct _Unwind_Exception *exceptionObject,
^
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:160:28: warning: incompatible pointer types passing ‘struct _Unwind_Exception *’ to parameter of type ‘struct _Unwind_Exception *’ [-Wincompatible-pointer-types]
if (__gnu_unwind_frame(exceptionObject, context) != _URC_OK)
^~~~~~~~~~~~~~~
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:148:66: note: passing argument to parameter here
_Unwind_Reason_Code __gnu_unwind_frame(struct _Unwind_Exception *,
^
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:184:38: warning: declaration of ‘struct _Unwind_Exception’ will not be visible outside of this function [-Wvisibility]
_Unwind_State state, struct _Unwind_Exception *exceptionObject,
^
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:202:31: warning: incompatible pointer types passing ‘struct _Unwind_Exception *’ to parameter of type ‘struct _Unwind_Exception *’ [-Wincompatible-pointer-types]
return continueUnwind(exceptionObject, context);
^~~~~~~~~~~~~~~
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:153:42: note: passing argument to parameter ‘exceptionObject’ here
continueUnwind(struct _Unwind_Exception *exceptionObject,
^
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:207:31: warning: incompatible pointer types passing ‘struct _Unwind_Exception *’ to parameter of type ‘struct _Unwind_Exception *’ [-Wincompatible-pointer-types]
return continueUnwind(exceptionObject, context);
^~~~~~~~~~~~~~~
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:153:42: note: passing argument to parameter ‘exceptionObject’ here
continueUnwind(struct _Unwind_Exception *exceptionObject,
^
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:250:27: warning: incompatible pointer types passing ‘struct _Unwind_Exception *’ to parameter of type ‘struct _Unwind_Exception *’ [-Wincompatible-pointer-types]
return continueUnwind(exceptionObject, context);
^~~~~~~~~~~~~~~
/home/llvm_all/llvm/projects/compiler-rt/lib/builtins/gcc_personality_v0.c:153:42: note: passing argument to parameter ‘exceptionObject’ here
continueUnwind(struct _Unwind_Exception *exceptionObject,
^
7 warnings generated.
[152/207] Building ASM object lib/builtins/CMakeFiles/clang_rt.builtins-armhf.dir/arm/aeabi_cdcmp.S.o
ninja: build stopped: subcommand failed.

Almost there! Thanks in advance!

Christian

Hello Christian,

Yes it does look like clang will add /usr/local/include unless
--nostdinc is used, although that will mean skipping a lot of other
include directories that clang will implicitly add based on the
target. I can think of a couple of ways to proceed:
1.) use -nostdinc and add in the directories you need manually
2.) use a cross gcc toolchain in a different directory such as one
from (Downloads | GNU-A Downloads – Arm Developer)
and use --gcc-toolchain and --sysroot.

I must admit I've only ever done 2.) myself as I've wanted to make
sure I've not inadvertently depended on something on my machine.

Apologies for the confusion.

Peter

Hello Peter and Lists,

thanks a lot, that way it worked out! The final cmake was

cmake -G “Ninja” … -DCOMPILER_RT_BUILD_BUILTINS=ON -DCOMPILER_RT_BUILD_SANITIZERS=OFF -DCOMPILER_RT_BUILD_XRAY=OFF -DCOMPILER_RT_BUILD_LIBFUZZER=OFF -DCOMPILER_RT_BUILD_PROFILE=OFF -DCMAKE_C_COMPILER=/usr/local/myclang/bin/clang -DCMAKE_AR=/usr/local/myclang/bin/llvm-ar -DCMAKE_NM=/usr/local/myclang/bin/llvm-nm -DCMAKE_RANLIB=/usr/local/myclang/bin/llvm-ranlib -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_C_COMPILER_TARGET=“arm-linux-gnueabihf” -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DLLVM_CONFIG_PATH=/usr/local/myclang/bin/llvm-config -DCMAKE_ASM_FLAGS=“–target=arm-linux-gnueabihf -march=armv7a --gcc-toolchain=/home/crichter/arm-linux-gnueabihf/gcc-arm --sysroot=” -DCMAKE_C_FLAGS=“–target=arm-linux-gnueabihf -march=armv7a --gcc-toolchain=/home/crichter/arm-linux-gnueabihf/gcc-arm --sysroot=”

where contains sysroot-glibc-8.2-x86_64 and /arm-linux-gnueabihf/gcc-arm contains gcc-arm-8.2 for Aarch32 hard float from . This resulted in successfully building libclang_rt.builtins-armhf.a

So next, I tried to use the cmake recipe for BaremetalARM as in the documentation. Therefore, I moved the compiler-rt directory from llvm/projects to llvm/runtimes. I downloaded the latest updates of gcc-arm-none-eabi6/7/8 from and tried to build in a new directory. But whether I gave the -C the path to BaremetalARM.cmake’s directory or the file itself, nothing started. I was unsure whether to keep the paths to llvm-ar, llvm-nm and so on as well and whether or not to give the new compiler-rt-directory or the whole llvm-directory as a starting point. Am I using the wrong build directory here? Is this still “Ninja”? The error message (see below) is true: /home/llvm_4rt/llvm/tools/clang/cmake/caches contains no CMakeLists.txt, just the BaremetalARM.cmake among other recipes. Giving -C the file directly just leads to a “this is a file, not a directory” error.

This is (one of my) cmake commands:

root@christian-forschung-virtual-machine:/home/llvm_4rt/buildrecipe# cmake -G “Ninja” … -DCOMPILER_RT_BUILD_BUILTINS=ON -DCOMPILER_RT_BUILD_SANITIZERS=OFF -DCOMPILER_RT_BUILD_XRAY=OFF -DCOMPILER_RT_BUILD_LIBFUZZER=OFF -DCOMPILER_RT_BUILD_PROFILE=OFF -DCMAKE_C_COMPILER=/usr/local/myclang/bin/clang -DCMAKE_AR=/usr/local/myclang/bin/llvm-ar -DCMAKE_NM=/usr/local/myclang/bin/llvm-nm -DCMAKE_RANLIB=/usr/local/myclang/bin/llvm-ranlib -DCMAKE_TRY_COMPILE_TARGET_TYPE=STATIC_LIBRARY -DCMAKE_C_COMPILER_TARGET=“arm-linux-gnueabihf” -DCOMPILER_RT_DEFAULT_TARGET_ONLY=ON -DLLVM_CONFIG_PATH=/usr/local/myclang/bin/llvm-config -DBAREMETAL_ARMV5M_SYSROOT=/home/crichter/Downloads/gcc-arm-none-eabi-5_4-2016q3 -DBAREMETAL_ARMV6M_SYSROOT=/home/crichter/Downloads/gcc-arm-none-eabi-6-2017-q2-update -DBAREMETAL_ARMV7M_SYSROOT=/home/crichter/Downloads/gcc-arm-none-eabi-7-2018-q2-update -C /home/llvm_4rt/llvm/tools/clang/cmake/caches

loading initial cache file /home/llvm_4rt/llvm/tools/clang/cmake/caches
CMake Error: Error processing file: /home/llvm_4rt/llvm/tools/clang/cmake/caches
CMake Error: The source directory “/home/llvm_4rt/llvm/tools/clang/cmake/caches” does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.

So I’m obviously using it wrong, would appreciate any pointers in the right direction!
Christian

Hello Christian,

I've just retried the runtimes way of building for v6m, v7m and v7e-m
. My cmake command was
ARMEABIGCC=/path/to/gcceabi/arm-none-eabi
cmake \
  -G Ninja\
  -DBAREMETAL_ARMV6M_SYSROOT=${ARMEABIGCC}\
  -DBAREMETAL_ARMV7M_SYSROOT=${ARMEABIGCC}\
  -DBAREMETAL_ARMV7EM_SYSROOT=${ARMEABIGCC}\
  -DCMAKE_BUILD_TYPE=Release\
  -C/path/to/llvm/tools/clang/cmake/caches/BaremetalARM.cmake \
  /path/to/llvm

The cache file requires clang and lld. From the build directory they
will go into lib/clang. That worked for me (TM). Hopefully if you can
edit the paths it will work for you. My guess is that you'll want to
set ARMEABIGCC=/home/crichter/Downloads/gcc-arm-none-eabi-5_4-2016q3/arm-none-eabi

Peter

Hello again Christian,

I've posted https://reviews.llvm.org/D55709 to see if we can get the
documentation on how to cross-compile compiler-rt improved. I'll be
out of office until next year so I may be a bit slow to respond to any
follow ups.

Peter

Hello again,

thanks a lot, finally building! The cmake looked like this in my case:

cmake -G Ninja -DBAREMETAL_ARMV6M_SYSROOT=${ARMEABI5GCC} -DBAREMETAL_ARMV7M_SYSROOT=${ARMEABI5GCC} -DBAREMETAL_ARMV7EM_SYSROOT=${ARMEABI5GCC} -DCMAKE_BUILD_TYPE=Release -C /home/llvm_4rt/llvm/tools/clang/cmake/caches/BaremetalARM.cmake

echo $ARMEABI5GCC
/home/crichter/Downloads/gcc-arm-none-eabi-5_4-2016q3/arm-none-eabi

(which is the DL from ) This lead to the desired lib/clang/8.0.0/armv6m-none-eabi/lib/libclang_rt.builtins.a and so on being build. So thanks a lot for all the help and happy holidays! Christian

Hello again,

so after I successfully build the compiler-rt for armv6 I tried to actually use it in compiling a small helloworld for a baremetal arm (consisting of barehelloCLANG.c and a small io.h + io.c) , but the linking part of the compilation resulted in this:

root@christian-forschung-virtual-machine:/home/progs# clang -v --target=armv6-none-eabi -L /home/llvm_all/buildrecipe/lib/clang/8.0.0/armv6m-none-eabi -lclang_rt.builtins.arm barehelloCLANG.o io.o -o helloCLANGstatic -static -fuse-ld=lld
clang version 8.0.0 (https://git.llvm.org/git/clang.git/ a152c7a4b7ba8f4cb9532ead9a38a7121db43d50) (https://git.llvm.org/git/llvm.git/ 1959ce6f3e01241919968ac1911fd45660239d23)
Target: armv6-none-unknown-eabi
Thread model: posix
InstalledDir: /usr/local/myclang/bin
  "/usr/local/myclang/bin/ld.lld" -lclang_rt.builtins.arm barehelloCLANG.o io.o -Bstatic -L/usr/local/myclang/lib/clang/8.0.0/lib/baremetal -L/home/llvm_all/buildrecipe/lib/clang/8.0.0/armv6m-none-eabi -lc -lm -lclang_rt.builtins-armv6.a -o helloCLANGstatic
ld.lld: error: unable to find library -lclang_rt.builtins.arm
ld.lld: error: unable to find library -lc
ld.lld: error: unable to find library -lm
ld.lld: error: unable to find library -lclang_rt.builtins-armv6.a
clang-8: error: ld.lld command failed with exit code 1 (use -v to see invocation)

So basically, the compiler does not use/find the given libraries, but after trying a lot of variations of the above with the same result I can't figure out why. /home/llvm_all/buildrecipe/lib/clang/8.0.0/armv6m-none-eabi is what the recipe from https://llvm.org/docs/HowToCrossCompileBuiltinsOnArm.html gave me and is empty except for clang_rt.builtins-armv6.a. Do I still need to use the sysroot for baremetal arm in addition or do the compiler-rt suffice? Once more thanks in advance for any hint or help!

Christian Richter

Hello Christian,

I've put some comments inline,

Hello again,

so after I successfully build the compiler-rt for armv6 I tried to
actually use it in compiling a small helloworld for a baremetal arm
(consisting of barehelloCLANG.c and a small io.h + io.c) , but the
linking part of the compilation resulted in this:

root@christian-forschung-virtual-machine:/home/progs# clang -v
--target=armv6-none-eabi -L
/home/llvm_all/buildrecipe/lib/clang/8.0.0/armv6m-none-eabi
-lclang_rt.builtins.arm barehelloCLANG.o io.o -o helloCLANGstatic
-static -fuse-ld=lld
clang version 8.0.0 (https://git.llvm.org/git/clang.git/
a152c7a4b7ba8f4cb9532ead9a38a7121db43d50)
(https://git.llvm.org/git/llvm.git/
1959ce6f3e01241919968ac1911fd45660239d23)
Target: armv6-none-unknown-eabi
Thread model: posix
InstalledDir: /usr/local/myclang/bin
  "/usr/local/myclang/bin/ld.lld" -lclang_rt.builtins.arm
barehelloCLANG.o io.o -Bstatic
-L/usr/local/myclang/lib/clang/8.0.0/lib/baremetal
-L/home/llvm_all/buildrecipe/lib/clang/8.0.0/armv6m-none-eabi -lc -lm
-lclang_rt.builtins-armv6.a -o helloCLANGstatic
ld.lld: error: unable to find library -lclang_rt.builtins.arm
ld.lld: error: unable to find library -lc
ld.lld: error: unable to find library -lm
ld.lld: error: unable to find library -lclang_rt.builtins-armv6.a
clang-8: error: ld.lld command failed with exit code 1 (use -v to see
invocation)

Just to be sure; do you really mean --target=armv6-none-eabi ? That is
targeting an old ArmV6 device such as an ARM1176 as used on the
Raspberry Pi; this is very different from --target=armv6m-none-eabi ,
as used on the cortex-m0, despite there being only one letter
difference in the target! Whichever you need you'll need to have the
right compiler-rt.

When you use a -none-eabi target clang will use the BareMetal driver
that in contrast with the Linux driver adds very few include and
library paths automatically. The driver will automatically add
-lclang_rt.builtins-{arch-name}.a where arch-name will be armv6 if you
are using --target=armv6-none-eabi. Unfortunately when LLD sees
-l{library name} it will search for {library name}.a and {library
name}.so, even if {library name} ends in .a, so LLD will be looking
for clang_rt.builtins-armv6.a.a which it won't find. Personally I
think this could be considered a bug in the BareMetal driver. As a
workaround you can rename, copy or symlink a
clang_rt.builtins-{arch-name}.a.a so that LLD can find it.

So basically, the compiler does not use/find the given libraries, but
after trying a lot of variations of the above with the same result I
can't figure out why.
/home/llvm_all/buildrecipe/lib/clang/8.0.0/armv6m-none-eabi is what the
recipe from How to Cross Compile Compiler-rt Builtins For Arm — LLVM 18.0.0git documentation
gave me and is empty except for clang_rt.builtins-armv6.a. Do I still
need to use the sysroot for baremetal arm in addition or do the
compiler-rt suffice? Once more thanks in advance for any hint or help!

Yes you'll still need to use a sysroot for bare metal Arm. The
compiler-rt builtins library provides run-time functions that the
compiler can use in code-generation, a good example is supporting for
software floating point emulation. It isn't a replacement for a C or
Math library. The last time I tried to make a bare-metal Arm program
work with clang I did the following:
- Downloaded the arm-none-eabi GNU toolchain

- Found one of the sample programs in the
share/gcc-arm-none-eabi/samples directory and built that.
- Made sure the program worked.
- Used arm-none-eabi-gcc -v to find the libraries and paths that GCC was using.
- Substituted clang for arm-none-eabi-gcc after after removing the
libraries I had clang equivalents for.

This is obviously not a great user experience, the BareMetal driver
needs quite a bit of work. Unfortunately due to the needs of multilib
and the dependencies between newlib/newlib-nano and libgloss
components that gcc uses specs files for, this is not simple.

Peter

Hello again,

so I’ve tried the following: I created a working gcc version with arm-none-eabi-gcc (this took some time, hence the late answer I’m afraid). The output of the linker stage looks like this:

root@christian-forschung-virtual-machine:/home/progs# arm-none-eabi-gcc -v start.o barehello.o io.o -nostartfiles -Wl,–build-id=none -Wl,-init=_start -Ttext 0x8000 -static -o hello

Using built-in specs.
COLLECT_GCC=arm-none-eabi-gcc
COLLECT_LTO_WRAPPER=/usr/lib/gcc/arm-none-eabi/6.3.1/lto-wrapper
Target: arm-none-eabi
Configured with: …/src/configure --build=x86_64-linux-gnu --prefix=/usr --includedir=‘/usr/lib/include’ --mandir=‘/usr/lib/share/man’ --infodir=‘/usr/lib/share/info’ --sysconfdir=/etc --localstatedir=/var --disable-silent-rules --libdir=‘/usr/lib/lib/x86_64-linux-gnu’ --libexecdir=‘/usr/lib/lib/x86_64-linux-gnu’ --disable-maintainer-mode --disable-dependency-tracking --mandir=/usr/share/man --enable-languages=c,c++,lto --enable-multilib --disable-decimal-float --disable-libffi --disable-libgomp --disable-libmudflap --disable-libquadmath --disable-libssp --disable-libstdcxx-pch --disable-nls --disable-shared --disable-threads --disable-tls --build=x86_64-linux-gnu --target=arm-none-eabi --with-system-zlib --with-gnu-as --with-gnu-ld --with-pkgversion=15:6.3.1+svn253039-1build1 --without-included-gettext --prefix=/usr/lib --infodir=/usr/share/doc/gcc-arm-none-eabi/info --htmldir=/usr/share/doc/gcc-arm-none-eabi/html --pdfdir=/usr/share/doc/gcc-arm-none-eabi/pdf --bindir=/usr/bin --libexecdir=/usr/lib --libdir=/usr/lib --disable-libstdc+±v3 --host=x86_64-linux-gnu --with-headers=no --without-newlib --with-multilib-list=rmprofile CFLAGS=‘-g -O2 -fdebug-prefix-map=/build/gcc-arm-none-eabi-iopiMw/gcc-arm-none-eabi-6.3.1+svn253039=. -fstack-protector-strong’ CPPFLAGS=‘-Wdate-time -D_FORTIFY_SOURCE=2’ CXXFLAGS=‘-g -O2 -fdebug-prefix-map=/build/gcc-arm-none-eabi-iopiMw/gcc-arm-none-eabi-6.3.1+svn253039=. -fstack-protector-strong’ FCFLAGS=‘-g -O2 -fdebug-prefix-map=/build/gcc-arm-none-eabi-iopiMw/gcc-arm-none-eabi-6.3.1+svn253039=. -fstack-protector-strong’ FFLAGS=‘-g -O2 -fdebug-prefix-map=/build/gcc-arm-none-eabi-iopiMw/gcc-arm-none-eabi-6.3.1+svn253039=. -fstack-protector-strong’ GCJFLAGS=‘-g -O2 -fdebug-prefix-map=/build/gcc-arm-none-eabi-iopiMw/gcc-arm-none-eabi-6.3.1+svn253039=. -fstack-protector-strong’ LDFLAGS=‘-Wl,-Bsymbolic-functions -Wl,-z,relro’ OBJCFLAGS=‘-g -O2 -fdebug-prefix-map=/build/gcc-arm-none-eabi-iopiMw/gcc-arm-none-eabi-6.3.1+svn253039=. -fstack-protector-strong’ OBJCXXFLAGS=‘-g -O2 -fdebug-prefix-map=/build/gcc-arm-none-eabi-iopiMw/gcc-arm-none-eabi-6.3.1+svn253039=. -fstack-protector-strong’ INHIBIT_LIBC_CFLAGS=-DUSE_TM_CLONE_REGISTRY=0 AR_FOR_TARGET=arm-none-eabi-ar AS_FOR_TARGET=arm-none-eabi-as LD_FOR_TARGET=arm-none-eabi-ld NM_FOR_TARGET=arm-none-eabi-nm OBJDUMP_FOR_TARGET=arm-none-eabi-objdump RANLIB_FOR_TARGET=arm-none-eabi-ranlib READELF_FOR_TARGET=arm-none-eabi-readelf STRIP_FOR_TARGET=arm-none-eabi-strip
Thread model: single
gcc version 6.3.1 20170620 (15:6.3.1+svn253039-1build1)
COMPILER_PATH= LIBRARY_PATH= COLLECT_GCC_OPTIONS=‘-v’ ‘-nostartfiles’ ‘-Ttext’ ‘0x8000’ ‘-static’ ‘-o’ ‘hello’ /usr/lib/gcc/arm-none-eabi/6.3.1/collect2 -plugin /usr/lib/gcc/arm-none-eabi/6.3.1/liblto_plugin.so -plugin-opt=/usr/lib/gcc/arm-none-eabi/6.3.1/lto-wrapper -plugin-opt=-fresolution=/tmp/cceNgJBK.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lc -Bstatic -X -o hello -L/usr/lib/gcc/arm-none-eabi/6.3.1 -L/usr/lib/gcc/arm-none-eabi/6.3.1/…/…/…/arm-none-eabi/lib start.o barehello.o io.o --build-id=none -init=_start --start-group -lgcc -lc --end-group -Ttext 0x8000 COLLECT_GCC_OPTIONS=‘-v’ ‘-nostartfiles’ ‘-Ttext’ ‘0x8000’ ‘-static’ ‘-o’ ‘hello’

and the resulting program works on the baremetal ARM (after objcopying it). So far, so good. Using a similar call for clang --target=armv6m-none-eabi fails like this:

root@christian-forschung-virtual-machine:/home/progs/clang# clang -v start.o barehello.o io.o --target=armv6m-none-eabi -Wl,–build-id=none -Wl,-init=_start -Ttext 0x8000 -static -o hello

clang version 8.0.0 ( a152c7a4b7ba8f4cb9532ead9a38a7121db43d50) ( 1959ce6f3e01241919968ac1911fd45660239d23) Target: armv6m-none-unknown-eabi Thread model: posix InstalledDir: /usr/local/myclang/bin “/usr/local/myclang/bin/ld.lld” start.o barehello.o io.o --build-id=none -init=_start -Bstatic -L/usr/local/myclang/lib/clang/8.0.0/lib/baremetal -Ttext 0x8000 -lc -lm -lclang_rt.builtins-armv6m.a -o hello ld.lld: error: unable to find library -lc ld.lld: error: unable to find library -lm ld.lld: error: unable to find library -lclang_rt.builtins-armv6m.a clang-8: error: ld.lld command failed with exit code 1 (use -v to see invocation)

I downloaded the sysroot (from ) and tried to include it via --sysroot (like --sysroot=/home/crichter/Downloads/gcc-arm-none-eabi-5_4-2016q3/arm-none-eabi) or -L or -l and tried the same for the two libraries gcc seems to use according to its -v (LIBRARY_PATH=

Hello Christian,

I'd expect that adding the library paths (-L) from gcc -v should fix
the unable to find -lc, -lm but it won't fix the
-lclang_rt.builtins-armv6m.a . To get clang_rt.builtins-armv6m.a you
will need to cross compile compiler-rt for v6m and copy it to
/usr/local/myclang/lib/clang/8.0.0/lib/baremetal . Beware that
building compiler-rt for v6m does need quite a bit of fighting cmake
(https://llvm.org/docs/HowToCrossCompileBuiltinsOnArm.html). Your
alternative if you already have a libgcc.a is to use --nostdlib or
--nodefaultlibs to stop the driver adding -lm -lc
-lclang_rt.builtins-armv6m.a , although you'll need to add your c
library (and possibly math library) yourself in that case.

I don't understand the part about __start. I'd expect __start to be
provided by the c library, probably newlib or newlib nano from
arm-none-eabi.

Peter

Hello Peter,

the unable to find -lc, -lm was indeed fixed as soon as I got the -L right, thanks! So for the record, the correct way to include the paths was „-L/usr/lib/gcc/arm-none-eabi/6.3.1/ -L/usr/lib/arm-none-eabi/lib/“.

The -clang_rt.builtins-armv6m.a still puzzles me: I built the compiler-rt according to the mentioned baremetal recipe some time ago with

cmake –G Ninja –DBAREMETAL_ARMV6M_SYSROOT=${ARMEABI5GCC} -DBAREMETAL_ARMV7M_SYSROOT=${ARMEABI5GCC}- DBAREMETAL_ARMV7EM_SYSROOT=${ARMEABI5GCC} –DCMAKE_BUILD_TYPE=Release –C /home/llvm_4rt/llvm/tools/clang/cmake/caches/BaremetalARM.cmake /home/llvm_4rt/llvm/

where ARMEABI5GCC=/home/crichter/Downloads/gcc-arm-none-eabi-5_4-2016q3/arm-none-eabi is from the sysroot download site you gave me back then.

That resulted in a libclang_rt.builtins.a file which I considered to be the right one to use now, but neither copying it into
/usr/local/myclang/lib/clang/8.0.0/lib/baremetal (which did not exist before, only /linux was present already) or adding another .a behind the name helped the linker, nor did adding a -l<path-to-libclang_rt.builtins.a>. Did I
build the wrong one or am I using it incorrectly?

The part about the int _start () attribute ((naked)) was needed when compiling with gcc because otherwise the program contained an unwanted push{r4, lr}. But this is a problem for a later day that might not even occur with clang. I’ll see if it comes back to haunt me when I’m able to compile the program with clang, I guess :slight_smile:

Thanks once more!
Christian

Hello Christian,

I reran my script with a similar cmake command to yours. After the
build finished the following command from the build directory gave me:
find . -name \*builtins.a
./lib/clang/9.0.0/armv6m-none-eabi/lib/libclang_rt.builtins.a
./lib/clang/9.0.0/armv7m-none-eabi/lib/libclang_rt.builtins.a
./lib/clang/9.0.0/armv7em-none-eabi/lib/libclang_rt.builtins.a
I hope you see something like this with your build. You can check that
they are correct by disassembling them to see if they contain the
instructions that you are looking for.

Unfortunately it looks like the runtimes method does not produce the
library names that match what the driver is expecting:
For example with --target=armv7m-none-eabi I get with -v
-L/path/to/my/clang/build/dir/lib/clang/9.0.0/lib/baremetal -lc -lm
-lclang_rt.builtins-armv7m.a

I suggest renaming the files when copying them to the
/path/to/my/clang/build/dir/lib/clang/9.0.0/lib/baremetal dir.
libclang_rt.builtins-armv6m.a
libclang_rt.builtins-armv7m.a
libclang_rt.builtins-armv7em.a

When I build the builtins using the standalone build then I get the
correct names:
find /linaro/compiler-rt/build_rt_arm_v7m/ -name \*.a
/path/to/compiler-rt/build/dir/lib/baremetal/libclang_rt.builtins-armv7m.a

Hope that gets you a bit further. You may need to write your __start
function in assembler, I don't think clang allows function calls in
naked functions.

Peter

Hello Peter,

so in short: It works now! The compiler call looked like this in the final version:

root@virtual-machine:/home/progs/clang# cat BAREhelloCLANG.sh
clang -v --target=arm-none-eabi -O4 -c start.c -o start.o
clang -v --target=arm-none-eabi -c barehello.c -o barehello.o
clang -v --target=arm-none-eabi -c io.c -o io.o
clang -v --target=armv6m-none-eabi -L/usr/lib/gcc/arm-none-eabi/6.3.1/ -L/usr/lib/arm-none-eabi/lib/ start.o barehello.o io.o -nostartfiles -Wl,--build-id=none -Wl,-init=_start -Ttext 0x8000 -static -o helloCLANG
arm-none-eabi-objcopy -O binary helloCLANG oc_hello_bare_CLANG

while I get two warnings ( "unused command -nostartfiles" and "lld uses blx, no object with architecture supporting feature detected") and the resulting files is significantly larger (gcc: 204 bytes, clang: 4000 bytes, probably because of the inclusion of unused libraries from the look of the assembly), the resulting file executed correctly on the baremetal arm. The __start()-stuff was not (yet) needed as it seems (contrary to the gcc version).

So once more thanks a lot!

Christian

Hello Christian,

That's good to know. Some explanation of the warnings:
"lld uses blx, no object with architecture supporting feature
detected" : lld assumes that it can use the BLX instruction to change
state between Arm and Thumb, this instruction isn't available on an
Arm7tdmi (Architecture 4vt), the instruction was introduced on Armv5t.
If you are genuinely running the program on an Arm7tdmi I'd be careful
to only use Arm instructions so that there are no linker generated
transitions to Thumb. If you are running on a more recent CPU that
supports BLX then you can ignore this warning. A clang target of
arm-none-eabi will default to -mcpu=arm7tdmi, if will be worth telling
clang that you are compiling for a more recent architecture.

As I understand it, the clang bare metal driver doesn't include any c
library startup code (crt0 etc.) so I'd expect it to always be
--nostartfiles.

Your clang linker invocation is using clang -v
--target=armv6m-none-eabi I'm guessing because that will select the
v6m compiler-rt. This will be Thumb v6m code. This won't be a problem
if the compiler doesn't call anything from compiler-rt, but due to
LLD's use of BLX to transition from Arm to Thumb then it will cause
you some problems if run on an Arm7tdmi that doesn't support BLX. The
best way to work around that would be to either compile compiler-rt
builtins for Arm7tdmi, or use libgcc.a. To use libgcc.a you'll need
--nostdlib -lc -lgcc and possibly a -L with a path to libgcc.a

The size difference is probably coming from page alignment, LLD
currently assumes page alignment (4k for Arm) even for embedded
systems. On ld.bfd you can use -N (--omagic) or -n (--nmagic) to
disable page alignment. LLD has some support for -N but it doesn't
disable page alignment. You can use -zmax-page-size=1 to disable page
alignment. This may result in a smaller binary.

Peter