Typo
[linux_from_scratch_hints.git] / OLD / alfs_paco.txt
blob2c33dc3ce208bc989ca1968073d1dd056071c405
1 AUTHOR:       David Rosal i Ricart <david.rosal@upf.edu>
3 DATE:         2005-10-24
5 LICENSE:      GNU Free Documentation License Version 1.2
7 SYNOPSIS:     Using paco in ALFS
9 PRIMARY URI:  http://paco.sourceforge.net/doc/
13 DESCRIPTION:
14 The program paco can be used along with nALFS to track the installation of an
15 entire LFS system. This is done by editing the XML ALFS profiles properly.
16 This hint intends to provide instructions to edit those profiles and integrate
17 paco in ALFS in the most neat and safe way.
21 ATTACHMENTS:
23   * The LFS-6.1 profile paco patch:
24     --> http://paco.sourceforge.net/dl/profile-LFS-6.1-paco.patch
28 PREREQUISITES:
30   * The program nALFS >= 1.2.4
31     --> http://www.linuxfromscratch.org/alfs/downloads/stable/
33   * The ALFS profiles for LFS-6.1:
34     --> http://www.linuxfromscratch.org/alfs/downloads/profiles/stable/
35   
36   * The program paco. Version 1.10.0 or later.
37     --> http://sourceforge.net/project/showfiles.php?group_id=118115
41 HINT:
45 0. INTRODUCTION
46 ===============
47 There are mainly two ways to integrate paco in ALFS: the "brute force" way, and
48 the neat way.
49 In this hint I'm going to describe the neat way in detail, but first I wanted to
50 say a few words about the "brute force" way, which indeed works fine, and has
51 been happily used by some ALFS'ers until today.
53 Note: Regardless the method used, before running nALFS, the tarball of paco has
54 to be copied into the directory where the other LFS packages reside.
57 1. THE BRUTE FORCE WAY
58 ======================
59 In a nutshell, this method consists of (ab)using the element
60 <execute command="paco"> to wrap each command that installs files into the
61 system.
62 As an example, let's look at the following piece of XML "code", taken from the
63 file chapter06/binutils.xml in the LFS-6.1 profile, which installs the package
64 binutils:
66     ---[ begin XML ]---
68     <make>
69       <param>tooldir=/usr</param>
70       <param>install</param>
71     </make>
72     <copy>
73       <source>../&binutils-directory;/include/libiberty.h</source>
74       <destination>/usr/include</destination>
75     </copy>
77     ---[ end XML ]---
79 The above fragment could be paco'ized thusly:
81     ---[ begin XML ]---
83     <execute command="paco">
84       <param>-lp binutils-&binutils-version;</param>
85       <param>make tooldir=/usr install</param>
86     </execute>
87     <execute command="paco">
88       <param>-lp+ binutils-&binutils-version;</param>
89       <param>cp ../&binutils-directory;/include/libiberty.h</param>
90       <param>/usr/include</param>
91     </execute>
93     ---[ end XML ]---
95 If you're familiar with paco, this is quite straightforward.
96 With this method is always possible to track package installations, no matter
97 the complexity or number of the commands involved, but it's not very... you
98 know, clever, because it does not take advantage of the variety of elements
99 defined in the ALFS DTD, and replaces each of them with the element <execute>.
101 Next I'm gonna describe in detail the process of building an LFS system with
102 nALFS and paco in a definitely better way.
105 2. THE NEAT WAY
106 ===============
107 [ Note for impatients: Go directly to section 2.1 of this hint. ]
110 2.0. Technichal notes
111 =====================
112 To log package installations, paco uses a shared library to wrap the commands
113 that install files into the system.
114 Internally, right before spawning those commands, paco sets the following
115 environment variables:
117   LD_PRELOAD contains the path to the mentioned libpaco-log shared library,
118   which is responsible to catch the system calls that install files into the
119   system. Once libpaco-log is preloaded, it retrieves the rest of the variables
120   from the environment.
122   PACO_TMPFILE contains the path to the intermediate temporary log file used to
123   comunicate libpaco-log and paco.
125   If PACO_DEBUG is set to "yes", then libpaco-log prints debugging information.
127   PACO_INCLUDE and PACO_EXCLUDE are a colon-separated list of paths to include
128   or exclude when logging the created files.
131 What we'll going to do in ALFS is to use the XML element <variable> to set those
132 variables "by hand".
134 From now on, the files in the LFS-6.1 profile will be referenced using paths
135 relative to the LFS-6.1 profile directory, as created when unpacking the
136 profile-LFS-6.1.tar.bz2 tarball.
138 All of PACO_* variables may be set in the file LFS.xml, at the beggining of each
139 chapter in which any package is installed, though it does not hurt if they are
140 set throughout the whole LFS installation.
142 The variable LD_PRELOAD must be set separately in each XML profile in which any
143 package is installed. More strictly, it must be set whenever any install command
144 (or group of them) are executed whithin those profiles.
145 To ensure that the libpaco-log library is loaded only during the execution of
146 the install commands, we have to join them toghether in a separate <stage>.
147 Thus, the LD_PRELOAD variable is only set whithin that stage, and we prevent the
148 log to be contaminated with all the files created during the configure, patch
149 and build commands.
151 Currently, in the LFS-6.1 profiles, the whole process of building and installing
152 a package take place in a single stage called "Installing". We're going to split
153 that stage into different smaller pieces, defining these new kinds of stages:
155   "Building":   Patches are applied. The package is configured and built.
156   "Installing": LD_PRELOAD is set, and the package is installed.
157   "Logging":    Paco is used to create a log for the installed package, reading
158                 the list of files to log from the PACO_TMPFILE.
159   
160 The stages "Unpacking" and "Cleanup" are not modified.
162 The "Building" stage can be omitted in those packages that don't need to be
163 configured or built, like lfs-bootscripts or man-pages.
165 IMPORTANT: The file PACO_TMPFILE must be removed at the beggining of the
166 "Installing" stage, and at the end of the "Logging" stage, to clear the list of
167 files to log.
169 See an example of how should it be done in section 2.3 below.
172 2.1. Patching the LFS profile
173 =============================
174 All changes can be done automatically in one step, by applying the patch
175 profile-LFS-6.1-paco.patch from the LFS-6.1 profiles directory:
177     $ patch -Np1 -i </path/to/the/patch>
179 This hint could finish here, since the above patch makes all needed
180 modifications, but I'll give detailed information on what is actually done by
181 that patch, for those who want to know more, or tune it to their own
182 preferences.
185 2.2. Cookbook to make it by hand
186 ================================
187 We'll consider that we are not interested on tracking the installations of the
188 packages in chapter 5 ("Constructing a Temporary System"), so all XML files in
189 directory chapter05 that install packages will be left untouched.
192 chapter05/creatingtoolsdir.xml
193 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
194 An additional <source> element has to be added, to copy the paco package into
195 the LFS partition:
197     ---[ begin file fragment ]---
199     <source>&ncurses-package;</source>
200     <source>&paco-package;</source>
201     <source>&patch-package;</source>
203     ---[ end file fragment ]---
206 config/package.ent
207 ~~~~~~~~~~~~~~~~~~
208 The following 3 lines have to be added:
210     ---[ begin file fragment ]---
212     <!ENTITY paco-version "1.10.0">
213     <!ENTITY paco-package "paco-&paco-version;.tar.bz2">
214     <!ENTITY paco-directory "paco-&paco-version;">
216     ---[ end file fragment ]---
219 config/paco.ent
220 ~~~~~~~~~~~~~~~
221 We have to create the file config/paco.ent, containing the paco related
222 entities:
224     ---[ begin file ]---
226     <!-- PACO_TMPFILE -->
227     <!ENTITY paco-tmpfile "/tmp/paco.tmp">
229     <!-- LD_PRELOAD (path to the libpaco-log  shared library) -->
230     <!ENTITY paco-lib "/usr/lib/libpaco-log.so">
232     <!-- path to the paco log directory -->
233     <!ENTITY paco-logdir "/var/log/paco">
235     <!-- PACO_INCLUDE and PACO_EXCLUDE -->
236     <!ENTITY paco-include "/">
237     <!ENTITY paco-exclude "/tmp:/tools:/sources">
239     <!-- PACO_DEBUG -->
240     <!ENTITY paco-debug "no_thanks">
242     <!-- different XML "macros":
243       'paco-clear'        removes the temporary log file.
244       'paco-ld-preload'   sets the LD_PRELOAD variable.
245       'paco-log-dirname'  runs "paco -lD" to log packages.
246     -->
247     <!ENTITY paco-clear "<remove>&paco-tmpfile;</remove>">
249     <!ENTITY paco-ld-preload
250       "<environment>
251         <variable name='LD_PRELOAD'>&paco-lib;</variable>
252       </environment>">
253   
254     <!ENTITY paco-log-dirname
255       "<execute command='paco'>
256         <param>-lD &lt; &paco-tmpfile;</param>
257       </execute>
258       &paco-clear;">
260     ---[ end file ]---
263 chapter06/paco.xml
264 ~~~~~~~~~~~~~~~~~~
265 Paco itself should be installed as the first package in chapter 6, so we have to
266 create the file chapter06/paco.xml, with the commands needed to install it:
268     ---[ begin file ]---
270     <?xml version="1.0" encoding="iso-8859-1"?>
271     <!DOCTYPE alfs SYSTEM "../DTD/ALFS.dtd"
272     [
273     <!ENTITY % general_entities SYSTEM "../config/general.ent">
274     <!ENTITY % package_entities SYSTEM "../config/package.ent">
275     <!ENTITY % paco_entities SYSTEM "../config/paco.ent">
276     %general_entities;
277     %package_entities;
278     %paco_entities;
279     ]>
280     <alfs>
281       <package name="paco" version="&paco-version;">
282         <stage name="Unpacking">
283           <unpack>
284             <archive>&packages_dir;/&paco-package;</archive>
285             <destination>&build_dir;</destination>
286           </unpack>
287         </stage>
288         <stage name="Installing">
289           <stageinfo>
290             <base>&build_dir;/&paco-directory;</base>
291           </stageinfo>
292           <configure>
293             <param>--prefix=/usr</param>
294             <param>--disable-gpaco</param>
295             <param>--sysconfdir=/etc</param>
296           </configure>
297           <make />
298           <make>
299             <param>install</param>
300           </make>
301           <textdump>
302             <file>/etc/pacorc</file>
303             <content>
304               =LOGDIR=&paco-logdir;
305               =INCLUDE=&paco-include;
306               =EXCLUDE=&paco-exclude;
307             </content>
308           </textdump>
309         </stage>
310         <stage name="Cleanup">
311           <remove>&build_dir;/&paco-directory;</remove>
312         </stage>
313       </package>
314     </alfs>
316     ---[ end file ]---
319 LFS.xml
320 ~~~~~~~
321 The file LFS.xml has to be edited to include the installation of paco, right
322 after the 'basic-dev' section in chapter 6:
324     ---[ begin file fragment ]---
326     <xi:include href="chapter06/basic-dev.xml" />
327     <xi:include href="chapter06/paco.xml" />
328     <xi:include href="chapter06/libc-headers.xml" />
329   
330     ---[ end file fragment ]---
332 The paco environment variables have to be set in chapters 6, 7, 8 and 9.
333 For each of these chapters, in the <environment> element, the following variable
334 settings must be inserted:
336     ---[ begin file fragment ]---
338     <variable name="PACO_DEBUG">&paco-debug;</variable>
339     <variable name="PACO_TMPFILE">&paco-tmpfile;</variable>
340     <variable name="PACO_INCLUDE">&paco-include;</variable>
341     <variable name="PACO_EXCLUDE">&paco-exclude;</variable>
343     ---[ end file fragment ]---
346 chapter0?/*.xml
347 ~~~~~~~~~~~~~~~
348 Finally, the hard work: Each and every XML profile in which any package is
349 installed has to be modified, if we want that package to be logged.
350 Since not all packages are installed the same way, it's not easy to make the
351 modifications in an automatized way.
353 An example of how should it be done in practice follows.
356 2.3. Example
357 ============
358 Let's take the file chapter06/zlib.xml. I have stripped some parts like the
359 "Patching" stage and the md5 checksum to make it simpler. This file is a good
360 example, because install and non-install commands take place alternatively.
362 Whithout using paco the file looks thusly:
364     ---[ begin file ]---
366     <?xml version="1.0" encoding="iso-8859-1"?>
367     <!DOCTYPE alfs SYSTEM "../DTD/ALFS.dtd"
368     [
369     <!ENTITY % general_entities SYSTEM "../config/general.ent">
370     <!ENTITY % package_entities SYSTEM "../config/package.ent">
371     %general_entities;
372     %package_entities;
373     ]>
374     <alfs>
375       <package name="zlib" version="&zlib-version;">
376         <stage name="Unpacking">
377           <unpack>
378             <archive>&packages_dir;/&zlib-package;</archive>
379             <destination>&build_dir;</destination>
380           </unpack>
381         </stage>
382         <stage name="Installing">
383           <stageinfo>
384             <base>&build_dir;/&zlib-directory;</base>
385           </stageinfo>
386           <configure>
387             <param>--prefix=/usr</param>
388             <param>--shared</param>
389           </configure>
390           <make />
391           <make>
392             <param>install</param>
393           </make>
394           <remove>/lib/libz.so</remove>
395           <link>
396             <option>force</option>
397             <target>../../lib/libz.so.&zlib-version;</target>
398             <name>/usr/lib/libz.so</name>
399           </link>
400           <make>
401             <param>clean</param>
402           </make>
403           <configure>
404             <param>--prefix=/usr</param>
405           </configure>
406           <make />
407           <make>
408             <param>install</param>
409           </make>
410           <permissions mode="644">
411             <name>/usr/lib/libz.a</name>
412           </permissions>
413         </stage>
414         <stage name="Cleanup">
415           <remove>&build_dir;/&zlib-directory;</remove>
416         </stage>
417       </package>
418     </alfs>
420     ---[ end file ]---
423 And here's the same file, but using paco to track the installation.
424 Newly added lines are marked with '+' at the beggining. Modified lines are
425 marked with '!':
427     ---[ begin file ]---
429     <?xml version="1.0" encoding="iso-8859-1"?>
430     <!DOCTYPE alfs SYSTEM "../DTD/ALFS.dtd"
431     [
432     <!ENTITY % general_entities SYSTEM "../config/general.ent">
433     <!ENTITY % package_entities SYSTEM "../config/package.ent">
434 +   <!ENTITY % paco_entities SYSTEM "../config/paco.ent">
435 +   %paco_entities;
436     %general_entities;
437     %package_entities;
438     ]>
439     <alfs>
440       <package name="zlib" version="&zlib-version;">
441         <stage name="Unpacking">
442           <unpack>
443             <archive>&packages_dir;/&zlib-package;</archive>
444             <destination>&build_dir;</destination>
445           </unpack>
446         </stage>
447 !       <stage name="Building">
448           <stageinfo>
449             <base>&build_dir;/&zlib-directory;</base>
450           </stageinfo>
451           <configure>
452             <param>--prefix=/usr</param>
453             <param>--shared</param>
454           </configure>
455           <make />
456 +       </stage>
457 +       <stage name="Installing">
458           <stageinfo>
459 +           &paco-ld-preload;
460             <base>&build_dir;/&zlib-directory;</base>
461           </stageinfo>
462 +         &paco-clear;
463           <make>
464             <param>install</param>
465           </make>
466           <remove>/lib/libz.so</remove>
467           <link>
468             <option>force</option>
469             <target>../../lib/libz.so.&zlib-version;</target>
470             <name>/usr/lib/libz.so</name>
471           </link>
472 +       </stage>
473 +       <stage name="Building">
474 +         <stageinfo>
475 +           <base>&build_dir;/&zlib-directory;</base>
476 +         </stageinfo>
477           <make>
478             <param>clean</param>
479           </make>
480           <configure>
481             <param>--prefix=/usr</param>
482           </configure>
483           <make />
484 +       </stage>
485 +       <stage name="Installing">
486 +         <stageinfo>
487 +           &paco-ld-preload;
488 +           <base>&build_dir;/&zlib-directory;</base>
489 +         </stageinfo>
490           <make>
491             <param>install</param>
492           </make>
493           <permissions mode="644">
494             <name>/usr/lib/libz.a</name>
495           </permissions>
496 +       </stage>
497 +       <stage name="Logging">
498 +         <stageinfo>
499 +           <base>&build_dir;/&zlib-directory;</base>
500 +         </stageinfo>
501 +         &paco-log-dirname;
502         </stage>
503         <stage name="Cleanup">
504           <remove>&build_dir;/&zlib-directory;</remove>
505         </stage>
506       </package>
507     </alfs>
509     ---[ end file ]---
512 Let's analyze the different changes that have been made:
514 First, the paco entities are included. This is done by the lines:
516     <!ENTITY % paco_entities SYSTEM "../config/paco.ent">
517     %paco_entities;
519 The original "Installing" stage, has been splitted into different stages:
521 # "Building" (1st pass):
522 The package is configure'd and make'd. No files are installed into the system,
523 so we leave the commands untouched.
525 # "Installing" (1st pass):
526 Some files are installed, so we have to set the LD_PRELOAD environment variable
527 at the beggining of the stage. This is done by the XML "macro" paco-ld-preload:
529     <stageinfo>
530       &paco-ld-preload;
531       <base>&build_dir;/&zlib-directory;</base>
532     </stageinfo>
534 And because it's the first "Installing" stage in this file, the libpaco-log
535 temporary file is removed to ensure that we don't log any file installed by any
536 previously installed package:
538     &paco-clear;
540 # "Building" (2nd pass):
541 The package is reconfigured again in order to install the static library.
542 The LD_PRELOAD variable is automatically unset because the environment set in
543 the <stageinfo> of the previous stage is not seen by the current one.
545 # "Installing" (2nd pass):
546 The static library is installed. We set the LD_PRELOAD variable again, but this
547 time "&paco-clear" is not used, because we do not want to overwrite the already
548 logged files, but to add new files into the log.
550 # "Logging":
551 This is a completely new stage.
552 Now that the list of files to be logged is saved in the libpaco-log temporary
553 file, a "paco -lp" command creates the log for the package. This is done with
554 the XML "macro" paco-log-dirname. It's worth noting that this macro works when
555 the name of the directory from which the package is built is the same as the
556 name of the package as we want it to be logged. This is generally true for all
557 packages, with the following exceptions:
559   - vim and tcl: because the directory created when unpacking the tarballs has a
560     "non standard" name (vim63 and tcl5.8.3).
561   - All packages that need to be built in a dedicated directory, separated from
562     the sources (gcc, glibc, e2fsprogs).
564 In these cases, the macro &paco-log-dirname; should be replaced by the following
565 lines:
567     <execute command="paco">
568       <param>-lp foo-&foo-version;</param>
569       <param>&lt; &paco-tmpfile;</param>
570     </execute>
571     &paco-clear;
573 where 'foo' is the name of the package to log.
577 3. THE END
578 ==========
579 This hint finishes here. Now it should be up to the reader to build an entire
580 LFS system with a single press on the Enter key, having control over almost
581 every byte written in the hard disk.  Ha!
583 And this is only the beggining. With litle modifications, the above instructions
584 can be applied to install all the BLFS stuff too...
588 ACKNOWLEDGEMENTS:
590 I'd like to thank specially the ALFS staff. I'm really impressed with the
591 possibilities of the ALFS system.
592 No more nights wasted in front of the computer screen, typing "./configure &&
593 make && make install" like a zombie...
595 I'd also like to thank Brad Bailey for creating an initial version of the
596 alfs-paco patch, and to encourage me to write this hint.
598 And finally, I can't forget the people who aid me in the development of paco.
602 CHANGELOG:
604 [2005-10-24]
605   * Initial hint.