crosscompiling hint

Nicholas Dille darkyeti at gmx.net
Thu Jan 23 03:44:39 PST 2003


On 2003-01-22 14:57, Timothy Bauscher wrote:
> On Wed, Jan 22, 2003 at 10:34:11AM +0100, Nicholas Dille wrote:
> > after having given up maintaining the crosscompiling hint i am receiving
> > far too many support requests lately. could anyone please remove the
> > mail address as well as the url to rakshas.de from the hint.
> 
> Hint authors must make their own changes. Please submit the
> hint to hints at linuxfromscratch.org afterwards.

there you go

nic.

-- 
rakshas at quietude // C23C1939 // 7793747 // rakshas dot de
-------------- next part --------------
TITLE:			Crosscompiling on ix86 platforms
LFS VERSION:	cvs-20020630
AUTHOR:			Nicholas Dille

SYNOPSIS:
	How to compile LFS on a fast machine and use it on your old box

HINT:
version 2.1.6 (04.07.2002)


===============================================================================
MAINTENANCE
------------

PLEASE NOTE THAT I HAVE STOPPED MAINTAINTING THIS HINT.

SUPPORT: lfs-support at linuxfromscratch.org


===============================================================================
 0  Table of contents
----------------------

	0	Table of contents
	1	Introduction
	2	Why the naive approach fails
	3	Preparation
	4	Setting CFLAGS
	5	Targetting using configure
		5.1	perl 5.6.1
	6	Patches
		6.1	bin86 0.16.3
		6.2	bzip2 1.0.2
		6.3	kbd 1.06
		6.4	lilo 22.2
		6.5	man 1.5j
		6.6	net-tools 1.60
		6.7 netkit-base 0.17
		6.8	procinfo 18
		6.9	procps 2.0.7
		6.10	psmisc 21
		6.11	sysklogd 1.4.1
		6.12	sysvinit 2.84
	7	Extra packages
		7.1	pam 0.75
		7.2	simpleinit-msb 1.1
	8	Notes
		8.1	kernel

	A	The uname hack
		A.1	Traditional
		A.2	Kernel module
	B	Online
	C	Changelog


===============================================================================
 1	Introduction
---------------------

Alright, we have gathered here to mourn our failing in compiling our favourite
LFS system for our beloved outdated hardware and have either dived right into
it being stopped by unforseen difficulties or been hinted at this document to
circumvent some known problems.

Lets say you call an old i486 your own but moved on to some i686 based box some
time ago. Now you decided that the i486 might serve wonderfully as your perso-
nal file/printer server, internet gateway, MP3 player, a combination or some
entirely different purpose.
Without even trying you can imagine that it will probably take quite some time
to compile a LFS system caused by the lack of memory, harddisk space and mere
performance. Wouldn't it be nice to have your, by comparison, blindingly fast
i686 compile LFS and then use the resulting system on your i486?

I can assure you that several people had the same idea (including me ... wow,
how surprising) and tried solving the difficulties encountered. I hope to com-
pile most of those experiences here to help you find the least time consuming
path from a bare i486 to a lovely lfs'd linux box.

To give you a rough outline how I organized the hint let me elaborate shortly:
We will learn what problems you may encounter, under what conditions, why they
exist AFAIK and then at last come to the part where you can actively profit
from this by giving it a try.

In any case if you feel the hint missing something important, doesn't explain
something to your convenience, completely missed some point or if you'd just
like to give me a big hug, I'd be honestly happy to hear you out.

I'd also like to thank:
	* Gerard Beekmans for this wonderful project
	* Tommy Wareing for the uname hack
	* Arthur H. Johnson II for bullying me into rewriting this hint and
	  helping collecting new material
	* Christophe Devine for the kernel module uname hack
	* Yann Guidon for extending the kernel module uname hack

(If you feel you need to receive credits here or that I wrongly credited some-
 one here, please let me know.)


===============================================================================
 2	Why the naive approach fails
-------------------------------------

