Thumbs up! Short video, really good information. I'm a 30+ year developer but just now getting started on bare metal programming on the Raspberry Pi - no linux on the target system, just booting into my (kernel) code on the target (Pi 4B+). I am in no way an experienced Pi or ARM developer so vids like this are priceless. Thanks!
Magic, I found all the GCC documentation confusing and spent hours trying to get the ARM compiler working, followed this to the letter and now working perfectly........Many Thanks
Was trying to cross-compile some C/C++ code to ARM assembly on an x86 Ubuntu machine and the docs just weren't cutting it. Super helpful video, thanks a ton!
sir thank you for the great content! In this example, it seems that the executable file hello_arm is dynamically linked shown in the description got from the file command I wonder if we run it on the target, does it throw any dependency error. if I need to compile it statically so that it runs without error, how to compile it statically linked?
You are correct. If the executable is dynamically linked, then any dynamic library (.so) that it is dependent on will need to reside on the target machine. Depending on your design goals, you may or may not want to do this. To compile statically, you can just add the -static option when you compile and it will attempt to compile the program using static libraries. Just note that you will have to have the corresponding static library (.a) on your host system for any libraries you want to link in statically. Check out my video on static and dynamic linking for more info on that: ruclips.net/video/UdMRcJwvWIY/видео.html You can also pass Bstatic and Bdynamic options to the linker (ld) using the -Wl switch with gcc. You follow those switches with what libraries that you want to link in. In this way, you can compile in some libraries statically and dynamically with others. For example, if you want to statically compile any references to libsomething but dynamically with libc, you could try something like this (not tested): gcc source.c -Wl,-Bstatic -lsomething -Wl,-Bdynamic -lc -o output Just make sure you also use the -I option (capital i) to specify include directories where your header files are located if they are in a non-standard location. I've also heard you can use -l: when specifying the library and you just give the full library name, so something like this (also untested): gcc source.c -l:libsomething.a -o output I have never tried this though. Also be aware, as other viewers have pointed out in the comments, compiling statically with the c library can be problematic depending on what your program does and you may run into come challenges at compile time and at run time.
Most of the time you will pass in the name of the cross-compiler as an environment variable to make and Configure commands. For example, for openssl, from inside the build directory you would give the command: CC=${NAME_OF_CROSS_COMPILER} ./Configure [configuration options] and then to build: CC=${NAME_OF_CROSS_COMPILER} make Keep in mind, the location of your cross-compiler has to be on your Linux path, or NAME_OF_CROSS_COMPILER would have to explicitly state the absolute path. Every library is different. Some libraries have you pass in the cross compiler as a command line option rather than as an environment variable. In this case, you would do something like: make CC=${NAME_OF_CROSS_COMPILER} I believe this is the case for zlib. In the past, I have cross-compiled zlib like this: CC=${NAME_OF_CROSS_COMPILER} ./configure --enable-shared --prefix[LOCAL_LIBRARY_DIRECTORY] make CC=${NAME_OF_CROSS_COMPILER} make CC=${NAME_OF_CROSS_COMPILER} install One other thing to keep in mind. Whenever you run "make install", make certain that you have specified where to install the compiled binaries. Depending on the make files, you will use the --prefix option in the configure command or you may specify DESTDIR=${INSTALL_DIR} as command line option to make to point to where you want to install the compiled libraries: CC=${NAME_OF_CROSS_COMPILER} make DESTDIR=${INSTALL_DIR} install If you don't do this, it will install on the local machine in the default directory which may overwrite libraries that already exist on your host system and you don't want that.
by the way. i v a question that how Python export to bin. iv been searched for a long time.. but the way is not what I want.. I want just like Linux native bin to compile the Python code.. thx...
The compilers I talk about in this video are all 32-bit compilers. You would need the 64-bit compiler. If you are running the cross-compiler on Ubuntu Linux, you want to look for gcc-aarch64-linux-gnu, you can install it with apt. You can also check out the cross-compilers provided by Bootlin here: toolchains.bootlin.com/ They have a 64-bit cross-compiler (aarch64). It looks like the Pi 4b uses the Cortex A72 which does have floating point hardware, but I'm not sure if there are any 64-bit ARM compilers that do software float anyway. Keep in mind that all of the other support development packages you download may need to be 64-bit versions as well like binutils, libc dev libraries, etc. I'm not certain, just something to look into.
Very good video. Thanks a lot. Could you please make a video about transferring the compiled file to the embedded linux (target machine) and for remote debugging? That would be great!
Thanks for the feedback. I will likely include that in some future video. In general, you would make this binary part of the root file system. The root file system is written into non-volatile memory (like NAND flash). When the system boots up, the bootloader is responsible for copying the root file system from permanent flash into RAM and telling the Linux kernel where it is. If you already have a running kernel and just want to copy the file over, then you should be able to connect to a terminal via serial connection or ssh and then just do a secure copy (scp) from host to the target, but you would have to do the copy every time you reset the device.
The aarch64 compilers should have armv8. You can use the options --mabi and --march to specify what you want --mabi=ilp32 specifies to use the 32-bit version if that is what you wanrt --march='armv8-a' gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/AArch64-Options.html If you have the normal 32-bit cross-compiler then you should be able to just specify --march='armv8-a', but I have never tested that.
@@embeddedarmdev Check out: developer.arm.com/ tools-and-software/ open-source-software/ developer-tools/ gnu-toolchain/ gnu-a/ downloads (Remove the extra space after the slashes - I added the space(s) so the link wouldn't be flagged.) These are gcc cross-compilers and tools for ARM development.
Realy interresting video. I tryed out myselve with a raspberry pi 3b+ and an quite old amd sempron x86 with lubuntu 18.4. I discovert that i can actualy run the cross compiled code on both maschienes but i realy dont know why. The only difference was that i used static linking (-static). Maybe someone can explane this to me.
Wow... This is the best video.
I was exhausted reading for this thing. Thanks man
I read a couple of tutorials about this topic. Most of them do not work. The way presented in your video is easy and works very well. Thanks a lot.
lovely... had a hard time installing cross compiler till i found this vedio. NOW I can start on embedded programming
Great! I'm glad the video was helpful to you.
Thumbs up! Short video, really good information. I'm a 30+ year developer but just now getting started on bare metal programming on the Raspberry Pi - no linux on the target system, just booting into my (kernel) code on the target (Pi 4B+). I am in no way an experienced Pi or ARM developer so vids like this are priceless. Thanks!
Magic, I found all the GCC documentation confusing and spent hours trying to get the ARM compiler working, followed this to the letter and now working perfectly........Many Thanks
Was trying to cross-compile some C/C++ code to ARM assembly on an x86 Ubuntu machine and the docs just weren't cutting it. Super helpful video, thanks a ton!
Glad it helped!
Nice tutorial!! Thank you so much
absolutely great explanation Thanks
Quite helpful :) ... this could be extended to include a simple qemu tutorial to run those Arm executables ...
what a nice course...so nice
very useful, thanks much!
Great video! Tnx.
How can I compile my application using cross-compile g++ that generate a EABI4 output ELF?
sir thank you for the great content!
In this example, it seems that the executable file hello_arm is dynamically linked shown in the description got from the file command
I wonder if we run it on the target, does it throw any dependency error. if I need to compile it statically so that it runs without error, how to compile it statically linked?
You are correct. If the executable is dynamically linked, then any dynamic library (.so) that it is dependent on will need to reside on the target machine. Depending on your design goals, you may or may not want to do this.
To compile statically, you can just add the -static option when you compile and it will attempt to compile the program using static libraries. Just note that you will have to have the corresponding static library (.a) on your host system for any libraries you want to link in statically. Check out my video on static and dynamic linking for more info on that:
ruclips.net/video/UdMRcJwvWIY/видео.html
You can also pass Bstatic and Bdynamic options to the linker (ld) using the -Wl switch with gcc. You follow those switches with what libraries that you want to link in. In this way, you can compile in some libraries statically and dynamically with others.
For example, if you want to statically compile any references to libsomething but dynamically with libc, you could try something like this (not tested):
gcc source.c -Wl,-Bstatic -lsomething -Wl,-Bdynamic -lc -o output
Just make sure you also use the -I option (capital i) to specify include directories where your header files are located if they are in a non-standard location.
I've also heard you can use -l: when specifying the library and you just give the full library name, so something like this (also untested):
gcc source.c -l:libsomething.a -o output
I have never tried this though.
Also be aware, as other viewers have pointed out in the comments, compiling statically with the c library can be problematic depending on what your program does and you may run into come challenges at compile time and at run time.
Do you have similar cross compiler for riscv32 CPU ? can you please share commands to install?
You can compile it for yourself
Thank's
very very great
nice video, anyway how can we cross cimpile library such as libcurl with openssl or zlib for ARM
Most of the time you will pass in the name of the cross-compiler as an environment variable to make and Configure commands. For example, for openssl, from inside the build directory you would give the command:
CC=${NAME_OF_CROSS_COMPILER} ./Configure [configuration options]
and then to build:
CC=${NAME_OF_CROSS_COMPILER} make
Keep in mind, the location of your cross-compiler has to be on your Linux path, or NAME_OF_CROSS_COMPILER would have to explicitly state the absolute path.
Every library is different. Some libraries have you pass in the cross compiler as a command line option rather than as an environment variable. In this case, you would do something like:
make CC=${NAME_OF_CROSS_COMPILER}
I believe this is the case for zlib. In the past, I have cross-compiled zlib like this:
CC=${NAME_OF_CROSS_COMPILER} ./configure --enable-shared --prefix[LOCAL_LIBRARY_DIRECTORY]
make CC=${NAME_OF_CROSS_COMPILER}
make CC=${NAME_OF_CROSS_COMPILER} install
One other thing to keep in mind. Whenever you run "make install", make certain that you have specified where to install the compiled binaries. Depending on the make files, you will use the --prefix option in the configure command or you may specify DESTDIR=${INSTALL_DIR} as command line option to make to point to where you want to install the compiled libraries:
CC=${NAME_OF_CROSS_COMPILER} make DESTDIR=${INSTALL_DIR} install
If you don't do this, it will install on the local machine in the default directory which may overwrite libraries that already exist on your host system and you don't want that.
by the way. i v a question that how Python export to bin.
iv been searched for a long time..
but the way is not what I want..
I want just like Linux native bin to compile the Python code..
thx...
hey just a general question, can i use these compilers to develop on rasberry pi 4b, its 64bit cpu but im not sure about hardware float
The compilers I talk about in this video are all 32-bit compilers. You would need the 64-bit compiler. If you are running the cross-compiler on Ubuntu Linux, you want to look for gcc-aarch64-linux-gnu, you can install it with apt.
You can also check out the cross-compilers provided by Bootlin here: toolchains.bootlin.com/
They have a 64-bit cross-compiler (aarch64).
It looks like the Pi 4b uses the Cortex A72 which does have floating point hardware, but I'm not sure if there are any 64-bit ARM compilers that do software float anyway.
Keep in mind that all of the other support development packages you download may need to be 64-bit versions as well like binutils, libc dev libraries, etc. I'm not certain, just something to look into.
Thank you .
Very good video. Thanks a lot. Could you please make a video about transferring the compiled file to the embedded linux (target machine) and for remote debugging?
That would be great!
Thanks for the feedback. I will likely include that in some future video.
In general, you would make this binary part of the root file system. The root file system is written into non-volatile memory (like NAND flash). When the system boots up, the bootloader is responsible for copying the root file system from permanent flash into RAM and telling the Linux kernel where it is.
If you already have a running kernel and just want to copy the file over, then you should be able to connect to a terminal via serial connection or ssh and then just do a secure copy (scp) from host to the target, but you would have to do the copy every time you reset the device.
Thanks dude, but do you know how to get a cross compiler for ARMv8 , doesn't care if it's for C++ or C
The aarch64 compilers should have armv8. You can use the options --mabi and --march to specify what you want
--mabi=ilp32 specifies to use the 32-bit version if that is what you wanrt
--march='armv8-a'
gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/AArch64-Options.html
If you have the normal 32-bit cross-compiler then you should be able to just specify --march='armv8-a', but I have never tested that.
@@embeddedarmdev Check out: developer.arm.com/ tools-and-software/ open-source-software/ developer-tools/ gnu-toolchain/ gnu-a/ downloads
(Remove the extra space after the slashes - I added the space(s) so the link wouldn't be flagged.)
These are gcc cross-compilers and tools for ARM development.
Realy interresting video. I tryed out myselve with a raspberry pi 3b+ and an quite old amd sempron x86 with lubuntu 18.4. I discovert that i can actualy run the cross compiled code on both maschienes but i realy dont know why. The only difference was that i used static linking (-static). Maybe someone can explane this to me.
Alex,
I can't explain this. The cross-compiled ARM binary should not be executable on both an ARM and x86 machine.
@@embeddedarmdev wierd but thanks anyway :)