This is the mail archive of the crossgcc@sources.redhat.com mailing list for the crossgcc project.

See the CrossGCC FAQ for lots more information.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Updated HOWTO [Re: Linux target, cygwin host ]


On Wed, 24 Jan 2001, Fabrice Gautier wrote:

> Well i'm still trying to do that. I've followed most of Mummit Khan howto at
> http://www.xraylith.wisc.edu/~khan/software/gnu-win32/cygwin-to-linux-cross-
> howto.txt
> 
> The problem I ran into is:
> 
> src/gcc-2.95.2/gcc/libgcc2.c:41: stdlib.h: No such file or directory
> src/gcc-2.95.2/gcc/libgcc2.c:42: unistd.h: No such file or directory
> 
> Well I guess I've this problem because i've not installed what Mummit call
> the target runtime.

> I've not done so because I'm wondering why I need it.

If you don't understand why you need the target runtime, I'm not so sure 
I can explain it here. This may sound harsh, but the first rule of thumb 
in successfully using a tool is to figure out the terminology used by 
that tool or toolchain, and then go from there.

When it comes to cross-compiling (the simple kind or the canadian kind),
three terms are very important -- host, target and build. The host is
the machine that the resulting toolchain will run on, the build is the
machine that the resulting toolchain are being built on, and target is
the machine that resulting toolchain will create binaries for. The most
usual case is where host == build == target (eg., if you're using a Linux
compiler on a Linux box that was created on a Linux box); in the case of
most cross-compilers, host == build, target is different (eg., host and
build could be say Linux and target could be say i686-pc-cygwin, so that
when you compile/link on Linux box using this toolchain, you create
binaries that will run on i686-pc-cygwin); in the case of building a 
canadian cross compiler, host, build and target may all be different
(I'll refrain from expounding on this one, and leave it to your 
imagination).

Ok, so let's say we have a PC running Win2k and Cygwin, and we want to
able to build Linux binaries on that PC. Yuk, I know, but there are
those who seem to want it, and I just did it to satisfy some perverse
need to see if it could be done trivially.

CrossGCC folks use various schemes, and I personally find those too
complicated, but do it my way mostly because I'm too lazy to read the 
instructions.

Here're the basic steps: (Preliminaries) Decide on where you want to 
install and so on, (1) Gather all the source packages you need, move 
these over to the Cygwin host, (2) Get the Linux runtime from a Linux 
box and move that over as well, (3) Build and install Binutils, and 
finally (3) Build and install GCC.

The only complicated step is (2), but good news is that you *only* need
to do this once. You only need to redo this when you want to upgrade 
glibc2 for the cross-compiler.

Preliminaries:
==============

Scattered throughout this article are user commands that you'll type
in, and I've used either ``cygwin$'' or ``linux$'' as the shell prompt
to denote the host machine you're supposed to be on for that particular
step.

