CMake: adding a compiler flag in a toolchain file - c

I'm trying to compile a single codebase for both ArmV8 aarch64 and aarch32 with GCC. My code requires the -mfloat-abi=hard flag and possibly others when compiled for aarch32, but not for aarch64.
I have multiple toolchains so I created two toolchain files.
What's the most idiomatic CMake way to add this flag only when the aarch32 toolchain file is used?
Of course I could do this inside the project CMakeLists.txt file, at the point where I already created the target and I'm setting other compiler flags.
But then I would have to add this flag conditionally depending on the toolchain, which seems to defeat the point of having two neatly separated toolchain files.

Related

How to cross compile GSL library for arm-none-eabi-gcc?

I need to use the GSL library in my program on LPCXpresso 4367(ARM CORTEX M4). I tried to follow the library linking procedure for LPC xpresso but the MCU linker is giving me these errors:
MCUXpressoIDE_10.3.0_2200\workspace\test1\Debug/../src/test1.c:53: undefined reference to 'gsl_linalg_LU_decomp'
MCUXpressoIDE_10.3.0_2200\workspace\test1\Debug/../src/test1.c:56: undefined reference to 'gsl_matrix_alloc'
MCUXpressoIDE_10.3.0_2200\workspace\test1\Debug/../src/test1.c:57: undefined reference to 'gsl_linalg_LU_invert'
and so on for other functions as well.
I have the libgsl.a and libgslcblas.a precompiled libraries for windows which works perfectly on codeblocks on windows with GCC compiler.
I read that I need to crosscompile library for the arm-none-eabi-gcc toolchain. But can someone please provide me the procedure as well?
the libgsl.a and libgslcblas.a precompiled libraries for windows
Those won't do for ARM.
In order to work on another platform, these libs need to be compiled from source code with the proper compiler (and settings - Cortex-M4F requires Thumb2 instruction set).
As the libraries are precompiled for Windows they don't work for ARM (as it is said in the other answer)
You need to cross compile the libraries first. If you install the GSL libraries following this procedure, you only need to change the parameters in the ./config according to your platform, for example I used:
./config --host=arm-linux-gnueabihf --prefix=/home/yourname/gsl_arm
Inside the .zip file with the gsl-2.5 files, there is a file called INSTALL. There you can find more details on the options for cross compiling.
Make sure to make clean before if you have already compiled the library for different settings. After cross-compiling the library when you run make check on the terminal you will probably get errors, but still it works. Continue with make install and you are ready to use it.

How to generate the assembly output which has arm instruction set

i have a windows machine(intel processor) and gcc installed.
gcc -save-temps "filename.c"
generated the intermediate files and i viewed the assembly file (.s file)
which is intel x86 instructions.
my question is how to generate the assembly which is ARM instruction set architecture equivalent on the same machine?
gcc is always built for a single target. https://developer.arm.com/open-source/gnu-toolchain is where you get your arm-gcc cross-compiler toolchain. Clang on the other hand can generate code for multiple targets.
Both are available on https://www.godbolt.org to see the assembly directly.

Converting C source to ARM assembly

I am trying to convert .c files for ARM (ARMv7l for Raspberry Pi2) but I could not find any online converter or understand how it works. Previously these .c files were executable in Windows platform and thus unable to execute on Pi's arm architecture. Does anybody can assist me in this?
Any c compiler can generate assembly code from C code, if your objective is specifically to generate assembly code for arm then you'll need a cross compiler such as the GNU arm embedded toolchain.
For gcc on particular you just need to use the -S option when compiling, so the line looks something like:
gcc -S -source.c -o output.s
Of course you'll need to include any headers and include directories for it to compile.
if you simply want to cross compile it, then simply do the full compilation assemblage and linking process. Depending on how low level the c code is it's actually possible for it not to work on the pi 2 (but it will compile)

building binutils before gcc compiler

I am trying to build a gcc cross compiler. I understand that before compiling the cross compiler I need to have the target binutils built already. why the building of the compiler need the target binutils ? the compiler alone only takes high level code and turn it to the assembly that I defined it in the compiler sources. so why do I need the target bintools for compiling the cross compiler ? It is written in all of the cross compiler documentation that I need them to be build before compiling the cross compiler. (e.g. http://wiki.osdev.org/Building_GCC and http://www.ifp.illinois.edu/~nakazato/tips/xgcc.html).
GCC needs an assembler to transform the assembly it generates into object files (machine code), and a linker to link object files together to produce executables and shared libraries. It also needs an archiver to produce static libraries/archives.
Those three are usually provided by the binutils package (among other useful tools): the GNU assembler as, linker ld and the ar archiver.
Your key question seems to be:
why the building of the compiler need the target binutils ?
As described in Building a cross compiler, part of the build process for a GNU cross-compiler is to build runtime libraries for the target using the newly-compiled cross-compiler. So the binutils for the target need to be present for that step to succeed.
It may be possible to build the cross-compiler first, using empty files for the subset of binutils components that gcc needs - such as as and ld and ar and ranlib - then build and install the target binutils components into the proper locations, then build the target runtime libraries.
But it would be less error-prone to do things the following way (and the documentation recommends this): build binutils for the target first, place the specified executables in gcc's source tree, then build the cross-compiler.
The binutils (binary utilities) provide low-level handling of
binary files, such as linking, assembling, and parsing ELF files. The GCC
compiler depends on these tools to create an executable, because it generates
object files that binutils assemble into an executable image.
ELF is the format that Linux uses for binary executable
files. The GCC compiler relies on binutils to provide much of the platform-specific functionality.
Here your are cross-compiling for some other architecture not for x86. So resulting binutils are platform-specific
while configuring has to give --host!=target. i.e --host=i686-pc-linux-gnu
where --target=arm-none-linux-gnueabi.
So resulting executable are not same which host already having binutils.
addition
the basic things needs to be known.
The build machine, where the toolchain is built.
The host machine, where the toolchain will be executed.
The target machine, where the binaries created by the
toolchain are executed.
So binutils will be having tools to generate and manipulate binaries
for a given CPU architecture. Not for the one host is using

Comparing ELF/binary files generated from different versions of a toolchain

I have two binary files generated via 'objcopy -O binary' from respective ELF files. The ELF files are built with arm-none-linux-gnueabi toolchains; one is from linaro gcc 4.6.2 and other is from codesourcery gcc 4.6.3.
I load the binary files into memory via Uboot. While the one built with Linaro executes as expected the one built with codesourcery crashes (most probably as) there is no error on Uboot prompt but the program seems to hang.
Using 'arm-none-linux-gnueabi-readelf -S' from binutils of respective toolchains does not show much difference between files except for address offsets. Are there any tools/techniques that can help in this kind of situation before I attempt runtime debugging on target.
Thanks!
The difference turned out to be compiler option -munaligned-access. Code Sourcery toolchain enables this by default for ARMv6 and later architectures.
http://gcc.gnu.org/gcc-4.7/changes.html
Although this appeared in upstream gcc in 4.7 version, Code Sourcery had added this support earlier in their tool chain.
To figure this out I tracked the data abort exception and then compiled the culprit file with -save-temps options. Comparing intermediate .s file provided the hint.
What I can advice you is to compare default flags both compilers were built with:
/path/to/cross-compiler/bin/arm-*-*-gcc -Q -v
And preprocessor definitions:
/path/to/cross-compiler/bin/arm-*-*-gcc -dM -E - < /dev/null
The reason why your code compiled using Linaro GCC works is fact, that
it may have some options enabled by default, when CodeSourcery one
may have not.

Resources