In case you only paste the commands provided by the LFS book to your console,
wait some time and come back for the next package you might want to read
through this to understand what really happens.

Let us devide the package which you are about to compile into two destinct
categories: the friendly and the painful packages.

Friendly packages are configured using autoconf (./configure ...) which
usually check for a sane environment and also try to determine which system it
will be compiled on. This information is then passed on to gcc which then knows
which architecture specific features it is allows to use. These packages are
easily persuaded to believe they are being compiled on a weaker platform.

In contrast, the painful packages do not provide any automatic check whether
their prerequisites are satisfied and trust the user to know what he is doing.
In this case the decision which platform is present is left to gcc which uses
uname and C(XX)FLAGS to guess it. Unfortunately these packages are harder to
force to compile for a weaker platform.

So, if you leave any of those packages alone they will compile for the platform
they detect either by the configure script or by means of gcc.
We need to make configure and gcc think that the underlying architecture is of
a different type. The following chapter will describe the method which have
proven to work for me.


===============================================================================
 3	Preparation
--------------------

Before starting off please obtain the architecture name from the machine which
will profit from the resulting LFS system:

	# uname -m

I will use $ARCH in the following chapters to refer to this value.


===============================================================================
 4	Setting CFLAGS
-----------------------

CFLAGS is an environment variable which is used by any honourable package to
pass user flags on to gcc. It is often used to set the optimization level (-On
where n is a number). For details please refer to the optimization hint.
In our case we additionally try to force gcc to compile for the desired archi-
tecture by setting CFLAGS:

	# export CFLAGS="-march=$ARCH"


===============================================================================
 5	Targetting using configure
-----------------------------------

As I have stated before configure scripts are specially easy to persuade into
believing to be running on a different architecture.
You will have to add "--host=$ARCH-pc-linux-gnu --target=$ARCH-pc-linux-gnu"
to the configure scripts' arguments.

Please note that the configure script bundled with netkit-base does not honour
those options, see 6.7 for details.


===============================================================================
 5.1	perl 5.6.1
--------------------

unfortunately this will not work with the configure scripts shipped with perl
which does not recognize --host or --target. But you can still target perl
using the -Dhost, -Dtarget and -Darchname switches:

"-Dhost=$ARCH-pc-linux-gnu -Dtarget=$ARCH-pc-linux-gnu -Darchname=$ARCH-linux"

The host parameter tells configure to compile for the host system specified,
whereas target causes compile tools shipped with the package to be compiled
for the specified architecture.


===============================================================================
 6	Patches
----------------

This chapter will provide you with a list of packages which do not come with a
configure script or which come with one that does not honour --host and
--target options. These packages will have to be patched to use the value of
CFLAGS.

Please note that some patches may have lines longer than 80 characters.


===============================================================================
 6.1	bin86 0.16.3
---------------------

Use the following commands to write your CFLAGS variable into bin86's Makefile.

	# make CFLAGS="-D_POSIX_SOURCE $CFLAGS"


===============================================================================
 6.2	bzip2 1.0.2
--------------------

Use the following commands to patch bzip2:

	# cp Makefile Makefile.backup
	# sed -e 's%$(BIGFILES)%$(BIGFILES) $(OPT)%' \
		Makefile.backup > Makefile
	# cp Makefile-libbz2_so Makefile-libbz2_so.backup
	# sed -e 's%$(BIGFILES)%$(BIGFILES) $(OPT)%' \
		Makefile-libbz2_so.backup > Makefile-libbz2_so

Add 'OPT="$CFLAGS"' to the make commands:

	For chapter 5:
	# make CC="gcc -static" OPT="$CFLAGS"

	For chapter 6:
	# make -f Makefile-libbz2_so OPT="$CFLAGS"
	# make OPT="$CFLAGS"


===============================================================================
 6.3	kbd 1.06
-----------------

Use the following commands to write your CFLAGS variable into kbd's Makefile.

	# make CFLAGS="$CFLAGS"


===============================================================================
 6.4	lilo 22.2
