OS Specific Toolchain: Difference between revisions

Jump to navigation Jump to search
[unchecked revision][unchecked revision]
Content deleted Content added
m Ask GCC for target-default crti.o and crtn.o via extra_parts.
No edit summary
Line 1: Line 1:
{{Rating|3}}
{{Rating|3}}


This tutorial will guide you through creating a toolchain comprising binutils and gcc that specifically targets your operating system. The instructions below teach binutils and gcc how to create programs for a hypothetical OS named 'MyOS'.
This tutorial will guide you through creating a toolchain comprising Binutils and GCC that specifically targets your operating system. The instructions below teach Binutils and GCC 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]].
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 binutils and gcc 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]].
This tutorial teaches you how to set up a cross-compiler that specifically targets your OS. This is actually the first step of ''porting Binutils and GCC 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 ==
== Introduction ==
Line 15: Line 15:
* automake
* automake
* libtool
* libtool
* The latest binutils source code.
* The latest Binutils source code.
* The latest gcc source code.
* The latest GCC source code.
* Knowledge of the internals of binutils and gcc.
* Knowledge of the internals of Binutils and GCC.
* Knowledge of autoconf and automake.
* Knowledge of autoconf and automake.
* The dependencies of binutils and gcc as detailed in [[GCC Cross-Compiler]].
* The dependencies of Binutils and GCC 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.
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 binutils and gcc. 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]].
You should decide exactly what targets you'll add to Binutils and GCC. 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.
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: Line 35:
=== bfd/config.bfd ===
=== bfd/config.bfd ===


This file is part of the configuration for libbfd, the back-end to binutils which provides a consistent interface for many object file formats. Generally, each platform-specific version of binutils 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:
This file is part of the configuration for libbfd, the back-end to Binutils which provides a consistent interface for many object file formats. Generally, each platform-specific version of Binutils 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">
<source lang="bash">
Line 152: Line 152:
=== config.sub ===
=== config.sub ===


Similar modification to config.sub in binutils.
Similar modification to config.sub in Binutils.


=== gcc/config.gcc ===
=== gcc/config.gcc ===
Line 188: Line 188:


<source lang="C">
<source lang="C">
/* Useful if you wish to make target-specific gcc changes. */
/* Useful if you wish to make target-specific GCC changes. */
#undef TARGET_MYOS
#undef TARGET_MYOS
#define TARGET_MYOS 1
#define TARGET_MYOS 1
Line 197: Line 197:


/* Files that are linked before user code.
/* Files that are linked before user code.
The %s tells gcc to look for these files in the library directory. */
The %s tells GCC to look for these files in the library directory. */
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"
#define STARTFILE_SPEC "crt0.o%s crti.o%s crtbegin.o%s"


Line 268: Line 268:
</source>
</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 gcc 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).
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 GCC 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.
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: Line 294:
=== Start Files Directory ===
=== 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 binutils and want gcc to match, you can add the following to <tt>gcc/config/myos.h</tt>:
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 Binutils and want GCC to match, you can add the following to <tt>gcc/config/myos.h</tt>:


<source lang="C">
<source lang="C">