The bad news is that you can't really do exactly what you're asking for very easily. Unless you are terribly ambitious or tasked with creating the developer toolchain that can do what you ask, you don't need to bother with the rest below. Switch to a platform like Ubuntu linux that has easily-installed (gcc) cross toolchains, or ask your BSP vendor for a Windows cross toolchain based on clang.
The release tarballs provided by LLVM community at https://releases.llvm.org/ are best suited for native builds. Yes, they include a compiler, assembler, linker, C++ library. They all work together well as a native toolchain (but will refer to the native host C library, and the native host linker by default). Yes, it's true that the compiler/assembler that are included do support all of the LLVM targets. But you don't want just a compiler, you want a toolchain. A complete cross-target C/C++ toolchain will typically include:
- OS headers that declare types and functions
- C library headers that refer to the OS headers and declare types and functions, library/shared object archive that define functions.
- C++ library headers that declare templates, types and functions, library/shared object archive that define functions.
- target linker
- binutils: standalone assembler, objcopy, objdump, archiver, etc.
With #2 above you could make a call to printf()
and the linker would be able to find its implementation in the C library archive. Your linked ./a.out
executable could then run that printf code and expect it to emit something to some console or semihosted output.
I am trying to cross-compile from windows to ARM. When I compile with
clang, I get an error missing stdio.h. When I compile with clang++ I
got warning: unable to find a Visual Studio installation. What to do?
When I compile with -target armv7a-none-eabi, I got missing stdio.h.
armv7a-none-eabi
describes a target that has no operating system. If we had a stdio.h that declared printf, that would get us part of the way. But what should happen in the printf()
implementation for this particular target?
What most users want is a vendor to provide the C library headers and archive -- a commercial or open source distributor who packages up a C library. Usually they're bundled with the toolchain itself. Sometimes the development board and corresponding toolchain come in one big bundle/BSP.
Since you asked for armv7a-none-eabi
specifically, I would strongly recommend that you find a vendor to give you what you want. Especially if you need to use a Windows host.
If you aren't stuck on Windows, or are willing to use WSL: Debian and Ubuntu provide cross toolchains and C libraries (including ones like libnewlib-arm-none-eabi
). Unfortunately, I don't think there's any clang-based cross toolchain that would leverage this C library.
While you could try to bind libnewlib-arm-none-eabi
with a clang tarball from https://releases.llvm.org/, it won't be particularly easy. I would start off by reviewing https://releases.llvm.org/11.0.0/tools/clang/docs/UsersManual.html#configuration-files - create a config file that references the relevant include path(s) and library path(s).
Once you have the config file prototyped, start small and build:
- try to compile an object file for your target from
int foo(void) { return 33; }
.
- try to build an executable from a .c file with
int main(void) {}
- try to build an executable from a .c file with a call to
printf()
.
If you get through those three steps, congratulations, you probably had to figure out a lot of interesting challenges. If you want std::cout
and friends to work, you will need to build a C++ library for your target. You can use libc++/libc++abi or libstdc++. C++ libraries on baremetal/freestanding targets are probably not very common. That said, there's lots of C++ library content that has little or no system dependencies. Especially the C++98/03 content that focused on STL - they probably only depend on the system heap allocator. Your example only shows std::vector<>
and std::cout
, so it's probably doable.