------------------

Use the following make commands:

	# make OPT="$CFLAGS"

This is not thoroughly tested since i don't use lilo. Please report any
problems or corrections to me!


===============================================================================
 6.5	man 1.5j
-----------------------

Use the following commands to add your CFLAGS variable to man2html's Makefile:

	# cp man2html/Makefile.in man2html/Makefile.in.backup
	# sed -e "s/CFLAGS = /CFLAGS = $CFLAGS /" \
		man2html/Makefile.in.backup > man2html/Makefile.in


===============================================================================
 6.6	net-tools 1.60
-----------------------

Use the following make command:

	# make COPTS="-D_GNU_SOURCE -Wall $CFLAGS"


===============================================================================
 6.7	netkit-base 0.17
-------------------------

This package does not need any changes to the book's commands. It will pick the
value of the CFLAGS variable and apply it correctly.


===============================================================================
 6.8	procinfo 18
--------------------

Add 'CFLAGS="$CFLAGS"' to the make command:

	# make LDLIBS=-lncurses CFLAGS="$CFLAGS"


===============================================================================
 6.9	procps 2.0.7
---------------------

Add 'OPT="$CFLAGS"' to the make command:

	# make OPT="$CFLAGS"

Please note that the build process will fail with top.c if your CFLAGS variable
did not contain the -On switch. If that is the case please use the following
line:

	# make OPT="$CFLAGS -O2"

This switch will not add any additional kind of optimization to your build pro-
cess because -O2 is usually assumed by gcc in case it is not told otherwise.
I will contact the author about this behaviour of procps and update the hint
accordingly.


===============================================================================
 6.10	psmisc 21
---------------------

Add 'AM_CFLAGS="$CFLAGS"' to the make command:

	# make AM_CFLAGS="$CFLAGS"


===============================================================================
 6.11	sysklogd 1.4.1
-----------------------

Add 'RPM_OPT_FLAGS="$CFLAGS"' to the make command:

	# make RPM_OPT_FLAGS="$CFLAGS"


===============================================================================
 6.12	sysvinit 2.84
-----------------------

Add 'CFLAGS="-Wall -D_GNU_SOURCE $CFLAGS"' to the make command:

	# make -C src CFLAGS="-Wall -D_GNU_SOURCE $CFLAGS"


===============================================================================
 7	Extra packages
-----------------------

I have added the following packages to give LFS users a chance to profit from
my tests even with non-standard packages.
I am actively using those packages with the given optimization method.


===============================================================================
 7.1	pam 0.75
-----------------

Add 'OS_CFLAGS="$CFLAGS"' to your make command:

	# make OS_CFLAGS="$CFLAGS"


===============================================================================
 7.2	simpleinit-msb 1.1
---------------------------

Isn't it weird that removing CFLAGS from a Makefile enables proper optimiza-
tion? You'll figure it out ;-)

	# cp sysvtools/Makefile sysvtools/Makefile.backup
	# cat sysvtools/Makefile.backup | \
		grep -vE "^CFLAGS" > sysvtools/Makefile


===============================================================================
 8	Notes
---------------------------

Just some notes ;-)


===============================================================================
 8.1	kernel
---------------------------

When installing the kernel headers in chapter 5 you do not need to worry about
any information about the architecture leaking into the headers.


===============================================================================
 A	The uname hack
-----------------------

Generally spoken the uname hack will fool the system. It pretends that linux is
running on different hardware.
For example, you are using an i686 based system to compile a lfs for an old
i586. Then the uname hack would force uname to lie about the underlying hard-
ware - not reporting i686 but i586.


===============================================================================
 A.1	Traditional
--------------------

Install the uname hack using the following commands:

	# cd /bin
	# mv uname uname.orig

Now create a file /bin/uname with the following content:
-------------------------8<-----------------------------
#!/bin/bash

/bin/uname.orig "$@" | sed "s/i[456]86/$ARCH/"
-------------------------8<-----------------------------

And give it the correct permissions:

	# chmod 755 uname

