1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
|
<chapter id="chapter-preparation" xreflabel="Chapter 4">
<title>Last preparations</title>
<?dbhtml filename="chapter04.html" dir="chapter04"?>
<sect1 id="prepare-aboutlfs">
<title>About $LFS</title>
<?dbhtml filename="aboutlfs.html" dir="chapter04"?>
<para>Throughout this book the environment variable LFS will be used several
times. It is paramount that this variable is always defined. It should be set
to the mount point you chose for your LFS partition. Check that your LFS
variable is set up properly with:</para>
<screen><userinput>echo $LFS</userinput></screen>
<para>Make sure the output shows the path to your LFS partition's mount
point, which is <filename class="directory">/mnt/lfs</filename> if you
followed our example. If the output is wrong, you can always set the variable
with:</para>
<screen><userinput>export LFS=/mnt/lfs</userinput></screen>
<para>Having this variable set means that if you are told to run a command like
<userinput>mkdir $LFS/tools</userinput>, you can type it literally. Your shell
will replace "$LFS" with "/mnt/lfs" (or whatever you set the variable to) when
it processes the command line.</para>
</sect1>
<sect1 id="prepare-creatingtoolsdir">
<title>Creating the $LFS/tools directory</title>
<?dbhtml filename="creatingtoolsdir.html" dir="chapter05"?>
<para>All programs compiled in this chapter will be installed under <filename
class="directory">$LFS/tools</filename> to keep them separate from the
programs compiled in the next chapter. The programs compiled here are only
temporary tools and won't be a part of the final LFS system and by keeping them
in a separate directory, we can later easily throw them away.</para>
<para>Later on you might wish to search through the binaries of your system to
see what files they make use of or link against. To make this searching easier
you may want to choose a unique name for the directory in which the temporary
tools are stored. Instead of the simple "tools" you could use something like
"tools-for-lfs". However, you'll need to be careful to adjust all references to
"tools" throughout the book -- including those in any patches, notably the
GCC Specs Patch.</para>
<para>Create the required directory by running the following:</para>
<screen><userinput>mkdir $LFS/tools</userinput></screen>
<para>The next step is to create a <filename>/tools</filename> symlink on
your host system. It will point to the directory we just created on the LFS
partition:</para>
<screen><userinput>ln -s $LFS/tools /</userinput></screen>
<note><para>The above command is correct. The <command>ln</command> command
has a few syntactic variations, so be sure to check the info page before
reporting what you may think is an error.</para></note>
<para>The created symlink enables us to compile our toolchain so that it always
refers to <filename>/tools</filename>, meaning that the compiler, assembler
and linker will work both in this chapter (when we are still using some tools
from the host) <emphasis>and</emphasis> in the next (when we are chrooted to
the LFS partition).</para>
</sect1>
<sect1 id="prepar-addinguser">
<title>Adding the user lfs</title>
<?dbhtml filename="addinguser.html" dir="chapter05"?>
<para>When logged in as <emphasis>root</emphasis>, making a single mistake
can damage or even wreck your system. Therefore we recommend that you
build the packages in this chapter as an unprivileged user. You could
of course use your own user name, but to make it easier to set up a clean
work environment we'll create a new user <emphasis>lfs</emphasis> and
use this one during the installation process. As <emphasis>root</emphasis>,
issue the following command to add the new user:</para>
<screen><userinput>useradd -s /bin/bash -m -k /dev/null lfs</userinput></screen>
<para>The meaning of the switches:</para>
<itemizedlist>
<listitem><para><userinput>-s /bin/bash</userinput>: This makes
<userinput>bash</userinput> the default shell for user
<emphasis>lfs</emphasis>.</para></listitem>
<listitem><para><userinput>-m -k /dev/null</userinput>: These create a home
directory for <emphasis>lfs</emphasis>, while preventing the files from a
possible <filename>/etc/skel</filename> being copied into it.</para></listitem>
</itemizedlist>
<para>If you want to be able to log in as <emphasis>lfs</emphasis>, then give
this new user a password:</para>
<screen><userinput>passwd lfs</userinput></screen>
<para>Now grant this new user <emphasis>lfs</emphasis> full access to
<filename class="directory">$LFS/tools</filename> by giving it ownership
of the directory:</para>
<screen><userinput>chown lfs $LFS/tools</userinput></screen>
<para>If you made a separate working directory as suggested, give user
<emphasis>lfs</emphasis> ownership of this directory too:</para>
<screen><userinput>chown lfs $LFS/sources</userinput></screen>
<para>Next, login as user <emphasis>lfs</emphasis>. This can be done via a
virtual console, through a display manager, or with the following substitute
user command:</para>
<screen><userinput>su - lfs</userinput></screen>
<para>The "<command>-</command>" instructs <command>su</command> to start a
<emphasis>login</emphasis> shell.</para>
</sect1>
<sect1 id="prepare-settingenvironment">
<title>Setting up the environment</title>
<?dbhtml filename="settingenvironment.html" dir="chapter05"?>
<para>We're going to set up a good working environment by creating two new
startup files for the <command>bash</command> shell. While logged in as
user <emphasis>lfs</emphasis>, issue the following command to create a new
<filename>.bash_profile</filename>:</para>
<screen><userinput>cat > ~/.bash_profile << "EOF"</userinput>
exec env -i HOME=$HOME TERM=$TERM PS1='\u:\w\$ ' /bin/bash
<userinput>EOF</userinput></screen>
<para>Normally, when you log on as user <emphasis>lfs</emphasis>,
the initial shell is a <emphasis>login</emphasis> shell which reads the
<filename>/etc/profile</filename> of your host (probably containing some
settings of environment variables) and then <filename>.bash_profile</filename>.
The <command>exec env -i ... /bin/bash</command> command in the latter file
replaces the running shell with a new one with a completely empty environment,
except for the HOME, TERM and PS1 variables. This ensures that no unwanted and
potentially hazardous environment variables from the host system leak into our
build environment. The technique used here is a little strange, but it achieves
the goal of enforcing a clean environment.</para>
<para>The new instance of the shell is a <emphasis>non-login</emphasis> shell,
which doesn't read the <filename>/etc/profile</filename> or
<filename>.bash_profile</filename> files, but reads the
<filename>.bashrc</filename> file instead. Create this latter file now:</para>
<screen><userinput>cat > ~/.bashrc << "EOF"</userinput>
set +h
umask 022
LFS=/mnt/lfs
LC_ALL=POSIX
PATH=/tools/bin:/bin:/usr/bin
export LFS LC_ALL PATH
<userinput>EOF</userinput></screen>
<para>The <command>set +h</command> command turns off
<command>bash</command>'s hash function. Normally hashing is a useful
feature: <command>bash</command> uses a hash table to remember the
full pathnames of executable files to avoid searching the PATH time and time
again to find the same executable. However, we'd like the new tools to be
used as soon as they are installed. By switching off the hash function, our
"interactive" commands (<command>make</command>,
<command>patch</command>, <command>sed</command>,
<command>cp</command> and so forth) will always use
the newest available version during the build process.</para>
<para>Setting the user file-creation mask to 022 ensures that newly created
files and directories are only writable for their owner, but readable and
executable for anyone.</para>
<para>The LFS variable should of course be set to the mount point you
chose.</para>
<para>The LC_ALL variable controls the localization of certain programs,
making their messages follow the conventions of a specified country. If your
host system uses a version of Glibc older than 2.2.4,
having LC_ALL set to something other than "POSIX" or "C" during this chapter
may cause trouble if you exit the chroot environment and wish to return later.
By setting LC_ALL to "POSIX" (or "C", the two are equivalent) we ensure that
everything will work as expected in the chroot environment.</para>
<para>We prepend <filename>/tools/bin</filename> to the standard PATH so
that, as we move along through this chapter, the tools we build will get used
during the rest of the building process.</para>
<para>Finally, to have our environment fully prepared for building the
temporary tools, source the just-created profile:</para>
<screen><userinput>source ~/.bash_profile</userinput></screen>
</sect1>
<sect1 id="prepare-aboutsbus">
<title>About SBUs</title>
<?dbhtml filename="aboutsbus.html" dir="chapter04"?>
<para>Most people would like to know beforehand how long it approximately
takes to compile and install each package. But "Linux from Scratch" is built
on so many different systems, it is not possible to give actual times that are
anywhere near accurate: the biggest package (Glibc) won't take more than
twenty minutes on the fastest systems, but will take something like three days
on the slowest -- no kidding. So instead of giving actual times, we've come up
with the idea of using the <emphasis>Static Binutils Unit</emphasis>
(abbreviated to <emphasis>SBU</emphasis>).</para>
<para>It works like this: the first package you compile in this book is the
statically linked Binutils in <xref linkend="chapter-temporary-tools"/>, and the time it
takes to compile this package is what we call the "Static Binutils Unit" or
"SBU". All other compile times will be expressed relative to this time.</para>
<para>For example, the time it takes to build the static version of GCC is
&gcc-time-tools-pass1;s. This means that if on your system it took 10 minutes
to compile and install the static Binutils, then you know it will take
approximately 45 minutes to build the static GCC. Fortunately, most build times
are much shorter than the one of Binutils.</para>
<para>Note that if the system compiler on your host is GCC-2 based, the SBUs
listed may end up being somewhat understated. This is because the SBU is based
on the very first package, compiled with the old GCC, while the rest of the
system is compiled with the newer GCC-&gcc-version; which is known to be
approximately 30% slower.</para>
<para>Also note that SBUs don't work well for SMP-based machines. But if you're
so lucky as to have multiple processors, chances are that your system is so fast
that you won't mind.</para>
<para>If you wish to see actual timings for specific machines, have a look at
<ulink url="&lfs-root;~bdubbs/"/>.</para>
</sect1>
<sect1 id="prepare-abouttestsuites">
<title>About the test suites</title>
<?dbhtml filename="abouttestsuites.html" dir="chapter04"?>
<para>Most packages provide a test suite. Running the test suite for a newly
built package is generally a good idea, as it can provide a nice sanity check
that everything compiled correctly. A test suite that passes its set of checks
usually proves that the package is functioning as the developer intended. It
does not, however, guarantee that the package is totally bug free.</para>
<para>Some test suites are more important than others. For example, the test
suites for the core toolchain packages -- GCC, Binutils, and Glibc -- are of
the utmost importance due to their central role in a properly functioning
system. But be warned, the test suites for GCC and Glibc can take a very long
time to complete, especially on slower hardware.</para>
<note><para>Experience has shown us that there is little to be gained from running
the test suites in <xref linkend="chapter-temporary-tools"/>. There can be no
escaping the fact that the host system always exerts some influence on the
tests in that chapter, often causing weird and inexplicable failures. Not only
that, the tools built in <xref linkend="chapter-temporary-tools"/> are
temporary and eventually discarded. For the average reader of this book we
recommend <emphasis>not</emphasis> to run the test suites in <xref
linkend="chapter-temporary-tools"/>. The instructions for running those test
suites are still provided for the benefit of testers and developers, but they
are strictly optional for everyone else.</para></note>
<para>A common problem when running the test suites for Binutils and GCC is
running out of pseudo terminals (PTYs for short). The symptom is a very high
number of failing tests. This can happen for several reasons, but the most
likely cause is that the host system doesn't have the
<emphasis>devpts</emphasis> file system set up correctly. We'll discuss this in
more detail later on in <xref linkend="chapter-temporary-tools"/>.</para>
<para>Sometimes package test suites will give false failures. You can
consult the LFS Wiki at <ulink url="&wiki-root;"/> to verify that these
failures are normal. This applies to all tests throughout the book.</para>
</sect1>
</chapter>
|