For some reason the compile speed of LLVM is extremely slow on my Mac, and based on my observation most of the time is spend on compiling the different target in llvm/lib/Target.
However, the only target I need is X86, so I'm wondering is there a way to specify the target I want to compile so that the LLVM will only compile that target and save a lot of time?
You can pass -DLLVM_TARGETS_TO_BUILD=X86 to the initial cmake invocation.
Related
I'm currently working on a rather generic communication stack. It gets bytes in on one end, parses the packet and calls a callback.
I want to have this stack in a static library (i.e. libcommstack.a).
The library is aimed towards embedded ARM Cortex-M devices. At the moment we have specified that at least a Cortex-M3 should be used (but it should also work for an M4 or M33).
Right now I'm integrating it into another application to verify that linking it is possible. In the future the idea is that we will ship this .a file to customers so they can build their application around it, without having direct access to our sources (to encapsulate our IP).
We are using GCC ARM v7.2.1 to compile both the library and the application that is linked to it.
The application I'm trying to integrate it with is compiled for a Cortex M33 with -mfloat-abi=hard -mfpu-fpv6-sp-d16.
The code for the library does not use any floating points and is compiled using -march=archv7-m (both have the -mthumb flag).
Linking seemed to all go well, until I actually called a function from the lib. At that point the linker starts to complain:
application.elf uses VFP register arguments, libcommstack.a(somefile.c.obj) does not
failed to merge target specific data of file libcommstack.a(somefile.c.obj)
Since I'm not using floating points in the library and I don't know (upfront) if the target application does or does not have an FPU (or even uses floats), I'm not sure how to approach this.
I figured there would be two approaches:
Compile a single version of the lib, using an instruction set that all of the microcontrollers understand. I was hoping that this would be the case with ARMv7 (although I'm not yet 100% confident that the M23/M33 also support this).
Compile a lot of different libs for the different flavors based on the different architectures, FPU, etc.
As you can imagine, I would prefer to keep it simple and go for option 1, but I'm not sure how to "convince" the linker to link these two (or perhaps how to convince the compiler NOT to care about floating points for the lib).
Does anyone know if option 1 is feasible and how it can be achieved?
If it is not feasible, what would be the variables to keep in mind to determine the different build flavors?
Does anyone know if option 1 is feasible
Well, feasible, probably.
how it can be achieved?
Get all the processors you want to support and determine the instructions sets available on all these processors. Then compile for that instruction set.
But, please don't, that is a workaround.
If it is not feasible, what would be the variables to keep in mind to determine the different build flavors?
Gcc has something like "multilib profiles". See arm-none-eabi-gcc --print-multi-lib output. If you have newlib installed, you can go to /usr/arm-none-eabi/lib/thumb/ and see the directories there - newlib is compiled for each profile and installs separate library for it and different library is picked up depending on configuration. Compile for each of those profiles, and package your library by putting libraries in proper /usr/arm-none-eabi/lib/proper/directory/here and compiler will pick them up by itself (see gcc -v output for library search paths). For an example search newlib sources where it happens, can't find it. (Here's my example). With cmake as a backend as a example you could compile and install as follows:
arm-none-eabi-gcc --print-multi-lib |
while IFS=';' read -r dir opts; do
cmake -B builddir CMAKE_C_FLAGS="$opts" CMAKE_INSTALL_LIBDIR="$dir"
cmake --build builddir
cmake --install builddir --prefix "/usr/arm-none-eabi/"
done
GCC is a compiler collection that generates machine code from different programming languages. For that you have to compile the compiler to run on your architecture and operating system. But you also have to define what kind of machine code and file format is generated.
Now my questions:
Is the output file of GCC only configurable at compilation time of GCC?
And can GCC be compiled so that it supports multiple architectures and file formats?
gcc and binutils are designed to build for one architecture/family at a time. So if you build them as a cross compiler for ARM then you cannot build mips, but you can have multiple/many installations so you can also build one to target mips and use that one.
clang/llvm if when you build you don't tell it not to it will build a tool for all targets it knows. This tool will get you up to the object level for any of the supported targets with the one tool, but linking is another story you need to tell it to builds its linker (and then I don't remember if the linker will support any target or one). You can use binutils to assemble/link for clang/llvm (and then you definitely have a single target assembler/linker).
I have tried -mthumb, it looks like the sources just get compiled for ARM. I have tried triple --target=thumbv7-linux-gnueabihf, but the build system just skips compiling the project. I know they somehow compile for Thumb-only target with the same build system (perhaps configuring in a different way, different target, options etc), but I can't reproduce so far the problem where my ARM assembly fails to compile on a Thumb-only CPU.
I've looked through gcc options for Thumb and got only the above ideas.
EDIT: it seems they compile for Thumb-only CPU on a Thumb-only CPU, so it is automatically selected as the default target. But I am cross-compiling from x86_64-Windows to ARM-Linux (and I want Thumb-Linux).
EDIT2: more specifically, I am trying to reproduce the following error in my assembly file:
Error: attempt to use an ARM instruction on a Thumb-only processor -- push {r1-r3,lr}
The LLVM compiler toolchain has a gcc that is compatible with normal gcc. The advantage of using llvm-gcc is that is goes to an arbitrary target, meaning normal gcc will say no such target when you try to compile to a random architecture, say mips-apple-darwin. llvm-gcc will, however, actually build a compiler for Mac OS X on a mips processor.
Here's the catch however: to build to a random target, you need the binutils built for that target already. So if you have a target that llvm would compile to but binutils can't, then you can't make the compiler because the GNU Binutils doesn't support that target.
So... Here's the question: Is there an equivalent llvm-binutils like an llvm-gcc that is compatable with GNU Binutils? (meaning one that builds to an arbitrary target, not one from a list.)
EDIT:
By arbitrary, I mean I don't pick the target when I run llvm-gcc, I pick the target when I compile llvm-gcc. Meaning: If I try to compile GCC for mips-apple-darwin, I get a target not supported. But If I build llvm-gcc for mips-apple-darwin, it works as long as I have mips-apple-darwin-as and mips-apple-darwin-ld.
As far as I can tell, LLVM does not compile for an arbitrary target. You must have all includes and definition to fit your target, and normally, llvm has a back-end to generate code for your said target. Read "Can I compile C or C++ code to platform-independent LLVM bitcode?" from http://llvm.org/docs/FAQ.html .
To answer the question, llvm does not uses GNU binutils, llvm has its own 'binutils' to generate code (called LLVM core project). Disassembler and debugger are part of LLDB project.
Where LLVM bring some independence, it's on the language level. Your project can be coded in C/C++, Ada, Fortran, etc ... llvm come with the ability to transform your code in an intermediate representation. That IR will eventually generate code.
llvm-gcc doesn't support arbitrary targets. llvm-gcc has to be built specifically for any given target. clang + LLVM can. I'm trying to do exactly that with ellcc: http://ellcc.org. I'm using binutils for assembly and linking.
I'm trying to migrate a project which uses Boost (particularly boost::thread and boost::asio) to VxWorks.
I can't get boost to compile using the vxworks gnu compiler. I figured that this wasn't going to be an issue as I'd seen patches on the boost trac that purport to make this possible, and since the vxworks compiler is part of the gnu tool chain I should be able to follow the directions in the boost docs for cross compilation.
I'm building on windows for a ppc vxworks.
I changed the user-config.jam file as specified in the boost docs, and used the target-os=linux option to bjam, but bjam appears to hang before it can compile. Closer inspection of the commands issued by bjam (by invoking it using the -n option) reveal that it's trying to compile with boost::thread's win32 files. This can't be right, as vxworks uses pthreads.
My bjam command: .\bjam --with-thread toolset=gcc-ppc target-os=linux gcc-ppc is set in user-config to point to the g++ppc vxworks cross compiler.
What am I doing wrong? I believe I have followed the docs to the letter.
If it's #including win32 headers instead of the pthread ones, there could be a discrepancy between the set of macros your compiler is defining and the macros the boost headers are checking for. I had a problem like that with the smart pointer headers, which in an older version of boost would check for __ppc but my compiler defined __ppc__ (or vice versa, can't remember).
touch empty.cpp
ccppc -dD -E empty.cpp
That will show you what macros are predefined by your compiler.
I never tried to compile boost for VxWorks, since I only needed a few of the headers.
Try also adding
threadapi=pthread
The documentation you mention is for Boost.Build -- which is standalone build tool -- and the above flag is something specific to Boost.Thread library. What do you mean by "hang"? Because Boost libraries are huge, it sometimes take a lot of time to scan dependencies prior to build.
If it actually hangs, can you catch bjam in a debugger and produce a backtrace? Also, log of any output will help.