Why do I need a Cross Compiler?: Difference between revisions

m
Added source tags
[unchecked revision][unchecked revision]
(Update rationale for cross-compilation with recommendations and problems that happen without one)
m (Added source tags)
Line 3:
It is possible ask your compiler what target platform it is currently using by calling the command:
 
<source lang="Cbash">
gcc -dumpmachine
</source>
 
If you are developing on 64-bit Linux, then you will get a response such as 'x86_64-unknown-linux-gnu'. This means that the compiler thinks it is creating code for Linux. If you use this gcc to build your kernel, it will use your system libraries, headers, the Linux libgcc, and it will make a lot of problematic Linux assumptions. If you use a [[GCC_Cross-Compiler|cross-compiler]] such as i585-elf-gcc, then you get a response back such as 'i586-elf' that means the compiler knows it is doing something else and you can avoid a lot of problems easily and properly.
Line 19 ⟶ 21:
 
== Using cross-tools ==
You get a lot of useful programs when you build your cross-binutillsbinutils. For instance, you get i586-elf-readelf, i586-elf-as, i586-elf-objdump, i586-elf-objcopy, and more. These programs know about your operating system and handle everything correctly. You can use some the programs that come with your local operating system instead (readelf, objcopy, objdump) if they know about the file format of your operating system, but it is in general best to use your cross tools instead. These tools all consistently have the prefix 'i586-elf-' if the platform of your OS is i586-elf.
 
== Options that you should pass to your Compiler ==
Line 68 ⟶ 70:
The compiler assumes it is targetting your local system, so you need a lot of options to make it behave. A trimmed down command sequence for compiling a kernel without a cross-compiler could look like this:
 
<source lang="bash">
as -32 boot.s -o boot.o
gcc -m32 kernel.c -o kernel.o -ffreestanding -nostdinc
gcc -m32 my-libgcc-reimplemenation.c -o my-libgcc-reimplemenation.o -ffreestanding
gcc -m32 -T link.ld boot.o kernel.o my-libgcc-reimplemenation.o -o kernel.bin -nostdlib -ffreestanding
</source>
 
Actually, the average case is worse. People tend to add many more problematic or redundant options. With a real cross-compiler, the command sequence could look this this:
 
<source lang="bash">
i586-elf-as boot.s -o boot.o
i586-elf-gcc kernel.c -o kernel.o -ffreestanding
i586-elf-gcc -T link.ld boot.o kernel.o -o kernel.bin -nostdlib -ffreestanding -lgcc
</source>
 
=== Reimplementing libgcc ===
Line 88 ⟶ 94:
You need to pass even more options to the command lines that build programs for your operating systems. You need a -Ipath/to/myos/include and -Lpath/to/myos/lib to use the C library, and more. If you set up an OS-specific toolchain, you just need
 
<source lang="bash">
i586-myos-gcc hello.c -o hello
</source>
 
to cross-compile the hello world program to your operating system.
Line 134 ⟶ 142:
If you create a real operating system and manage to port gcc to it, that gcc will produce the very same code as i586-myos-gcc. That means that you don't need a cross-compiler on your own operating system, because the gcc there will already do the right thing. This is why the Linux kernel is built with the Linux gcc, instead of a Linux cross-compiler.
 
=== A further concretionconcrete example ===
 
A paste of '*gcc -v'* from my Ubuntu machine gives:
 
<tt>
<source lang="C">
gravaera@gravaera-laptop:/void/cygwin/osdev/zbz$ gcc -v
Using built-in specs.
Line 151 ⟶ 159:
Thread model: posix
gcc version 4.4.3 (Ubuntu 4.4.3-4ubuntu5)
</sourcett>
 
The person who built the compiler that runs on my machine built it on a machine just like mine, an 'i486-linux-gnu' (build), and intended for it to run on a machine like his/mine: the same i486-linux-gnu (host), and he meant for this compiler he was building for me, to emit executables that targeted my very machine, so that when I compile programs, they will be able to run on a host that is i486-linux-gnu. Therefore he made the compiler target i486-linux-gnu.
Anonymous user