Search code examples
c++cgcccross-compilingcrosstool-ng

How to use candian in Crosstools-NG in a cross-native fashion to get gcc on an arm board?


As I understand, to have gcc on an armv5 board compiling executables while using my x86 machine to compile that arm native gcc, I need this setup:

  • Machine configuring the toolchain components: the config machine : x86_64
  • Machine building the toolchain components: the build machine : x86_64
  • Machine running the toolchain: the host machine : ARM
  • Machine the toolchain is generating code for: the target machine : ARM

Based on reading the cross-ng docs here, I should use a cross-native setup, but when I attempt to enable that using ct-ng menuconfig I need to enable:

  • experimental in Paths and misc options -> Try features marked as EXPERIMENTAL

  • Toolchain options -> Type (Cross) -> Cross-native (NO CODE!) (EXPERIMENTAL)

But of course Cross-Native doesn't work since there is no code for it. Googling leads me to this and this discussion on a mailing list saying that I should try to do this using a Canadian build style but I am somewhat lost as to what tuple's and whatnot to use for the Build System and Host System in crosstool-ng's menuconfig, or if this is still the correct way to go considering how both discussions are over 3 years old.

This post on SO seems to imply that the build system and host system tuples should be arm-unknown-linux-gnueabi?

To be clear, I have been able to compile and run executables using a cross compiler generated from crosstool-ng already, now I want to have a compiler on that armv5 system.

Edit: So I just added the normal cross compiler (arm-unknown-linux-gnueabi) generated by crosstools-ng to the tuple in Toolchain options -> General toolchain options -> Host system -> Tuple and was able to compile gcc as well as have it execute on the arm. Example

I now just need to fix the library situation and that should be that.


Solution

  • This answer is an extension of my original question regarding the general workflow for cross compiling a toolchain.

    I had the correct general idea, you have to do a Canadian-Build with the host system tuple being the arm-unknown-linux-gnueabi cross compiler I made earlier. Make sure to include it to your path or do some symlinking into /bin or however else you want to handle that.

    I had to wait roughly 30 minutes when doing the build using 3/4 cores of an I5-3570k and ~2GB of ram in a Ubuntu Vmware virtual machine using a normal HDD. Using a SSD will probably bump the speed up significantly.

    Once this is done, you should be have an output directory that Crosstools-NG made for you which includes the toolchain for the ARM architectre. You can verify this by running file filename on any of the binaries.

    Now, for the library situation which took me a while and gave a decent bit of confusion. In the toolchain output there should be a rootfs folder. That folder contains the expected root file system of the target for which you will be compiling (in this case arm). You need to copy the /lib folder as well as lib's from the user, mirroring the folder hierarchy of this rootfs folder.

    You can verify if you have the libraries setup right by doing objdump -p filename and seeing the NEEDED entries which point to required libraries which should be in the rootfs.

    If you are using a busybox based rootfs, then assuming you didn't statically compile it then you probably already have the libraries setup correctly since you needed them for busybox. I did a static build of busybox first to make sure I can get the system to boot to a shell, and then made a nonstatic build to have a soft start for libraries, using the libraries from the toolchains rootfs folder. Once I got a dynamically linked busybox system working, simply dropping the cross compiled toolchain into your rootfs at an arbitrary location (/usr/home/toolchain for me) should suffice, after which you should use the toolchain just the same as for an x86 system referring to path and symlinks and whatever you want to do.