Cross Compile Raspberry with external libraries - copying of target folders - c

I am cross compiling C-Code from Mac OS (Host) for a Raspberry Pi B+, running Raspbian Jessie, (Target). In order to link external libraries ("WiringPi" and "pthread") during make I have used a somewhat lazy approach of copying the relevant folders containing headers and libraries from the target (i.e. /lib/, /usr/include/, /usr/lib/, /usr/local/lib/, /usr/local/include/) to the host machine in advance.
My Cross GCC Compiler call is then modified as:
arm-linux-gnueabihf-gcc -I"/Path/to/copy/of/target-folders/.../usr/local/include" -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"main.d" -MT"main.o" -o "main.o" "../main.c"
The GCC Linker call is modified as:
arm-linux-gnueabihf-gcc --sysroot=/Path/to/copy/of/target-folders/ -o "BlinkLedCrossCompile" ./main.o -lWiringPi -lpthread
This uses the copied target folders as sysroot. And so far, it works without any problems.
My question is: Is this a valid approach? Can I expect any problems further on?

Related

How to Cross-Compile from LLVM IR to Assembly for ARM Cortex M4?

I'm trying to cross-compile an llvm-ir file to assembly, or better generate an object file, for an ARM Cortex M4 microprocessor using llc compiler.
Which are the parameters that I have to specify in order to do so?
I have tried with this command
llc -mtriple=armv7m-eabi -mcpu=cortex-m4 file.ll -o file.s
It doesn't throw any error but the assembly code generated is still for an x86 machine.
In particular, trying to compiling with random parameters, e.g.
llc -mtriple=randomwords -mcpu=cortex-m4 file.ll -o file.s
It goes smooth, producing an assembly code for the x86 machine. It ignores what I specify.
I found a solution, or better a work around to this problem.
Instead of using directly llc, first I've obtained the binary code through this command
llvm-as file.ll -o file.bc
An than I used clang to crosscompile and obtain the object file for ARM Cortex M4 using this instruction
clang --target=arm-none-eabi -march=armv7e-m -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -nostdlib file.bc -c -o file.o
The -c is used to compile only.
It is also possible to obtain the assembly code by using the following command line
clang -S --target=arm-none-eabi -march=armv7e-m -mcpu=cortex-m4 -mfpu=fpv4-sp-d16 -mfloat-abi=hard -mthumb -nostdlib file.bc -o file.s
llc (not sure about prior to v9) seems to only care about the architecture.
I can cross compile and link with the following script (for a RPI running Linux):
#/bin/sh
llc-9 -march=arm -float-abi=hard -O3 -filetype obj $1.ll -o $1.o
~/devel/musl/musl-cross-make/output/bin/arm-linux-musleabihf-gcc -mfloat-abi=hard -static $1.o -o $1
llc --version will show the available architectures
Try the following for your case (or use a more specific architecture if it is in the list):
llc -march=arm -mcpu=cortex-m4 -filetype obj file.ll -o file.o

clang links wrong ARM builtins in thumb mode

I am trying to build Cortex-M0 (ARMv6, thumb) firmware with clang 13.0. Everything seems fine except for builtin functions like __udivsi3, __udivmoddi4 that are in ARM mode. Of course the CPU only supports thumb and delivers a fault when trying to execute them. I know that these functions are wrong because the CPU faults, the debugger displays them as ARM mode and their addresses in the .elf have Lsb cleared. I am linking to newlib provided by gcc (v6 flavor of libc_nano.a) and the libc functions are correct (ie. thumb mode). Functions from my .c files are also correctly built in thumb mode and the firmware runs just fine until it encounters integer division.
My compile options:
clang -o some_file.o -c -MD --target=armv6m-none-eabi -nostdlib
--sysroot="/path/to/newlib/arm-none-eabi" -fshort-enums -mcpu=cortex-m0
-mthumb -mfloat-abi=soft -g3 -I ../some/includes -Oz -std=gnu11
-Wall -pipe -ffunction-sections -fdata-sections some_file.c
My linking options:
clang -o my_project.elf --target=armv6m-none-eabi -nostdlib
-L"/path/to/newlib/arm-none-eabi/lib/." "/path/to/newlib/lib/gcc/arm-none-eabi/9.2.1/libgcc.a"
"/path/to/newlib/arm-none-eabi/lib/thumb/v6-m/nofp/libc_nano.a"
-mcpu=cortex-m0 -mthumb -mfloat-abi=soft -g3 -Wl,--gc-sections
-T my_linker_script.ld object_file1.o object_file2.o object_file3.o -lm
The same happens when I try --target=arm-none-eabi or -mtune=cortex-m0. I am using clang 13.0.0 (official binaries from github). I tried building on both Windows and Linux machines. Clang lists cortex-m0 as available for target arm-none-eabi. llc lists thumb in the list of targets (and all my own functions are correctly built in thumb mode).
What am I doing wrong?
Thanks for help
I traced it down to the wrong libgcc.a being linked. I did not provide the correct architecture/thumb flags when executing arm-none-eabi-gcc -print-libgcc-file-name and it supplied the default version of that library build in ARM mode.

how to link the openssl library with the arm-cross compiler

