LinuxSir.cn,穿越时空的Linuxsir!

 找回密码
 注册
搜索
热搜: shell linux mysql
查看: 3151|回复: 6

Pure LFS怎么理解?

[复制链接]
发表于 2003-4-8 11:02:35 | 显示全部楼层 |阅读模式
Pure LFS是什么意思?
 楼主| 发表于 2003-4-8 13:17:11 | 显示全部楼层
?
发表于 2003-4-8 17:15:49 | 显示全部楼层
从字面意思看是:纯LFS。这里有篇文章自己看一下吧
TITLE:                How to build a "pure" LFS
LFS VERSION:        CVS
AUTHOR:                Ryan Oliver <Ryan.Oliver@pha.com.au>,
                Greg Schafer <gschafer@zip.com.au>

SYNOPSIS:
        The current LFS build method is a lot better than it used to be but is
still somewhat flawed in that not enough emphasis is placed on building a
correct toolchain. This was recently highlighted by criticism levelled at LFS
from senior Linux kernel hacker Alan Cox on the kernel mailing list. Here we
present a new strategy aimed at building a correct toolchain and thus a "pure"
LFS system. It is our belief that building a correct toolchain is the single
most important lesson that people reading the LFS book need to know. Everything
else is secondary.

HINT:

CHANGELOG
=========

  * 2003-XX-XX  Initial revision

INTRODUCTION
============

Broadly speaking, the toolchain comprises binutils, gcc and glibc. As of this
writing, the current LFS version is 4.0. The problems with the build method as
used in this version can be summarised as follows:-

  * too reliant on the host (build) system
    e.g. the autoconf tests for the static tools are performed whilst looking at
    the host system which may be vastly different from the final system. The
    most widely documented and glaring manifestation of this problem is gcc
    which ends up miscompiling a portion of glibc due to this flaw (the
    HAVE_GAS_HIDDEN hack works around this particular problem).

  * too much code is brought in from the host system
    e.g. all the static tools are statically linked against the host's glibc.
    The host's glibc is an unknown quantity and may contain bugs or anything.

  * too susceptible to incompatible glibc changes
    e.g. statically linked binaries compiled on a glibc-2.2.x based system that
    contain calls to getpwuid() crash when run on a glibc-2.3.x based system.

  * glibc is compiled whilst no existing glibc is present
    e.g. the glibc autoconf tests produce different results depending on whether
    an existing glibc is found or not. This leads to inconsistencies and
    encourages hacks and workarounds.

(NOTE - some of the abovementioned issues have been partially addressed in the
CVS version of the book but still do not go far enough and leave too much room
for error.)

To overcome all the issues, a new approach is required. The essence of what is
presented below can be summarised as follows:-

  * build a fully "self contained" and "self hosting" toolchain that has no
    dependencies on the host system.

The key differences between this approach and current LFS are:-

  * a glibc is built in Chapter 5

  * this glibc is built using the Chapter 5 gcc and binutils (NOT the versions
    from the host)

  * the rest of Chapter 5 is built against the new glibc using the new binutils
    and gcc

  * Chapter 5 packages are installed into a prefix of "/stage1" rather than
    "$LFS/static"

Some of the advantages to doing it this way are:-

  * we can build everything shared. It isn't necessary that we build all our
    binaries static in Chapter 5 (though you still can if you want to) as we
    will still have access to the shared libs we create when we chroot.

  * everything we use to build our shared binaries and libraries in Chapter 6
    will ALREADY be built and linked against the glibc we are migrating to. This
    avoids glibc migration issues now and in the future.

The key technical points of how the new approach works are:-

  * careful manipulation of ld's linker scripts (in particular, the SEARCH_DIR
    variables)

  * patching of gcc's "specs" file to tell gcc which dynamic linker to produce
    executables for

  * clever use of mount's "--bind" option to play a few filesystem tricks