The traditional uname hack will have to be installed thrice: once before you
start your lfs compilation to replace the uname binary of you host system, then
when you enter chroot to force your statically linked environment into assuming
a different architecture and last after installing sh-utils in chapter6 because
they will replace the uname binary.


===============================================================================
 A.2	Kernel module
----------------------

Please check out the niftiness of this version of the uname hack!

Put the code below into the file uname_i586.c and compile with the following
command:

	# gcc -I/usr/src/linux/include -c -DMODULE \
		-DUNAME_DUMB_STEPPING=\'4\' uname_i586.c

By adjusting the '4' in the compilation command you will be able to specify the
desired platform at compile time without changing the code :-)

------------------------8<-------------------------------------
/*
This simple piece of code simply turns your ix86 into a i586 -
useful if you're cross-compiling for a weaker platform.

Compile with: gcc -I/usr/src/linux/include -c -DMODULE uname_i586.c
and then: insmod ./uname_i586.o

Revision : whygee at f-cpu.org, Wed Apr 10 07:45:11 CEST 2002 :
   added the UNAME_DUMB_STEPPING parameter/ifdef so the user can
   modify it at compile time. it's just a quick hack.
   your command line for simulating a 486 will look like :
        gcc -I/usr/src/linux/include -c -DMODULE \
                -DUNAME_DUMB_STEPPING=\'4\' uname_i586.c

*/

#include <linux/module.h>
#include <linux/utsname.h>

#ifndef UNAME_DUMB_STEPPING
#define UNAME_DUMB_STEPPING '5';
/* #error "no stepping specified." */
#endif

char save;

int init_module( void )
{
    save = system_utsname.machine[1];
    system_utsname.machine[1] = UNAME_DUMB_STEPPING;
    return( 0 );
}

void cleanup_module( void )
{
    system_utsname.machine[1] = save;
}
------------------------8<-------------------------------------


===============================================================================
 B	Online
-----------

THE ONLINE VERSION WILL BE TAKEN OFFLINE SOON. SEE NOTE AT THE TOP.


===============================================================================
 C	Changelog
------------------

2.1.6
	- fixed typo in toc
	- added workaround for a weird procps behaviour
	- added chapter for netkit-base 0.17

2.1.5
	- removed processor table
	- updated bin86 to 0.16.3
	- sync'd bzip2 with the book
	- fixed typo in man 1.5j
	- updated psmisc to 21
	- updated simpleinit to 1.1

2.1.4
	- corrected the toc and the bin86 heading as i forgot to update the version
	  there after updating bin86 to 0.16.2

2.1.3
	- added AMD Athlon and Duron to the list of processor architectures
	- corrected processor architecture list (AMD K6* is i586)
	- updated lilo to 22.2
	- updated bin86 to 0.16.2
	- simplified kbd 1.06 commands
	- replaced the original uname hack kernel module with an easier to use
      by Yann Guidon

2.1.2
	- replaced bzip2 patch with sed
	- unified and condensed the changelog
	- reversed changelog; latest entry now at the top
	- added note about website
	- updated bzip2 to 1.0.2

2.1.1
	- added notes section
	- added man optimization
	- corrected perl targetting
	- corrected heading of sysvinit section

2.1
	- no changes since 2.1pre10

2.1pre
	- moved non-standard packages to separate chapter
	- added a table of intel architecture names
	- added uname appendix
	- moved the traditional uname hack to appendix
	- added kernel module uname hack
	- added optimization for simpleinit
	- added optimization for pam
	- added optimization for bin86
	- added optimization for lilo
	- added optimization for sysvinit
	- added note about packages which are left out
	- added psmisc optimization
	- added net-tools patch
	- added targetting description for perl
	- removed the uname hack

2.0.2
	- corrected the uname hack sed'ing

2.0.1
	- added some more explanations in the uname hack section


===============================================================================
 Copyright (c) 2002 by Nicholas Dille <webmaster at rakshas.de>


More information about the hints mailing list