I have application test.c which by using gcc on host(on ubuntu) machine i have succeed in compilation and successfully ran the application program on host.
now I would like to cross compile the same application with arm-cross compiler for LPC1788. please guide me how to link the openssl library files
My Mkakefile with GCC
CC = gcc
CFLAGS = -D__XMLSEC_FUNCTION__=__FUNCTION__ -DXMLSEC_NO_XKMS=1
-DXMLSEC_NO_CRYPTO_DYNAMIC_LOADING=1 -I/usr/include/xmlsec1
-I/usr/include/libxml2 -DXMLSEC_OPENSSL_097=1
-DXMLSEC_CRYPTO_OPENSSL=1 -DXMLSEC_CRYPTO=\"openssl\ -DUNIX_SOCKETS -D XML_SECURITY
LDFLAGS = -lcrypto -I/usr/include/libxml2 -lxml2 -I/usr/include/xmlsec1 -lxmlsec1
all:
$(CC) src/test.c -o test $(CFLAGS) $(LDFLAGS)
by changing the compiler I used the following Makefile
CC = /home/amarayya/doc/tools/arm-2010q1/bin/arm-uclinuxeabi-gcc
CFLAGS = -D__XMLSEC_FUNCTION__=__FUNCTION__ -DXMLSEC_NO_XKMS=1
-DXMLSEC_NO_CRYPTO_DYNAMIC_LOADING=1 -I/usr/include/xmlsec1
-I/usr/include/libxml2 -DXMLSEC_OPENSSL_097=1
-DXMLSEC_CRYPTO_OPENSSL=1 -DXMLSEC_CRYPTO=\"openssl\ -DUNIX_SOCKETS -D XML_SECURITY
LDFLAGS = -lcrypto -L/usr/include/libxml2 -lxml2 -L/usr/include/xmlsec1 -lxmlsec1
all:
$(CC) src/test.c -o test $(CFLAGS) $(LDFLAGS)
which leading to these errors
fatal error: openssl/rsa.h: No such file or directory
fatal error: openssl/rsa.h: No such file or directory
what causing these errors and how to over come
You cannot use your host libraries when compiling for a different architecture. First, you need to cross compile all non-standard libraries (libxml, libopenssl) for your target machine (i.e. ARM).
Basically, you need to download the source code for these libraries and configure it with
--host=arm-uclinuxeabi --prefix=SOME_HOST_DIR
(or something similar - you might check the README files)
assuming, that you have your cross compiler in PATH.
These libraries might also require more libraries to be cross compiled.
When compiling your application you should use these cross compiled libraries.

Is it possible to link bitcode with llvm-ar archieve into a single bitcode file?

I have read this thread on llvm-dev and is faced with the same problem: I cannot link the llvm-ar archieve library with other bitcode files into another single bitcode file with the help of llvm-link.
clang -emit-llvm -g -c -o main.bc main.c
clang -emit-llvm -g -c -o calc.bc calc.c
llvm-ar rcs libcalc.la calc.bc
llvm-link libcalc.la main.bc -o test
the problem is the same: llvm-link complains
llvm-link: libcalc.la:1:2: error: expected integer
!<arch>
^
And after reading How to link object to libraries with LLVM >= 3.1 ? ( no GNU ld ), I also tried a llvm2.9 version of llvm-ld.
llvm-ld --disable-opt libcalc.la main.bc -o test
however libcalc.la is not linked into the module correctly and lli reports:
LLVM ERROR: Program used external function 'Square' which could not be resolved!
So what should i do?
UPDATE
I then read Can't link against static library when compiling objects from LLVM bitcode. and find that llvm-ld WORKS when changing the order:
llvm-ld --disable-opt main.bc libcalc.la -o test
But llvm-link still fails.
llvm-link does not support bitcode archives, AFAIK. It simply goes over the input files it was provided, and tries to parse each one as a bitcode file (either binary or textual LLVM IR).
llvm-ld doesn't exist in the newer LLVMs, so I would suggest to stay away from it completely.
Just link the separate .bc files together with llvm-link. The archiving of bitcode files doesn't have the same benefits for the linker as in native linking anyway.
You don't need archivers to link your bitcode files:
clang -emit-llvm -g -c -o main.bc main.c
clang -emit-llvm -g -c -o calc.bc calc.c
clang main.bc calc.bc -o test

Cannot compile using ALSA

I am trying to create an C application on Debian GNU/Linux which uses the PortAudio interface. To do this I must compile my program with gcc -lrt -lasound -ljack -lpthread -o YOUR_BINARY main.c libportaudio.a from this docs.
For this I installed libasound2-dev, and I checked where the files are using apt-file search libasound.so, this is the output:
lib32asound2: /usr/lib32/libasound.so.2
lib32asound2: /usr/lib32/libasound.so.2.0.0
lib32asound2-dev: /usr/lib32/libasound.so
libasound2: /usr/lib/x86_64-linux-gnu/libasound.so.2
libasound2: /usr/lib/x86_64-linux-gnu/libasound.so.2.0.0
libasound2-dev: /usr/lib/x86_64-linux-gnu/libasound.so
So the libasound should be installed correctly, but when I compile my program with this makefile:
DMXTest: main.c libdmx.a
gcc -static -Wall main.c -L. -ldmx -lusb -lrt -lasound -ljack -lfftw3 -g -o main libportaudio.a
I get the following error: /usr/bin/ld: cannot find -lasound.
How can I link this library correctly?
You don't have libasound.a for -static, you will need that, or you can almost certainly just remove -static from the Makefile (likely in LDFLAGS or CFLAGS).
There's is a related Debian bug 522544, and a related Ubuntu bug #993959.
You may be able to build your own libasound from source, though as it also uses other libraries (notably libpthread.so, librt.so and libdl.so) I suspect it may remove some functionality when you build it statically, though it's supported with ./configure --enable-static at build time
(or try --enable-shared=no --enable-static=yes).
FWIW, the use of static binaries is "discouraged" by the glibc maintainers, though I don't agree...
To compile my code i used the following command
gcc -o rec_mic rec_mic.c -lasound
and it works perfectly, without create my own static library.

Resources