Cross Compiling GCC with Newlib

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
User avatar
0fb1d8
Member
Member
Posts: 27
Joined: Mon Nov 03, 2014 2:20 pm
Location: Seoul, South Korea
Contact:

Cross Compiling GCC with Newlib

Post by 0fb1d8 »

Hello,
I am trying to configure and build a cross compiler for my operating system, Arcrascent. I have thoroughly read the Wiki page for OS Specific Toolchain. I have followed every instruction in the wiki for all the utilities (at least i believe so).

So after modifying the source codes to add support for Arcrascent, I created the following script to build the cross compiler.

Code: Select all

# varaibles
export SYSROOT=$HOME/arcrascent
export PREFIX=$SYSROOT
export TARGET=i386-arcrascent
export PATH="$PREFIX/bin:$PATH"

# create root directory
mkdir $SYSROOT

# build binutils
mkdir make-binutils
cd make-binutils
../binutils-2.24/configure --target=$TARGET --prefix=$PREFIX
make all
make install

cd ..

# build gmp
mkdir make-gmp
cd make-gmp
../gmp-6.0.0a/configure --prefix=$PREFIX
make all
make install
make check

cd ..

# build mpfr
mkdir make-mpfr
cd make-mpfr
../mpfr-3.1.2/configure --prefix=$PREFIX --with-gmp=$SYSROOT
make all
make install
make check

cd ..

# build mpc
mkdir make-mpc
cd make-mpc
../mpc-1.0.3/configure --prefix=$PREFIX --with-gmp=$SYSROOT --with-mpfr=$SYSROOT
make all
make install
make check

cd ..

# build
mkdir make-gcc
# bootstrap
cd make-gcc
../gcc-4.9.2/configure --target=$TARGET --prefix=$PREFIX --without-headers --with-newlib --with-gmp=$SYSROOT --with-mpfr=$SYSROOT --with-mpc=$SYSROOT
make all-gcc
make install-gcc

cd ..

# build newlib
mkdir make-newlib
cd make-newlib
CC=$TARGET-gcc ../newlib-2.1.0/configure --prefix=$PREFIX --target=$TARGET
make all
make DESTDIR=${SYSROOT} install

cd ..

# rebuild gcc with newlib
rm -rf make-gcc
mkdir make-gcc
cd make-gcc
../gcc-4.9.2/configure --target=$TARGET --prefix=$PREFIX --with-newlib --enable-languages=c,c++ --with-gmp=$SYSROOT --with-mpfr=$SYSROOT --with-mpc=$SYSROOT --disable-dlopen
make all
make install
All Binutils, GMP, MPFR, MPC, Newlib, and GCC bootstrap build and install correctly, however in the last step, where I rebuild gcc with Newlib, I get the following error messages.

Code: Select all

