Talk:Why do I need a Cross Compiler?

From OSDev.wiki
Latest comment: 13 years ago by Solar in topic What *should* be on this page...
Jump to navigation Jump to search

As we're talking about GCC, I really don't see any reason for which a cross-compiler is neccessary, unless a different target architecture and/or executable format are needed. However, this is usually not the case. The more natural solution is to use the free-standing environment provided by GCC. --Love4boobies 15:01, 21 April 2011 (UTC)Reply

To get around distribution patches that almost always exist, licensing reasons, to create a reproducible environment on a variety of different development platforms.. and attempt to curtail the plethora of Cygwin/MinGW/DJGPP users asking dumb questions. So, is that reason enough for ya? --Brynet-Inc 06:04, 23 April 2011 (UTC)Reply
The first reason makes the most sense. Alas, I don't really know what kind of patches are usually there and how they affect code generation and/or linking---perhaps I should look into this. Could you give some examples for the other two reasons? I'm not 100% sure what you had in mind. --Love4boobies 14:51, 23 April 2011 (UTC)Reply
Well, GCC 4.2.1 for example.. it's the last GPLv2 version and contains several code generation bugs that had to be independently fixed, not only that, but the fixes aren't always identical between forks. Also, for someone running on Linux.. they may not wish to use the particular version of GCC that's available. It makes sense to pick a version of GCC/binutils that you've tested extensively for building your kernel/OS, as well as making that environment reproducible on Windows/Linux/OSX/BSD/etc. --Brynet-Inc 19:17, 23 April 2011 (UTC)Reply
I'm not sure using all this indentation is helpful :) Anyway, the GPL license applies to GCC, not code generated by it, so as far as the OS is concerned, this isn't a problem. As for the other thing, I thought it might be what you were thinking and it makes sense to some extent but I can't think of any specific problems that I've come across when using this technique... --Love4boobies 04:37, 24 April 2011 (UTC)Reply
Indeed, one mustn't abuse indentation. Also, the license covers distribution.. and with the introduction of the GPLv3 some additional gotchas. If you plan on including a compiler along with your OS, for example. It makes sense to eventually port the cross-compiler environment to your OS as a native hosted environment. Just trust me on this one. --Brynet-Inc 20:03, 24 April 2011 (UTC)Reply
For the record, only 32-bit linux is the actively used platform which shares architecture and executable format with "common" OS development. 64-bit linux comes with an amd64 toolchain, Windows and Macintosh comes with a different binary format - each of them needs very specific workarounds to get the desired behaviour if possible at all. On top of that, all of the hosted compilers might fail now or in the future because they target a specific OS and are therefore freely allowed to generate OS-specific code. Excluding the notion of doing things the right way, which you obviously do not promote, your suggestion requires that portable means 32-bits linux only instead of all common desktop installations out there.</sarcasm> - Combuster 21:40, 24 April 2011 (UTC)Reply
In the first part of your reply, you just repeated what I said (i.e., that cross-compilers are useful for different target architectures and/or file formats) and assumed you were making some point. No one argued against building a cross-compiler in that scenario; I only complained because the article instructs people to always do this, which is unnecessary. In the second part of your reply, you talked about hosted compilers and completely missed what I said about the freestanding functionality, which is present with any GCC port (RTFM, in this case, the GCC documentation), followed by more of your usual gibberish. --Love4boobies 22:15, 24 April 2011 (UTC)Reply
It is almost always necessary, you really shouldn't just build your OS with whatever is shipped with your 32-bit Linux distribution.. as stated many times on the forums, you'll run into problems eventually.. and you'll be surprised when an update introduces unexpected behaviour. --Brynet-Inc 22:28, 24 April 2011 (UTC)Reply
Well, at least there's an argument on the table now so let's focus on that one. I've successfully used MinGW, Cygwin GCC, Linux GCC and clean cross-compilers and had problems with neither so I wonder whether we're being realistic in the article. As per the GCC documentation, the freestanding environment implies that there's no standard library linked in and no system-specific startup code present. Could anyone point out any reproducible problems, on the forums or anywhere else? Otherwise, you could guess, I could guess but we're not really going to get anywhere :) --Love4boobies 22:42, 24 April 2011 (UTC)Reply
I give you the OpenBSD manual that briefly touches on some of the changes (..beyond bug fixes) to their version of GCC 4.2.1, as an example. gcc-local(1) --Brynet-Inc 01:59, 25 April 2011 (UTC)Reply
First off, I regret the ad hominem you had to use. Yes I know exactly what -ffreestanding is meant to do, and I also know its not enough, thanks to references to the always platform-specific libgcc. Point was that the cases where the hack of not building a crosscompiler only works on a limited and shrinking number of platforms. Now to return the favour, will you quit the arguments about ugly hacks being better than proper use because they happen to be marginally simpler. I hate those and they only really help those who are already aware of the reasons of why you would do things one way. We are out here to help mostly newcomers, and providing them broken information and dirty workarounds is counterproductive in the long run.
I want to close this up and call it a 3v1 vote. I'm including solar besides the active participants here because he wrote the original text and has made it clear that using a crosscompiler rules out any possible host-compiler-related problems rather than just making them unlikely. And debugging is about testing assertions, not guesswork.
- Combuster 09:23, 25 April 2011 (UTC)Reply
If you'll read more carefully, you'll see that there was no ad hominem in my reply, regardless of which one you are referring to (you've either read just half of one phrase or considered something to be an argument when it wasn't). Anyway, can you point out any problems for platform X or Y yet so as to shut me up? The reason for which I don't think this is a hack, but a solution, is that I have yet to come across any. Brynet's link seems to point out that OpenBSD's port changes some arguments and some other stuff but it shouldn't really cause any problems, esp. if one is going to write proper standards-compliant code. I expect that maybe sometimes people will need to use some different compiler/linker flags to get the thing to work, but does that make it a hack? Voting is nice but I prefer facts. --Love4boobies 13:43, 25 April 2011 (UTC)Reply
There is potential for problems, nobody has said that what you're doing won't work.. it's just not guaranteed to work, you can go around licking public surfaces and not get sick.. doesn't mean you're not going to.. get hit by a bus. --Brynet-Inc 23:54, 25 April 2011 (UTC)Reply