For the Cygwin host, let's say we'll be using the following (I'm using
bash, so if you're using a csh/tcsh type shell, do the right thing):
  
  cygwin$ host=i686-pc-cygwin
  cygwin$ build=i686-pc-cygwin
  cygwin$ target=i686-pc-linux-gnu
  cygwin$ prefix=/usr/local/linux
  cygwin$ src_root=/usr/local/src/gnu

Feel free to change $prefix and/or $src_root to match your environment,
but please don't mess with $host, $build and $target. Do make sure that
$src_root directory does exist. You don't have to set these shell 
variables of course, but it saves me some typing and saves you from my 
inevitable typos.

You should also add $prefix/bin to your PATH, but you can wait till you
have installed binutils for that (ie., end of Step 3).

Step 1:
=======
Gather all the source packages you need. The minimal set is the compiler
sources, binary utilities.

Let's say we get the following from a GNU mirror:
  
  gcc-2.95.2.tar.gz
  binutils-2.10.1.tar.gz

Since we're building on a Cygwin host, the safe bet is to get a version
of gcc-2.95.2 from the Cygwin distribution instead which may have some
Cygwin specific fixes, which is what I use. See Cygwin home page at
http://sources.redhat.com/cygwin/ to see how to download the GCC source 
package using the network "setup" utility (or just ftp it over from one
the mirrors). At the time of this writing, the latest one is gcc-2.95.2-6.

Download these on your Cygwin box and unpack:
  
  cygwin$ cd $src_root
  cygwin$ tar zxf /tmp/gcc-2.95.2.tar.gz
  cygwin$ tar zxf /tmp/binutils-2.10.1.tar.gz

Step 2:
=======
Gather the Linux target runtime.

Now comes the first slightly tricky job of deciding what the minimal set 
to get from a Linux box that will serve as our runtime. For the rest of
this article, when I refer to GNU/Linux, I'm referring to a RedHat 6.2
installation, so please take note if you're using some other distribution.
This at first would seem like a trivial task:

** On a Linux box now **
  
  [ on a Linux box now ]
  linux$ mkdir -p /tmp/linux-target-runtime
  linux$ cd /tmp/linux-target-runtime
  linux$ (cd /usr; tar cf - include lib) | tar xf -
  linux$ ln -s include sys-include
  [ Please don't ask why I add the sys-include symlink; if you do, I'll 
    simply ask you look at GCC configuration files. In fact, we could
    have just renamed include to sys-include, but there are packages 
    that get confused if the include directory is missing altogether. ]
  linux$ ls
  include lib sys-include

But there's a kink. Let's start with the problem with the includes after
we copied it over. If you look in /usr/include, you'll notice that there 
are two symbolic links that are rather important: 
  
  /usr/include/linux --> ../src/linux/include/linux
  /usr/include/asm   --> ../src/linux/include/asm

The ../src/linux points to /usr/src/linux, where your kernel headers and 
possibly the source tree is kept. So, that means that either you get your
whole kernel header tree as well, maintaining the correct relative paths,
or just copy those over instead of the symbolic link. But there's another
slight kink -- you'll note that the symbolic link /usr/include/asm points
to is itself a symbolic link -- points to asm-i386. Oh joy.
  
  /usr/src/linux/include/asm --> asm-i386

So, now we fix the links:
  
  linux$ cd /tmp/linux-target-runtime/include
  linux$ rm linux asm
  linux$ (cd /usr/src/linux/include; tar cf - linux asm-i386) | tar xf -
  linux$ ln -s asm-i386 asm

Whew, done with the includes.

Now, let's take a look at the library scenario: The following are the
most basic, and absolutely needed in the lib directory:

  linux$ cd /tmp/linux-target-runtime
  linux$ ls -F lib
  Mcrt1.o  gcrt1.o         libc.a            libc_stubs.a     libdl.so.2@
  crt1.o   ld-2.1.3.so*    libc.so           libdl-2.1.3.so*  libm-2.1.3.so*
  crti.o   ld-linux.so.2@  libc.so.6@        libdl.so.1@      libm.a
  crtn.o   libc-2.1.3.so*  libc_nonshared.a  libdl.so.1.9.5*  libm.so.6@

[ '*' after the name denotes executable, and '@' denotes symlink ]

The only kink in the libraries is that you'll need to fix libc.so, which
is just a linker script (and that's why it's only a few hundred bytes!).
If you look inside, you'll see something like the following:

  linux$ cat lib/libc.so
  /* GNU ld script
     Use the shared library, but some functions are only in
     the static library, so try that secondarily.  */
  GROUP ( /lib/libc.so.6 /usr/lib/libc_nonshared.a )

Note the last line -- obviously these paths are not going to be the
same on your Cygwin host, so both the paths need to changed to reflect
your Cygwin installation. If you choose say /usr/local/linux as the 
prefix when building your Linux-targeted Cygwin-hosted toolchain on 
Cygwin, then change /lib to $prefix/i686-pc-linux-gnu/lib instead.

Here's mine:

  cygwin$ cat /usr/local/linux/i686-pc-linux-gnu/lib/libc.so
  /* GNU ld script
     Use the shared library, but some functions are only in
     the static library, so try that secondarily.  */
  GROUP ( /usr/local/linux/i686-pc-linux-gnu/lib/libc.so.6 /usr/local/linux/i686-pc-linux-gnu/lib//libc_nonshared.a )

So, let's package it up and send it over to Cygwin box.
  
  linux$ cd /tmp/linux-target-runtime
  linux$ tar -zcvf /tmp/linux-target-runtime.tar.gz .
  linux$ scp /tmp/linux-target-runtime.tar.gz user@cygwin_hostname:/tmp/
  [ or use whatever method to copy it over to the cygwin box ]

** Back on the Cygwin box now **

Unpack the linux-target-runtime.

  cygwin$ mkdir -p $prefix/$target
  cygwin$ tar zxvf /tmp/linux-target-runtime.tar.gz
  cygwin$ ls
  include lib sys-include

Ok, we're done with Step 1. It's painful, but you only do this once every
few months, just like going to the dentist.

It's smooth sailing from now on.

Step 3:
=======

Build and install binutils. Never build in the source tree, so I'll just 
arbitrarily pick $src_root/BUILD as the top build directory, under which
I'll build both binutils and gcc.

  cygwin$ mkdir -p $src_root/BUILD/binutils
  cygwin$ cd $src_root/BUILD/binutils
  cygwin$ $src_root/binutils-2.10.1/configure \
    --with-included-gettext \
    --target=$target --host=$host --build=$build \
    --prefix=$prefix -v
  cygwin$ make > make.log 2>&1

If all goes well, install.

  cygwin$ make install > install.log 2>&1

*IMPORTANT* Add $prefix/bin to your PATH Before going forward.
  
  cygwin$ export PATH=$PATH:$prefix/bin

Check:

  cygwin$ i686-pc-linux-gnu-ld --version
  GNU ld 2.10.1
  Copyright 2000 Free Software Foundation, Inc.
  This program is free software; you may redistribute it under the terms of
  the GNU General Public License.  This program has absolutely no warranty.
    Supported emulations:
     elf_i386
     i386linux

Done. Smooth sailing. 

Step 4:
=======

Build and install GCC. 

  cygwin$ mkdir -p $src_root/BUILD/gcc
  cygwin$ cd $src_root/BUILD/gcc
  cygwin$ $src_root/gcc-2.95.2/configure \
    --enable-languages=c,c++ \
    --with-included-gettext --enable-shared --enable-threads \
    --target=$target --host=$host --build=$build \
    --prefix=$prefix -v

Feel free to change the arguments to --enable-languages, or leave it 
out altogether if you want to build all available languages. Also, 
do as you wish with --enable-shared and --enable-threads parameters.
Don't mess with the rest.

  cygwin$ make > make.log 2>&1

If all goes well, install.

  cygwin$ make install > install.log 2>&1

> Which headers libgcc2.c needs here? The host headers or the target header.

Target.

> The host, Cygwin, have those header in /usr/include but is not using them.
> And when configuring autoconf seems to find those headers... So what? Do I
> really need to install the include from linux glibc - and can I just get the
> include dir from glibc sources? Do i really need the librairies too? My next
> step is to be abble to build the glibc with my cygwin cross compiler but if
> i need to have an already build libc to build the compiler it's less fun...

It's actually quite simple to build glibc2 using a cross-compiler, but
there may a chicken and egg problem that you may face. Bootstrapping a
system with no initial runtime library is always a bit tricky, but after
you've done with above, it's trivial.

Regards,
Mumit



------
Want more information?  See the CrossGCC FAQ, http://www.objsw.com/CrossGCC/
Want to unsubscribe? Send a note to crossgcc-unsubscribe@sourceware.cygnus.com


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]