checking for ISO C99 support to TR1 in <ctype.h>... no
checking for fenv.h... (cached) no
no
checking for ISO C99 support to TR1 in <stdint.h>... no
checking for ISO C99 support to TR1 in <math.h>... no
no
no
checking stdbool.h usability... no
checking stdbool.h presence... yes
configure: WARNING: stdbool.h: present but cannot be compiled
configure: WARNING: stdbool.h:     check for missing prerequisite headers?
configure: WARNING: stdbool.h: see the Autoconf documentation
configure: WARNING: stdbool.h:     section "Present But Cannot Be Compiled"
configure: WARNING: stdbool.h: proceeding with the compiler's result
checking for stdbool.h... no
checking stdalign.h usability... no
checking stdalign.h presence... yes
configure: WARNING: stdalign.h: present but cannot be compiled
configure: WARNING: stdalign.h:     check for missing prerequisite headers?
configure: WARNING: stdalign.h: see the Autoconf documentation
configure: WARNING: stdalign.h:     section "Present But Cannot Be Compiled"
configure: WARNING: stdalign.h: proceeding with the compiler's result
checking for stdalign.h... no
checking for the value of EOF... configure: error: computing EOF failed
make[1]: *** [configure-target-libstdc++-v3] Error 1
make[1]: Leaving directory `/home/arcrascent/Desktop/ArcSDK/make-gcc'
make: *** [all] Error 2
What could be causing this?
Thanks!
Joonyoung Lee
Student at 한성과학고등학교(Hansung Science High School) & Ambitious OSDever
Arcrascent OS | Source <-- My OSDev Project
“One of my most productive days was throwing away 1000 lines of code.” - Ken Thompson
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Cross Compiling GCC with Newlib

Post by Candy »

You didn't make or install libgcc before the full gcc build - can that be the problem? Those files come from libgcc...
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Cross Compiling GCC with Newlib

Post by sortie »

Hi,

Congratulations on making it this far. Exciting, isn't it?

You've made a number of mistakes and have gotten a few abstractions wrong. First of all, you should follow the instructions in my Hosted GCC Cross-Compiler wiki article. This article covers the correct approach, and you should discard whatever you're doing now in favour of my instructions.

Your current approach suffers from a number of issues:
  • You've set the cross-compiler prefix and the sysroot to the same directory. This is absolutely wrong: The sysroot contains files that's part of your operating system and runs on it; the cross-compiler prefix contains a Linux (assuming you use Linux) toolchain that just happens to spew out files for your OS. You're putting it all in the same directory here, this can only blow up.
  • Is $HOME/arcrascent the source code directory for your OS? Then use a subdir like $HOME/arcrascent/sysroot for the sysroot. See Meaty Skeleton for an example on how to handle a sysroot in your project well.
  • You forgot to pass --with-sysroot to the binutils build.
  • Don't build libgmp, libmpfr and libmpc! Use the ones that come with your distribution. Ideally, you should only need to compile them when porting gcc to your OS! So delete all that, it'll only cause you grief. All the --with-{gmp,mpfr,mpc} option you later pass is also just trouble and not needed if you installed it as part of your distro.
  • You make a bootstrap gcc to build newlib and this is actually completely unnecessary. Instead, as seen in the Hosted GCC Cross-Compiler article, you should just (manually perhaps) install the newlib headers into the sysroot, and then pass --with-sysroot to gcc. It'll then find them, and you don't need the --without-headers option. If you do this, you can build a single cross-gcc, and then use it to build newlib.
  • You forgot to build libgcc, although the make all and make install sequence in the last step does build it. I'm really not sure how good an idea a full gcc cross-toolchain build is, I never do this, and it might try to build stuff you're might not ready for, like libstdc++ and other stuff.
Your method to cross-compile newlib itself and install it is wrong too, and this is covered in Cross-Porting Software:
  • Don't pass --target to newlib, as it's not a cross-compiler, but a library that runs on your OS: Use --host like you do when cross-compiling softwarer, rather than creating cross-compilers. This also means you don't need to set CC, the proper cross-compiler will be used automatically.
  • The --prefix option tells software where it will be located at runtime, that means on your operating system when you cross-compile! The system libc will not be installed into $HOME/arcrascent! No, it'll be installed into the root prefix. So set --prefix to the empty string, because nothing should be added in front of /lib when installing /lib/libc.a. DESTDIR=${SYROOT} takes cares of putting the libc somewhere different on the local system, under the promise that when the code is run, it'll be in the --prefix directory.
If you manage to do this well, and completely comprehend all my advise regarding proper cross-compilation, please improve the wiki porting newlib article. I split it out of the OS specific toolchain article as part of my effort of documenting how you can make your own native libc, rather than just using newlib, and the article got really disorganized. It needs love.

There's a lot of subtle semantics here that you want to get right, I documented most of them in the wiki articles I linked. Generally, it's favourable not to have complicated bootstraps, but to do it nicely in a single step. This is often more work, but it's worth it. For instance, as a further step, I personally detached libstdc++ entirely from the gcc tree, so it can be built independently at my leisure, rather than part of the compiler (where it can't be built, because the libc needs the compiler to be built, the compiler build wants to do libstdc++ first, libstdc++ needs libc to be built).
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Cross Compiling GCC with Newlib

Post by Candy »

Sortie, how do you build your compiler without libc or libstdc++ ? Do you have the details on that?
User avatar
0fb1d8
Member
Member
Posts: 27
Joined: Mon Nov 03, 2014 2:20 pm
Location: Seoul, South Korea
Contact:

Re: Cross Compiling GCC with Newlib

Post by 0fb1d8 »

Thank you so much for your responses! I'll get right into fixing it!
Joonyoung Lee
Student at 한성과학고등학교(Hansung Science High School) & Ambitious OSDever
Arcrascent OS | Source <-- My OSDev Project
“One of my most productive days was throwing away 1000 lines of code.” - Ken Thompson
User avatar
0fb1d8
Member
Member
Posts: 27
Joined: Mon Nov 03, 2014 2:20 pm
Location: Seoul, South Korea
Contact:

Re: Cross Compiling GCC with Newlib

Post by 0fb1d8 »

@sortie Thanks so much for your tips! I successfully built my i386-arcrascent-gcc toolchain! :D
Joonyoung Lee
Student at 한성과학고등학교(Hansung Science High School) & Ambitious OSDever
Arcrascent OS | Source <-- My OSDev Project
“One of my most productive days was throwing away 1000 lines of code.” - Ken Thompson
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Cross Compiling GCC with Newlib

Post by sortie »

0fb1d8 wrote:@sortie Thanks so much for your tips! I successfully built my i386-arcrascent-gcc toolchain! :D
Yay! The bitbucket source link in your signature is dead, btw.
Candy wrote:Sortie, how do you build your compiler without libc or libstdc++ ? Do you have the details on that?
I think you misunderstood me. We're talking about creating a cross-compiler. In the case of GCC, it needs libc, libstdc++, libmpc, libmpfr, libgmp and all that. But it uses the native ones on the local system. That's okay, the cross-compiler is a Linux (or whatever you use) executable after all. When you link with your cross-compiler, and not disabling the standard library, it'll link with your operating system's standard library as found in the sysroot.

As you can see, the use of the standard library is only at runtime, and only when you link user executables for your OS. The cross-compiler can thus be created before building the libc. This means that you can create a cross-compiler without the libc around, and then use that to compile libc, and then after libc is installed, you can now link userspace programs. The actual libc need not be around during the cross-compiler build.

The caveat is that compiler needs the libc headers during the build as libgcc needs them for a few things. People often confuse this with a requirement that the libc must be around, but that's not the case, just the headers are needed. This may be tricky if you use a libc whose headers can't be easily installed without building the whole libc, but that's a design mistake in my book, and not too hard to fix.

Thus, the proper sequence to bootstrap a cross-toolchain is:
  • Create sysroot and install the standard library (and kernel if needed) headers into the standard include directory.
  • Create cross-toolchain (binutils + gcc) pointed at the sysroot.
  • Compile libc with the cross-toolchain and install into the sysroot.
This is covered in Hosted GCC Cross-Compiler. It's also what I wrote above. :)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Cross Compiling GCC with Newlib

Post by Candy »

I was intending to point at
For instance, as a further step, I personally detached libstdc++ entirely from the gcc tree, so it can be built independently at my leisure, rather than part of the compiler
Do you have a reference for the standalone libstdc++?
User avatar
sortie
Member
Member
Posts: 931
Joined: Wed Mar 21, 2012 3:01 pm
Libera.chat IRC: sortie

Re: Cross Compiling GCC with Newlib

Post by sortie »

Candy wrote:I was intending to point at
For instance, as a further step, I personally detached libstdc++ entirely from the gcc tree, so it can be built independently at my leisure, rather than part of the compiler
Do you have a reference for the standalone libstdc++?
I talked a bit about it in #osdev if you're willing to search the channel logs. I basically have a script that's run in the gcc root source directory that creates a directory containing a stand-alone libstdc++: https://gitlab.com/sortix/gcc/blob/mast ... bstdc++.sh

It's a bit late, I hope that little pointer is good enough for you, otherwise ask more questions, and I'll answer tomorrow. :)
User avatar
Candy
Member
Member
Posts: 3882
Joined: Tue Oct 17, 2006 11:33 pm
Location: Eindhoven

Re: Cross Compiling GCC with Newlib

Post by Candy »

Thanks Sortie, that's exactly what I was looking for. Finally a decent way to build GCC, with libc, without making gcc build my libc.
Post Reply