What *should* be on this page...

The fact that Love4Boobies didn't understand the need for a cross-compiler shows that this page does a poor job of answering the question.

Things I feel are missing from the page (which might satisfy Love4Boobies, and which perhaps someone would like to insert as appropriate - I don't have the leisure ATM):

  • Building a cross-compiler is merely the first step towards "going native", i.e. a step you have to do sooner or later anyway. You might as well do it right at the beginning.
  • The moment you go forward to the next step - putting YourOS-specific files like libc headers, startup code etc. in the compiler directories - you need to seperate between system compiler and OSDev compiler, or you'll end up with a disfunctional system compiler.
  • Your system compiler is subject to being updated by your package management without specific notice. Depending on your distro, locking a specific version, or going back to an older version, might be anything but trivial (if at all possible without breaking your system). Worse, you might not even know which version it was that actually worked (before the latest update), and you might have depended on something distro-specific before, leaving your development environment in complete limbo.
  • As the recommended thing to do, it puts everyone following the recommended practice on similar footing. No comparing of (vanilla) gcc-4.5.2 with (Gentoo) gcc-4.5.2-r1 or (Ubuntu) gcc-4.5.2-1ubuntu3 or (Cygwin) gcc4-4.5.2-2 or somesuch.

-- Solar 09:15, 2 May 2011 (UTC)Reply


For the record, I completely agree with Love4Boobies and completely disagree with Solar. Building a crosscompile toolchain for later work is solely useful to cut down on the extra arguments needed to be given. You can achieve the same result with -ffreestanding -nostdlib -nostdlibinc (for the kernel) and --sysroot for usermode apps.

Not to mention that recompiling the compiler is a GCC-ism. Clang doesn't require it, it is naturally a crosscompiler, in which case you use --sysroot as well (until someone fixes the compiler driver to support dynamic retargetting, which is on my agenda but hasn't been done yet) -- JamesM


("Tongue in Cheek") Suggestion For Rewritten Page Introduction

The suggested new introduction for this page is:

"Even though C is a well known language that has been around since 1973, and GCC is a well known toolchain that has been around since 1987 and is relied on by many major open source projects; some people think GCC is so utterly broken that the sheer hassle of creating a cross-compiler is not only a justified step but necessary step, to shield developers from the complete and utter horror of GCC's brokenness. However, some people think that GCC actually does work (for at least one definition of "works") and that GNU developers and the open source community as a whole actually aren't completely incompetent. These people don't agree that creating a cross-compiler is justified or necessary. A third group of people are more practical and have the opinion that if GCC actually is so broken that a cross-compiler is necessary, then hiding symptoms isn't a cure and you should probably just use NASM instead." --Brendan 12:57, 19 March 2012 (CDT)