(NOTE - use of mount's "--bind" option mandates a minimum kernel version of
2.4.0 on the host. If the host's kernel is earlier than 2.4, an alternative
"symlink hack" method can be employed. But "mount --bind" is definitely the
neatest and preferred solution.)

At this point, it is worth mentioning there are other, less sophisticated ways
of attaining a "pure" LFS. A "brute force" method is to build Chapter 6 twice.
i.e. remove the /static directory (both physically and from the `PATH') then use
Chapter 6 to rebuild itself. This is the basic idea behind the method employed
by the Linux Standards Base folk with their LSB Sample Implementation[1]. Taking
this approach is not practical for the LFS book. It is far too laborious and
nowhere near as educational with regard to some of the toolchain internals we
describe below.

PROCEDURE
=========

Toolchain cleanliness
---------------------
It is important to realise there are varying degrees of "anal retentiveness"
we can employ when building a new toolchain. The more anal we are, the "cleaner"
the toolchain will be. For this reason it might seem we are building packages
more times than we really need to, but you have to keep in mind, the goal here
is to have a fully self hosted and very clean toolchain in which to perform the
final clean build of our target system in Chapter 6. Steps that are not strictly
necessary (i.e. less anal) will be pointed out as we move through the build. In
other words, a few shortcuts can be taken at the expense of anal retentiveness.


How we tested
-------------
We started from a glibc-2.2.5/gcc-2.95.3 based host to ensure any glitches were
caught early. The versions of the toolchain packages used in testing were
binutils-2.13.2, gcc-3.2.1 and glibc-2.3.1.


Chapter 5 - Creating the /stage1 directory
------------------------------------------

We assume you have already reached Chapter 5 of the LFS book. i.e. partition
created, filesystem made, partition mounted, $LFS/static created, lfs user
added, environment setup.

As mentioned in the introduction, we will use "/stage1" instead of "/static"
due to the fact we will be building a dynamic (shared) Chapter 5. This naming is
only a cosmetic thing. Leaving it as /static is likely to cause confusion.
Please revisit the "Creating the $LFS/static directory" chapter of the book but
instead run the following:-

    mkdir $LFS/stage1

Also, don't forget to do the chown bit:-

    chown lfs $LFS/stage1

The next step is to create a "/stage1" directory on the host system. Then we
"mount --bind" the $LFS/stage1 directory onto the /stage1 directory we just
created on the host:-

    mkdir /stage1
    mount --bind ${LFS}/stage1 /stage1

This ensures our toolchain will look in the same place (i.e. /stage1) in both
Chapters 5 and 6 (when we are inside the chroot). This is an important concept
to grasp. This aspect will become clearer as we progress.


Chapter 5 - Setting up the environment
--------------------------------------

Some adjustments to the environment setup are needed. Firstly, we do not use
the:-    export CC="gcc -s"    thing. We are trying to do things correctly here
and strictly speaking, the "-s" is a linker flag. Therefore we will put "-s" in
the LDFLAGS where it belongs like so:-

    export LDFLAGS="-s"

Secondly, we need to add "/static/bin" to the lfs user's `PATH' like so:-

    export PATH=/stage1/binPATH

As we progressively install Chapter 5 packages into "/stage1", the tools we just
built will get picked up in the `PATH' and thus get integrated into the build
process as we move along.

Thirdly, we switch off the "hash" function of the bash shell like so:-

    set +h

Bash has a useful feature whereby it uses a hash table to remember the full
pathnames of executable files to avoid multiple `PATH' searches. This
unfortunately conflicts with our intentions in that we want the newly built
tools to always come first in the `PATH'. The performance impact of disabling
this feature is negligible. To confirm the feature is switched off, simply
type:-    hash    at the shell prompt and it should report something like "su:
hash: hashing disabled"

One thing you'll notice throughout the build is some careful adjustment of the
CFLAGS environment variable. This is NOT TO FIDDLE WITH OPTIMISATION! The sole
purpose is to strip out the "-g" flag and thus save space during the builds. We
also throw in "-pipe" for marginally quicker builds. We do not export the CFLAGS
into the lfs user's environemnt globally because not all packages are
co-operative with their treatment of CFLAGS.


Chapter 5 - Installing binutils - Pass 1 (static)
-------------------------------------------------

This is basically the same as the current Chapter 5 binutils installation but
with an extra twist.

    mkdir ../binutils-build &&
    cd ../binutils-build &&
    CFLAGS="-O2 -pipe" ../binutils-2*/configure --prefix=/stage1 \
       --disable-nls &&
    make LDFLAGS="-all-static -s" &&
    make install

IMPORTANT! - Do NOT remove the binutils-build dir as we are going to reuse it a
bit further down the track. This will be explained further on, but for now, just
run the following:-

    cd ld &&
    make clean &&
    make LDFLAGS="-all-static -s" LIB_PATH=/stage1/lib

DO NOT RUN "make install" AT THIS POINT! We are saving this for later. All will
become clear in due course.

One of the main differences is we use a prefix of /stage1 instead of the usual
$LFS/static. Note the lack of $LFS. It is worth mentioning here that having the
new binutils available from the outset is important because both glibc and gcc
perform various feature tests on the linker and assembler to determine which
software features to enable.


Chapter 5 - Installing gcc - Pass 1 (static)
--------------------------------------------

(NOTE - SHORTCUT ALERT! - if you are building from a host with a minimum gcc-3.2
already installed, it is possible to skip this gcc step. The reason the shortcut
is possible is that the next package, glibc, requires a minimum gcc-3.2. We
recommend against skipping this step because it will mean our Chapter 5 glibc
will have then been compiled with a potentially unclean gcc from the host.)

    mkdir ../gcc-build &&
    cd ../gcc-build &&
    CFLAGS="-O2 -pipe" ../gcc-3*/configure --prefix=/stage1 \
       --with-local-prefix=/stage1 --enable-languages=c \
       --disable-nls --disable-shared &&
    make BOOT_LDFLAGS="-static -s" BOOT_CFLAGS="-O2 -pipe" \
       STAGE1_CFLAGS="-pipe" bootstrap &&
    make install-no-fixedincludes &&
    ln -s gcc /stage1/bin/cc

Here we start to experience some of the magic of the GNU toolchain. It is
important to realise that gcc does not search the `PATH' during it's configure
run to search for which binutils to use. It actually searches
$prefix/TARGET-TRIPLE/bin where TARGET-TRIPLE is for e.g. i686-pc-linux-gnu.
This means everything "just works" and we don't have to specify --with-ld= and
--with-as= to configure.

The extra BOOT_CFLAGS and STAGE1_CFLAGS on the make line are just extra steps to
remove "-g" from the gcc build. A few occurences still remain but we haven't yet
figured out how to weed them out.

The other interesting configure switch is --with-local-prefix=/stage1. The
purpose of this switch is to remove /usr/local/include from gcc's include search
path. It is not absolutely essential but we want to try and minimise the
influence from the host system so this is a logical thing to do. The gcc install
page[2] says:-

"The same value can be used for both --with-local-prefix and --prefix provided
it is not /usr. This can be used to avoid the default search of
/usr/local/include."

which is exactly what we want. You can see the gcc search include order by
compiling a test program with "-v" e.g. gcc -v foo.c. The following snippets of
output demonstrate the issue. This is with the "--with-local-prefix" switch:-

#include "..." search starts here:
#include <...> search starts here:
/stage1/include
/stage1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include
/usr/include
End of search list

And this is without:-

#include "..." search starts here:
#include <...> search starts here:
/usr/local/include
/stage1/include
/stage1/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/include
/usr/include
End of search list


Chapter 5 - Installing kernel headers
-------------------------------------

In normal LFS we install the kernel headers in Chapter 6. But seeing as we are
now installing a glibc in Chapter 5, we need to install the kernel headers in
Chapter 5 also.

The procedure is essentially the same as current LFS with the exception that the
headers are copied to /stage1/include. In other words, follow the procedure from
current LFS (minus the /bin/pwd hacks) and substitute "cp blah /usr/include"
with "cp blah /stage1/include".


Chapter 5 - Installing glibc
----------------------------

By this stage (assuming no shortcuts were taken) we have a new binutils and a
new gcc (both statically linked against the glibc on the host). We'll use both
of these to build the Chapter 5 glibc.

    mkdir -p /stage1/etc &&
    touch /stage1/etc/ld.so.conf &&
    mkdir ../glibc-build &&
    cd ../glibc-build &&
    CFLAGS="-O2 -pipe" ../glibc-2*/configure --prefix=/stage1 \
       --enable-add-ons --disable-profile \
       --with-binutils=/stage1/bin \
       --with-headers=/stage1/include &&
    make &&
    make install

Please note, the use of --with-binutils= and --with-headers= configure switches
is not strictly required. But they do ensure nothing can go wrong with regard
to the kernel headers and binutils that get used during the glibc build. If you
perform a "diff" comparison between the two configured glibc-build dirs, both
with, and without those switches, you'll surely believe it is a lot cleaner to
use them.

As mentioned above, the CFLAGS saves space during the build. If you rely solely
on the LDFLAGS from the environment then the *.a archives will still be chock
full of debug symbols. It is important to understand the glibc build system is
very sensible about how it treats the CFLAGS supplied by the user. In other
words, the CFLAGS above do not change any vital aspect of the glibc build. They
simply remove "-g" and add "-pipe".

The other important thing to realise is that glibc is pretty well self contained
in terms of it's build mechanics. No fancy linker switches are required. It
doesn't rely on compiler or linker defaults as all the required build switches
are supplied "by hand". e.g. you will see stuff like:-

  -Wl,-dynamic-linker=/stage1/lib/ld-linux.so.2

during the glibc build. What is shown there is simply an example of how glibc's
build system overrides gcc's default behaviour of passing:-

  -dynamic-linker=/lib/ld-linux.so.2

to the linker (ld) as it goes about it's business of constructing the binaries
and libraries.


Linker scripts and library search order - A quick overview
----------------------------------------------------------
At this juncture, it is worth discussing how ld (the linker) performs it's
magic. On a normal LFS system you will find the linker scripts located in the
/usr/lib/ldscripts dir. They have names like elf_i386.x, elf_i386.xc and so on.
There are 13 of these scripts altogether but only the 8 that start with elf*
concern us. The others are involved when creating a.out format binaries which
basically means never. The a.out format was superceded years ago by the more
modern ELF format.

The linker scripts for our new toolchain in /stage1 are located in
/stage1/TARGET-TRIPLE/lib/ldscripts. If you view the scripts, you'll notice the
default linker search path (as indicated by the SEARCH_DIR variables) is:-

  $prefix/TARGET-TRIPLE/lib, $prefix/lib, /usr/local/lib, /lib, /usr/lib

where $prefix is the value of the --prefix configure option and TARGET-TRIPLE
is the cpu-arch-os triple for the host (e.g. i686-pc-linux-gnu). Anything linked
by ld using these linker scripts will link against our new glibc installed into
/stage1/lib because /stage1/lib comes before /usr/lib in the search path. So far
so good. This is exactly what we want. However, what we really need is to remove
the /usr/local/lib, /lib, and /usr/lib from the search path altogther. In this
way we can be 100% certain that nothing links against the libraries on the host
system. There are a few ways we can achieve this:-

  1. edit all the linker scripts by hand
  2. perform some sort of sed substitution on each of the scripts
  3. utilise the LIB_PATH variable in ld's Makefile to our advantage

No 3 is the easiest solution. A small mention of LIB_PATH was made back in the
pass 1 binutils section. A bit further down, you'll see how it's usage helps us.


Gcc's specs file - A quick overview
-----------------------------------
>From the gcc info page:-

"`gcc' is a driver program.  It performs its job by invoking a sequence of other
programs to do the work of compiling, assembling and linking.  GCC interprets
its command-line parameters and uses these to deduce which programs it should
invoke, and which command-line options it ought to place on their command lines.
This behavior is controlled by "spec strings".  In most cases there is one spec
string for each program that GCC can invoke, but a few programs have multiple
spec strings to control their behavior.  The spec strings built into GCC can be
overridden by using the `-specs=' command-line switch to specify a spec file.
"Spec files" are plaintext files that are used to construct spec strings."

To find out where the specs file is located simply type in "gcc -v" like so:-

  gws@tigers-lfs:~$ gcc -v 2>&1 | head -n 1
  Reading specs from /static/lib/gcc-lib/i686-pc-linux-gnu/3.2.1/specs

If you examine a normal dynamic executable using the readelf utiltity, you can
determine which dynamic linker (i.e. program interpreter) the executable was
compiled for. Take a look at this example:-

  gws@tigers-lfs:~/src$ readelf -a foo | grep interpreter
        [Requesting program interpreter: /lib/ld-linux.so.2]

If we want to change the program interpreter that gets embedded into our
binaries we need to utilise the linker switch -dynamic-linker e.g.
-Wl,-dynamic-linker=/stage1/lib/ld-linux.so.2. But forcing this onto every
package we compile can be quite troublesome. It is much easier to simply force
the issue by adjusting the specs string in the specs file to point where we
want.

There are a few ways we can achive this:-

  1. edit, sed or patch the specs file
  2. patch the gcc source before we compile it

Both methods are used below, depending on which stage of the build process we
are at.


Chapter 5 - Locking in our new glibc
------------------------------------

Now that we have the lectures out of the way, it is down to business. By now we
have our Chapter 5 glibc installed and operational. This is the point in the
proceedings where we need to ensure that we do not link against the libraries on
the host system.

The first thing to do is edit our gcc specs file. Simply edit the file by hand
using your favourite editor and replace the single occurrence of
"/lib/ld-linux.so.2" with "/stage1/lib/ld-linux.so.2".

(NOTE - a patch or a sed might be more appriate above - dunno)

The next thing to do is adjust the linker scripts. Remember back in the binutils
pass 1 section we added a couple of extra commands at the end? Well here is
where we utilise those commands. Simply cd back into your binutils-build dir and
run the following:-

    cd ld &&
    make install-data-local

This installs the adjusted linker scripts. The linker scripts now contain no
mention of /lib, /usr/lib or /usr/local/lib. From this point onwards, everything
will link only against the libs in /stage1/lib.


Chapter 5 - Installing binutils - Pass 2 (shared)
-------------------------------------------------

Here we reinstall binutils. It will be dynamically linked against the new glibc
(guaranteed due to the "lock in" steps we took in the last section).

    mkdir ../binutils-build &&
    cd ../binutils-build &&
    CFLAGS="-O2 -pipe" ../binutils-2*/configure --prefix=/stage1 \
       --disable-nls &&
    make -e LDFLAGS="-s" LIB_PATH=/stage1/lib &&
    make install

The only curious command here is the use of "make -e". We need to do this so
that the LIB_PATH=/stage1/lib gets passed down to the sub-make process during
the build of ld. Some people may consider this "impure" or a bit of a security
risk. The use of "make -e" gives variables taken from the environment precedence
over variables from makefiles. Another solution would be to perform a sed on the
ld/Makefile before compilation. Or we could even employ a similar (cd ld; make
clean; make LIB_PATH=/static/lib; make install-data-local) technique as per our
pass 1.


Chapter 5 - Installing gcc - Pass 2 (shared)
--------------------------------------------

(NOTE - SHORTCUT ALERT! - this step could be considered optional as we already
have a new gcc to begin compiling Chapter 6 with. However that gcc is statically
linked against the host's glibc. By recompiling gcc now, we'll end up with a
completely shared toolchain linked against the new glibc. And it will be very
clean indeed.)

Before we start this recompile of gcc, we really need to ensure that the
traditional spec string for the dynamic linker doesn't somehow influence the
build. We therefore patch gcc (the file is gcc/config/i386/linux.h). It is just
a simple substition of "/lib/ld-linux.so.2" with "/stage1/lib/ld-linux.so.2". Or
again, we could perform a sed instead. It doesn't really matter. The end result
will be the same as manually editing the specs file at the end of the build like
we did earlier on.


    patch -Np1 -i ../gcc-3.2.1.specs.patch &&
    mkdir ../gcc-build &&
    cd ../gcc-build &&
    CFLAGS="-O2 -pipe" ../gcc-3*/configure --prefix=/stage1 \
       --with-local-prefix=/stage1 --enable-languages=c --disable-nls \
       --enable-shared &&
    make BOOT_LDFLAGS="-s" BOOT_CFLAGS="-O2 -pipe" \
       STAGE1_CFLAGS="-pipe" bootstrap &&
    make install-no-fixedincludes

The main difference between here and pass 1 is the --enable-shared configure
switch to build the shared gcc libs.


Chapter 5 - Toolchain Summary
-----------------------------

At this stage, we have compiled gcc twice, binutils twice and glibc once. A bit
excessive you think? Not quite, when you realise how clean the toolchain really
is. That feeling of cleanliness is very powerful and worth every bit of effort
in our opinion.


Chapter 5 - Remaining packages - (shared)
-----------------------------------------

The list of remaining packages in Chapter 5 is still open to debate. We
definitely need to add ncurses. Additionally, the build order is still under
review to maximise the cleanliness effect.




TODO
====

  - remainder of Chapter 5 packages
  - Chapter 6
  - look at "make check" stuff
  - look at ways to remove /usr/include from gcc's include search path
  - look at ways to remove unwanted dirs from "gcc -print-search-dirs"
  - look at gcc-2.95.x for kernel compiles
  - look at using gcc's -enable-version-specific-runtime-libs for installing
    multilple versions of gcc into the one prefix
  - look at NLS stuff
  - look at C++ stuff




CREDITS
=======

Ryan - Devised the whole scheme. Bucket loads of testing and research. Helped
       with documentation.

Greg - Wrote the bulk of the documentation. Helped refine the process, Helped
       with testing and research. Initially ranted on lfs-dev about potential
       build flaws and thus spurred Ryan into action :-)

lfs-dev folk - input and ideas.

FOOTNOTES
=========

1. http://www.linuxbase.org/impl/
2. http://gcc.gnu.org/install/configure.html
发表于 2003-4-8 18:54:05 | 显示全部楼层
pure ,英文的意思为纯净的。
在LFS里面,大概的意思是就是说从所有软件的编译环境包括所有产生的代码都是纯净的,没有掺入原有产生这些代码的主系统的东西。
即新生成的系统是不依赖于主系统的东西而存在的。是一个干净的新的系统。
发表于 2003-4-8 19:31:14 | 显示全部楼层
没错,它纯净表现在:
不会把主系统里的头文件搞到lfs里面来。
自己的工具链能满足编译自身的需要。
不提供给你源码以外的东西。
这几点,现在还是唯一能做到的呢。其他的版本:redhat,mandrake全是二进制文件了,gentoo好些,不过gentoo为了减少麻烦,让更多的人容易装上,所以提供了stage1-stage3的二进制包。
LFS能让你了解一个系统是怎样做出来的,很有成就感吧?
PS:上面那位兄弟,你贴的pure lfs hints,有中文翻译的版本,在:
http://lfs.cosoft.org.cn/plfs
 楼主| 发表于 2003-4-9 12:47:29 | 显示全部楼层
我不明白的是,lfs不也是自己编译的吗?难道他还不纯?
发表于 2003-4-9 12:57:18 | 显示全部楼层
介绍

总的来说,工具链由 binutils, gcc 和 glibc 组成。写本文的时候,最新的 LFS 版本是 4.0.这个版本中编译方法的问题可以归纳成以下几点:-

    * 太依赖于主(编译)系统。比如,静态工具的 autoconf 测试时,是在与最终系统可能 大不相同的主系统中寻找。这个问题最常记载和表现在 gcc 错误的编译了一部份的 glibc( HAVE_GAS_HIDDEN 是解决这一特定错误的变通办法).
    * 从主系统里带入了太多代码。比如,所有静态工具都静态连接到主系统的 glibc.主 系统的 glibc 质量不明,可能会有 bug 或其他的问题。
    * 对不兼容的 glibc 变化太敏感。比如,在 glibc-2.2.x 的系统里静态连接的工具, 如果包含了对 getpwuid() 的调用,在 glibc-2.3.x系统里运行就会崩溃。
    * glibc 是在没有 glibc 的情况下编译的。比如,glibc 的 autoconf 测试在这种情况 下会产生与有 glibc 时完全不同的结果,会造成不一致,需要 hack 和变通办法。

(注意:上面提到的一些问题在 CVS 版本的书中已经部份的处理了,但还不充分,留下了太多出错的可能。)

为了克服所有的问题,需要我们找到一个新的解决方案。本文将阐述的办法,它的本质可以归纳为:-

    * * 创建一个完全“自给自足”的工具链,它不依赖于主系统。

这个办法和现在的 LFS 主要区别在:-

    * * 在第五章里编译一个 glibc
    * * 这个 glibc 用第五章的 gcc 和 binutils(而不是主系统的版本)来编译
    * * 第五章的余下部份就连接到新的 glibc 并使用新的 binutils 和 gcc
    * * 第五章的包安装在“/stage1”前缀下而不是 "$LFS/static"

这个办法的好处有:-

    * * 我们可以动态的连接所有东西。在第五章中也无须编译静态二进制文件(当然如果你想, 也是可以的),因为我们在 chroot 环境中仍然能使用第五章中创建的共享库文件。
    * * 在第六章里编译共享二进制文件和库文件所需要的一切,都是连接到我们移植的 glibc 上。这就避免了 gblic 的移植问题,不管是现在还是将来。
    * * 适合编译 LFS 的主系统应该更多了,因为对主系统的依赖少了。理论上来说,唯一的 要求是主系统的编译器能从 bootstrap 阶段开始编译 gcc。
    * * 目前 LFS 技术支持中的很大一部份问题都会消失。例如,“不能静态编译第五章的 包”,“不能编译 texinfo”,“binutils 检测相关问题”。

这个方法的技术要点在于:-

    * * 与跨平台编译的原则有些相似,靠把工具装到某个前缀下,并协同工作,这利用了一 些 GNU 的“魔法”。
    * * 仔细的控制 ld 的连接器脚本(尤其是 SEARCH_DIR 变量)
    * * 编辑 gcc 的 "specs" 文件来告诉 gcc 为哪个动态连接器创建可执行程序

应该说明,有更简单的方法来得到一个“纯净的”LFS 系统。一个"粗鲁的"方法是编译第六章两次。例如,删除 /static 目录(既是物理上删除,同时也从‘PATH’中去掉它)然后使用第六章来重新编译它自身。这是 Linux Standards Base (是linux的一个统一技术标准)中在 LSB Sample Implementation[1]中所用方法的主要思想。对 LFS 来说,使用这个方法不可行,因为它既费力,与我们下面所揭示的工具链相比又没有什么教育意义。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

快速回复 返回顶部 返回列表