OS Specific Toolchain: Difference between revisions

no edit summary
[unchecked revision][unchecked revision]
m (Ask GCC for target-default crti.o and crtn.o via extra_parts.)
No edit summary
Line 1:
{{Rating|3}}
 
This tutorial will guide you through creating a toolchain comprising binutilsBinutils and gccGCC that specifically targets your operating system. The instructions below teach binutilsBinutils and gccGCC how to create programs for a hypothetical OS named 'MyOS'.
 
Until now you have been using a [[GCC Cross-Compiler|cross-compiler]] configured to use an existing generic bare target. This is very convenient when starting out as you get a reliable target and the compiler doesn't make any bad assumptions because it thinks it is targeting an existing operating system. However, when you proceed it becomes useful if the compiler knows it is targeting your operating system and what its customs are. For instance, you can make the compiler define a <tt>__myos__</tt> preprocessor macro, know which directories to search for include files in, what special <tt>crt*.o</tt> files are used when linking against libc, and so on. It also becomes much easier to cross-compile software to your OS when you simply have to invoke <tt>x86_64-myos-gcc hello.c -o hello</tt> to cross-compile a program. Additionally part of the instructions here can be applied to other software packages that also use the GNU build system, which will help you [[Cross-Porting Software|port existing software]].
 
This tutorial teaches you how to set up a cross-compiler that specifically targets your OS. This is actually the first step of ''porting binutilsBinutils and gccGCC to your operating system'': Any information you give GCC about your OS will help it run on your OS. Once your OS Specific Toolchain has been set up and you have built your OS with it, you can continue by using the cross-compiler to cross-compile the compiler itself to your OS, assuming your libc and kernel is powerful enough. For more information see [[Porting GCC to your OS]].
 
== Introduction ==
Line 15:
* automake
* libtool
* The latest binutilsBinutils source code.
* The latest gccGCC source code.
* Knowledge of the internals of binutilsBinutils and gccGCC.
* Knowledge of autoconf and automake.
* The dependencies of binutilsBinutils and gccGCC as detailed in [[GCC Cross-Compiler]].
 
Additionally you will need a [[C Library]] as described in a later section. As detailed in [[Hosted GCC Cross-Compiler]], it doesn't need to support much and the functionality can be stubbed, but libgcc will need to believe you have a libc.
 
You should decide exactly what targets you'll add to binutilsBinutils and gccGCC. If you have been using a generic <tt>i686-elf</tt> or <tt>x86_64-elf</tt> or such target, you'll simply want to swap <tt>-elf</tt> with <tt>-myos</tt> and get <tt>i686-myos</tt> and <tt>x86_64-myos</tt>. Naturally, don't actually write myos, but rather use the name of your OS converted to lower case. See [[Target Triplet]].
 
This tutorial currently only have instructions for adding a new x86 and x86_64 target for myos, but it serves as a good enough example that it should be trivial to add more processors by basing it on these instructions and what other operating systems have done.
Line 35:
=== bfd/config.bfd ===
 
This file is part of the configuration for libbfd, the back-end to binutilsBinutils which provides a consistent interface for many object file formats. Generally, each platform-specific version of binutilsBinutils contains a libbfd which only supports the object files normally in use on that system, as otherwise the library would be massive (libbfd can support a _lot_ of object types). We need to associate our os with some particular object types. There is a long list starting 'WHEN ADDING ENTRIES TO THIS MATRIX' with the first line as 'case "${targ}" in'. We need to add our full canonical name to this list, by adding some cases such as:
 
<source lang="bash">
Line 152:
=== config.sub ===
 
Similar modification to config.sub in binutilsBinutils.
 
=== gcc/config.gcc ===
Line 188:
 
<source lang="C">
/* Useful if you wish to make target-specific gccGCC changes. */
#undef TARGET_MYOS
#define TARGET_MYOS 1
Line 197:
 
/* Files that are linked before user code.
The %s tells gccGCC to look for these files in the library directory. */
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
 
Line 268:
</source>
 
A number of operating systems (especially older and obscure ones) provide troublesome systems headers that fail to strictly comply with various standards. The GCC developers consider it their job to fix these headers. GCC will look into your system root, apply a bunch of patterns to detect headers it doesn't like, then it copies that header into a private gccGCC system directory (that overrides your standard system directory) and attempts to fix the header. Sometimes fixincludes even break working headers (some people refer to it as breakincludes).
 
This is rather inconvenient as your libc will likely happen to trigger these patterns (and false positives often happens). Any time you change your system headers, you have to rebuild your compiler so the fixed versions get updated. The first time you encounter this, it will show up as a system header that does nothing different even though you edit it.
Line 294:
=== Start Files Directory ===
 
You can modify which directory GCC looks for the crt0.o, crti.o and crtn.o in. The path to that directory is stored in <tt>STANDARD_STARTFILE_PREFIX</tt>. For instance, if you change the library directory to <tt>/lib</tt> in binutilsBinutils and want gccGCC to match, you can add the following to <tt>gcc/config/myos.h</tt>:
 
<source lang="C">
Anonymous user