Development without a cross-compiler?

I would like to give a perspective from a os-dev newcomer who has been using the this and wiki pages to get started with kernel developement. I do not feel mature enough to take side, but for me it would have been helpfull if the article would state something like "It is possible, under circumstances xyz, not to use a crosscompiler or post-pone it for later. Then flags xyz will be necessary." And then stress again that this is not recommanded. Maybe also point to the discussion page for details why or why not.

I downloaded a couple of available "hobby OSes" (e.g. geekos and prettyos) and compiled them without problem using my i686-linux-gnu gcc and they run. I'm not trying to say that it is a good idea not to use a cross compiler. I'm saying that to me this article in the current version gave the impression that it is simply impossible without build cross-compiler; and I was confused when it actually worked. -- Tang

Hi, this kind of discussion is probably more suited for the forums. Nonetheless, I'll try to answer your questions here. The main reason you need a cross-compiler is because the gcc that came with your distribution targets your current system. For instance, a Linux gcc will search for headers in /usr/include and libraries in /usr/lib. Not only that, it will use the Linux executable format (ELF) and the generated code will assume the Linux ABI. Indeed, the compiler will declare Linux-specific preprocessor macros. It will assume instruction set extensions are enabled. (Even the libgcc assumes it will run on a Linux platform and contains references to stuff like pthreads, if I'm not wrong). It might even generate code for the wrong architecture if you wish to make a 32-bit kernel on a 64-bit system.
In other words, the root cause is that the compiler thinks it targets a Linux system (in this example, but substitute whatever you use) and all the problems you will experience are caused by this. You implicitly lied to the compiler and told it that it targets Linux - when it really doesn't - and it might do bad things. This article mentions a number of compiler options that can change the behaviour to disable some of the symptoms, but it doesn't correct the root problem: Your OS is not Linux. You can use the compiler options, but the result will be a fragile toolchain that is harder to use. Indeed, you can't even fully pass command line options that undo all the Linux assumptions. You can't even use freestanding headers like <stdint.h> in your kernel as on GNU libc platforms this header is provided by GNU libc, but as you pass -nostdinc you disable both /usr/include and the compiler specific include directory.
That said, you can provide a bunch of compiler options that gradually treat whatever symptoms would appear and it will likely work if you are skilled - but you won't gain the reliably of a target like i686-elf where the compiler never makes any of these bad assumptions in the first place. It is likely possible to provide a list of options that would fix most issues people would encounter, but then there's additional problems caused by the fact that distributions further patch the system compiler with further enhancements and change compiler option defaults - even the fact that they may need to pass options like -m32 (which doesn't make sense if cross-developing from, say, ARM) causes much complexity.
So yes, it's much simpler to just do things properly and cross-compile to a target like i686-elf. Indeed, most people that would use the advise on how to avoid using a cross-compiler are likely lazy and will complain when things break - this increases the support burden for our community. Besides, requiring a bit of patience from newcomers to build a cross-compiler isn't unreasonable considering the time it takes to write an OS - it's even educational to know how to compile GCC. --Sortie 14:52, 4 January 2014 (CST)


I noted in a comment earlier that "portable" seems to be defined as "32-bit linux only". While this wouldn't be completely true, the hacks you need to force specific compilers to do the things you expect them to do can often differ between setups, have some issues that can't be patched, or just can't be made to work at all in several cases. And these settings change as GCC goes to newer versions. Basically what you request consists of two things:
  1. Post and maintain hacks for all possibilities.
  2. Post instructions with the intent that they're not being performed.
The former is a waste of time, the second is just silly. Also note that building the cross-compiler is in several people's vision the equivalent of the entrance test because it implies the minimal reading skills many people lack. Getting caught not using one is in practice just an excuse for being flamed for your stupidity, and not getting any further help until you "fix" the problem. So you're better off doing it right the first time anyway.
As for the article, I'll always stick with the established psychology that tells you to teach people the things to do, rather than the things not to do because the latter only gives people ideas. Basically, every non-cross-compiler reference to GCC in the wiki is to be considered an error.
- Combuster 10:14, 7 January 2014 (CST)