1 <!-- $Id: package.xml,v 1.5 2005/03/27 21:36:13 per Exp $ -->
2
3 <title>The Package System</title>
4
5 <section id="The-Package-System-Introduction">
6 <title>Introduction</title>
7
8 <para>The package system (<ulink
9 url="http://www.fukt.bth.se/~per/pkgutils/">pkgutils</ulink>)
10 is made with simplicity in mind, where all packages are plain
11 <filename>tar.gz</filename> files (i.e. without any kind of meta
12 data). Packages follow the naming convention <filename
13 ><replaceable><name></replaceable>#<replaceable
14 ><version></replaceable>-<replaceable
15 ><release></replaceable>.pkg.tar.gz</filename>,
16 where <filename><replaceable
17 ><name></replaceable></filename> is the name of the program,
18 <filename><replaceable><version></replaceable></filename>
19 is the version number of the program, and <filename><replaceable
20 ><release></replaceable></filename> is the version number
21 of the package. The <filename>pkg.tar.gz</filename> extension is
22 used (instead of just <filename>tar.gz</filename>) to indicate
23 that this is not just any <filename>tar.gz</filename> file, but a
24 <filename>tar.gz</filename> that is meant to be installed using
25 <userinput>pkgadd</userinput>. This way it is easy to tell
26 packages apart from other <filename>tar.gz</filename>
27 files.</para>
28
29 <para><userinput>pkgadd(8)</userinput>, <userinput
30 >pkgrm(8)</userinput>, <userinput>pkginfo(8)</userinput>, and
31 <userinput>pkgmk(8)</userinput> are the package management
32 utilities. With these utilities you can install, uninstall,
33 inspect, make packages and query the package database.</para>
34
35 <para>When a package is installed using <userinput
36 >pkgadd</userinput> a new record is added to the package database
37 (stored in <filename>/var/lib/pkg/db</filename>). The package
38 system does not have any kind of dependency checking, thus it
39 will not warn you if you install a package that requires other
40 packages to be installed.</para>
41
42 <para>The following sections will in short describe how to use the
43 package utilities. Additional information about these utilities
44 can be found on their respective man page.</para>
45 </section>
46
47 <section id="Using-the-Package-System">
48 <title>Using the Package System</title>
49
50 <section id="Installing-a-Package">
51 <title>Installing a Package</title>
52
53 <para>Installing a package is done by using <userinput
54 >pkgadd</userinput>. This utility requires at least one
55 argument, the package you want to install. Example:</para>
56
57 <informalexample>
58 <screen>$ <userinput>pkgadd bash#2.05-1.pkg.tar.gz</userinput></screen>
59 </informalexample>
60
61 <para>When installing a package the package manager will ensure
62 that no previously installed files are overwritten. If conflicts
63 are found an error message will be printed and <userinput
64 >pkgadd</userinput> will abort without installing the package.
65 The error message will contain the names of the conflicting
66 files. Example:</para>
67
68 <informalexample>
69 <screen>$ <userinput>pkgadd bash#2.05-1.pkg.tar.gz</userinput>
70 bin/sh
71 usr/man/man1/sh.1.gz
72 pkgadd error: listed file(s) already installed (use -f to ignore and overwrite)</screen>
73 </informalexample>
74
75 <para>To force the installation and overwrite the conflicting
76 files you can use the option <userinput>-f</userinput> (or
77 <userinput>--force</userinput>). Example:</para>
78
79 <informalexample>
80 <screen>$ <userinput>pkgadd -f bash#2.05-1.pkg.tar.gz</userinput></screen>
81 </informalexample>
82
83 <para>The package system allows a file to be owned by
84 exactly one package. When forcing an installation the ownership
85 of the conflicting files will be transferred to the package
86 that is currently being installed. Directories can however be
87 owned by more then one package.</para>
88
89 <warning>
90 <para>It is often not a good idea to force the installation
91 unless you really know what you are doing. If a package
92 conflicts with already installed files it could be a sign
93 that the package is broken and installs unexpected files. Use
94 this option with extreme care, preferably not at all.</para>
95 </warning>
96
97 <para>As said earlier the package file itself does not contain any
98 meta data. Instead the package manager uses the package
99 filename to determine the package name and version. Thus, when
100 installing a package file named <filename
101 >bash#2.05-1.pkg.tar.gz</filename> the package manager will
102 interpret this as a package named <filename>bash</filename> at
103 version <filename>2.05-1</filename>. If <userinput
104 >pkgadd</userinput> is unable to interpret the filename (e.g.
105 <literal>#</literal> is missing or the filename does not end
106 with <filename>.pkg.tar.gz</filename>) an error message will be
107 printed and <userinput>pkgadd</userinput> will abort without
108 installing the package.</para>
109 </section>
110
111 <section id="Upgrading-a-Package">
112 <title>Upgrading a Package</title>
113
114 <para>Upgrading a package is done using <userinput
115 >pkgadd</userinput> with the <userinput>-u</userinput> option.
116 Example:</para>
117
118 <informalexample>
119 <screen>$ <userinput>pkgadd -u bash#2.05-1.pkg.tar.gz</userinput></screen>
120 </informalexample>
121
122 <para>This will replace the previously installed <filename
123 >bash</filename> package with the new one. If you have not
124 previously installed <filename>bash</filename>, <userinput
125 >pkgadd</userinput> will print an error message.
126 The package system does not care about
127 the version number of the package in that you can
128 <quote>upgrade</quote> version <filename>2.05-1</filename>
129 with version <filename>2.04-1</filename> (or even with version
130 <filename>2.05-1</filename> itself). The installed package will
131 be replaced with the specified package.</para>
132
133 <para>Upgrading a package is equivalent to executing <userinput
134 >pkgrm</userinput> followed by <userinput>pkgadd</userinput>
135 with one (big) exception. When upgrading a package (with
136 <userinput>pkgadd -u</userinput>) you have the option to
137 prevent some of the already installed files
138 from getting replaced. This is typically useful when you want
139 to preserve configuration and log files.</para>
140
141 <para>When executing <userinput>pkgadd</userinput> the file
142 <filename>/etc/pkgadd.conf</filename> will be read. This file
143 can contain rules describing how <userinput>pkgadd</userinput>
144 should behave when doing upgrades. A rule is built out of three
145 fragments; <emphasis>event</emphasis>, <emphasis
146 >pattern</emphasis> and <emphasis>action</emphasis>. The event
147 describes in what kind of situation this rule applies.
148 Currently only one type of event is supported, that is
149 <literal>UPGRADE</literal>. The <emphasis>pattern</emphasis> is
150 a filename pattern expressed as a regular expression and the
151 action applicable to the <literal>UPGRADE</literal> event is
152 <literal>YES</literal> or <literal>NO</literal>. More than one
153 rule of the same event type is allowed, in which case the first
154 rule will have the lowest priority and the last rule will have
155 the highest priority. Example:</para>
156
157 <informalexample>
158 <programlisting>#
159 # /etc/pkgadd.conf: pkgadd(8) configuration
160 #
161
162 UPGRADE ^etc/.*$ NO
163 UPGRADE ^var/log/.*$ NO
164 UPGRADE ^etc/X11/.*$ YES
165 UPGRADE ^etc/X11/XF86Config$ NO
166
167 # End of file</programlisting>
168 </informalexample>
169
170 <para>The above example will cause <userinput>pkgadd</userinput>
171 to never upgrade anything in <filename>/etc/</filename> or
172 <filename>/var/log/</filename> (subdirectories included), except
173 files in <filename>/etc/X11/</filename> (subdirectories
174 included), unless it is the file <filename
175 >/etc/X11/XF86Config</filename>. The default rule is to upgrade
176 everything, rules in this file are exceptions to that
177 rule.</para>
178
179 <note>
180 <para>A <emphasis>pattern</emphasis> should never contain an
181 initial <quote>/</quote> since you are referring to the files
182 in the package, not the files on the disk.</para>
183 </note>
184
185 <para>If <userinput>pkgadd</userinput> finds that a specific file
186 should not be upgraded it will install it under
187 <filename>/var/lib/pkg/rejected/</filename>. Files in this
188 directory are never added to the package database. The user is then
189 free to examine, use and/or remove that file manually.
190 Another option is to use <userinput>rejmerge</userinput>.
191 For each rejected file found in <filename>/var/lib/pkg/rejected/</filename>,
192 <userinput>rejmerge</userinput> will display the difference between the
193 installed version and the rejected version. The user can then choose to keep
194 the installed version, upgrade to the rejected version or perform a merge
195 of the two. Example (using the above <filename>/etc/pkgadd.conf</filename>):</para>
196
197 <informalexample>
198 <screen>$ <userinput>pkgadd -u bash#2.05-1.pkg.tar.gz</userinput>
199 pkgadd: rejecting etc/profile, keeping existing version
200 $ <userinput>ls /var/lib/pkg/rejected/</userinput>
201 etc/
202 $ <userinput>ls /var/lib/pkg/rejected/etc/</userinput>
203 profile</screen>
204 </informalexample>
205 </section>
206
207 <section id="Removing-a-Package">
208 <title>Removing a Package</title>
209
210 <para>Removing a package is done by using <userinput
211 >pkgrm</userinput>. This utility requires one argument, the
212 name of the package you want to remove. Example:</para>
213
214 <informalexample>
215 <screen>$ <userinput>pkgrm bash</userinput></screen>
216 </informalexample>
217
218 <warning>
219 <para>This will remove all files owned by the package, no
220 questions asked. Think twice before doing it and make sure
221 that you did not misspell the package name since that could
222 remove something completely different (e.g. think about what
223 could happen if you misspelled <filename>glib</filename> as
224 <filename>glibc</filename>).</para>
225 </warning>
226 </section>
227
228 <section id="Querying-the-Package-Database">
229 <title>Querying the Package Database</title>
230
231 <para>Querying the package database is done using
232 <userinput>pkginfo</userinput>. This utility has a few options
233 to answer different queries.</para>
234
235 <informaltable>
236 <tgroup cols="2">
237 <thead>
238 <row>
239 <entry>Option</entry>
240
241 <entry>Description</entry>
242 </row>
243 </thead>
244
245 <tbody>
246 <row>
247 <entry><userinput>-i</userinput>, <userinput
248 >--installed</userinput></entry>
249
250 <entry>List installed packages and their version.</entry>
251 </row>
252
253 <row>
254 <entry><userinput>-l</userinput>, <userinput
255 >--list <replaceable
256 >package|file</replaceable></userinput></entry>
257
258 <entry>List files owned by the specified <userinput
259 ><replaceable>package</replaceable></userinput> or
260 contained in <userinput><replaceable
261 >file</replaceable></userinput></entry>
262 </row>
263
264 <row>
265 <entry><userinput>-o</userinput>, <userinput
266 >--owner <replaceable
267 >pattern</replaceable></userinput></entry>
268
269 <entry>List owner(s) of file(s) matching <userinput><replaceable
270 >pattern</replaceable></userinput>.</entry>
271 </row>
272 </tbody>
273 </tgroup>
274 </informaltable>
275
276 <para>Examples:</para>
277
278 <informalexample>
279 <screen>$ <userinput>pkginfo -i</userinput>
280 audiofile 0.2.3-1
281 autoconf 2.52-1
282 automake 1.5-1
283 <...>
284 xmms 1.2.7-1
285 zip 2.3-1
286 zlib 1.1.4-1</screen>
287
288 <screen>$ <userinput>pkginfo -l bash</userinput>
289 bin/
290 bin/bash
291 bin/sh
292 etc/
293 etc/profile
294 usr/
295 usr/man/
296 usr/man/man1/
297 usr/man/man1/bash.1.gz
298 usr/man/man1/sh.1.gz</screen>
299
300 <screen>$ <userinput>pkginfo -l grep#2.5-1.pkg.tar.gz</userinput>
301 usr/
302 usr/bin/
303 usr/bin/egrep
304 usr/bin/fgrep
305 usr/bin/grep
306 usr/man/
307 usr/man/man1/
308 usr/man/man1/egrep.1.gz
309 usr/man/man1/fgrep.1.gz
310 usr/man/man1/grep.1.gz</screen>
311
312 <screen>$ <userinput>pkginfo -o bin/ls</userinput>
313 e2fsprogs usr/bin/lsattr
314 fileutils bin/ls
315 modutils sbin/lsmod</screen>
316 </informalexample>
317 </section>
318 </section>
319
320 <section id="Creating-Packages">
321 <title>Creating Packages</title>
322
323 <para>Creating a package is done using <userinput
324 >pkgmk</userinput>. This utility uses a file called <filename
325 >Pkgfile</filename>, which contains information about the package
326 (such as name, version, etc) and the commands that should be
327 executed in order to compile the package in question. To be more
328 specific, the <filename>Pkgfile</filename> file is actually a
329 <userinput>bash(1)</userinput> script, which defines a number of
330 variables (<literal>name</literal>, <literal>version</literal>,
331 <literal>release</literal> and <literal>source</literal>) and a
332 function (<literal>build</literal>). Below is an example of what a
333 <filename>Pkgfile</filename> file might look like. The example
334 shows how to package the <userinput>grep(1)</userinput> utility.
335 Some comments are inserted for explanation.</para>
336
337 <informalexample>
338 <programlisting># Specify the name of the package.
339 name=grep
340
341 # Specify the version of the package.
342 version=2.4.2
343
344 # Specify the package release.
345 release=1
346
347 # The source(s) used to build this package.
348 source=(ftp://ftp.ibiblio.org/pub/gnu/$name/$name-$version.tar.gz)
349
350 # The build() function below will be called by pkgmk when
351 # the listed source files have been unpacked.
352 build() {
353 # The first thing we do is to cd into the source directory.
354 cd $name-$version
355
356 # Run the configure script with desired arguments.
357 # In this case we want to put grep under /usr/bin and
358 # disable national language support.
359 ./configure --prefix=/usr --disable-nls
360
361 # Compile.
362 make
363
364 # Install the files, BUT do not install it under /usr, instead
365 # we redirect all the files to $PKG/usr by setting the DESTDIR
366 # variable. The $PKG variable points to a temporary directory
367 # which will later be made into a tar.gz-file. Note that the
368 # DESTDIR variable is not used by all Makefiles, some use prefix
369 # and others use ROOT, etc. You have to inspect the Makefile in
370 # question to find out. Some Makefiles do not support redirection
371 # at all. In those cases you will have to create a patch for it.
372 make DESTDIR=$PKG install
373
374 # Remove unwanted files, in this case the info-pages.
375 rm -rf $PKG/usr/info
376 }</programlisting>
377 </informalexample>
378
379 <para>In reality you do not include all those comments, thus the real
380 <filename>Pkgfile</filename> for <userinput>grep(1)</userinput> looks
381 like this:</para>
382
383 <informalexample>
384 <programlisting># $Id: package.xml,v 1.5 2005/03/27 21:36:13 per Exp $
385 # Maintainer: Per Lidén <per@fukt.bth.se>
386
387 name=grep
388 version=2.4.2
389 release=1
390 source=(ftp://ftp.ibiblio.org/pub/gnu/$name/$name-$version.tar.gz)
391
392 build() {
393 cd $name-$version
394 ./configure --prefix=/usr --disable-nls
395 make
396 make DESTDIR=$PKG install
397 rm -rf $PKG/usr/info
398 }</programlisting>
399 </informalexample>
400
401 <note>
402 <para>The <literal>build()</literal> function in the example
403 above is just an example of how <userinput>grep</userinput> is
404 built. The contents of the function can differ significantly
405 if the program is build in some other way, e.g. does not use
406 <userinput>autoconf</userinput>.</para>
407 </note>
408
409 <para>When the <literal>build()</literal> function has been
410 executed, the <filename>$PKG</filename> directory will be made
411 into a package named <filename><replaceable
412 ><name></replaceable>#<replaceable
413 ><version></replaceable>-<replaceable
414 ><release></replaceable>.pkg.tar.gz</filename>. Before the
415 package creation is completed, <userinput>pkgmk</userinput>
416 will check the content of the package against the <filename
417 >.footprint</filename> file. If this file does not exist, it will
418 be created and the test will be skipped. The <filename
419 >.footprint</filename> file will contain a list of all files
420 that should be in the package if the build was successful or a
421 list of all the files that were installed in <filename
422 >$PKG</filename> (if the <filename>.footprint</filename> did not
423 already exist).
424 If there is a mismatch the test will fail and an error message
425 will be printed. You should not write the <filename
426 >.footprint</filename> file by hand. Instead, when a package has
427 been upgraded and you need to update the contents of the <filename
428 >.footprint</filename> file you simply do <userinput>pkgmk
429 -uf</userinput>. This test ensures that a rebuild of the package
430 turned out as expected.</para>
431
432 <para>If the package built without errors it's time to install it
433 by using <userinput>pkgadd</userinput> and try it out. I highly
434 recommend looking at the <filename>Pkgfile</filename> in another
435 package(s), since looking at examples is a great way to
436 learn.</para>
437 </section>
438
439 <section id="Package-Guidelines">
440 <title>Package Guidelines</title>
441
442 <section id="Package-Guidelines-General">
443 <title>General</title>
444
445 <itemizedlist>
446 <listitem>
447 <para>The name of a package should always be lowercase (e.g.
448 <literal>name=eterm</literal> and not <literal
449 >name=Eterm</literal>). In case the package is added to the
450 CRUX ports system the exact same name should be use for
451 the name of the directory in the ports structure, i.e.
452 <filename>/usr/ports/???/eterm</filename>.</para>
453 </listitem>
454
455 <listitem>
456 <para>Do not combine several separately distributed
457 programs/libraries into one package. Make several
458 packages instead.</para>
459 </listitem>
460 </itemizedlist>
461 </section>
462
463 <section id="Package-Guidelines-Directories">
464 <title>Directories</title>
465
466 <itemizedlist>
467 <listitem>
468 <para>In general packages should install files in these
469 directories. Exceptions are of course allowed if there is
470 a good reason. But try to follow the following directory
471 structure as close as possible.</para>
472
473 <informaltable>
474 <tgroup cols="2">
475 <thead>
476 <row>
477 <entry>Directory</entry>
478
479 <entry>Description</entry>
480 </row>
481 </thead>
482
483 <tbody>
484 <row>
485 <entry><filename>/usr/bin/</filename></entry>
486
487 <entry>User command/application binaries</entry>
488 </row>
489
490 <row>
491 <entry><filename>/usr/sbin/</filename></entry>
492
493 <entry>System binaries (e.g. daemons)</entry>
494 </row>
495
496 <row>
497 <entry><filename>/usr/lib/</filename></entry>
498
499 <entry>Libraries</entry>
500 </row>
501
502 <row>
503 <entry><filename>/usr/include/</filename></entry>
504
505 <entry>Header files</entry>
506 </row>
507
508 <row>
509 <entry><filename>/usr/lib/<replaceable
510 ><prog></replaceable>/</filename></entry>
511
512 <entry>Plug-ins, addons, etc</entry>
513 </row>
514
515 <row>
516 <entry><filename>/usr/man/</filename></entry>
517
518 <entry>Man pages</entry>
519 </row>
520
521 <row>
522 <entry><filename>/usr/share/<replaceable
523 ><prog></replaceable>/</filename></entry>
524
525 <entry>Data files</entry>
526 </row>
527
528 <row>
529 <entry><filename>/usr/etc/<replaceable
530 ><prog></replaceable>/</filename></entry>
531
532 <entry>Configuration files</entry>
533 </row>
534
535 <row>
536 <entry><filename>/etc/</filename></entry>
537
538 <entry>Configuration files for system software
539 (daemons, etc)</entry>
540 </row>
541 </tbody>
542 </tgroup>
543 </informaltable>
544 </listitem>
545
546 <listitem>
547 <para><filename>/usr/X11R6</filename> and
548 <filename>/usr/<replaceable>???</replaceable>/X11</filename>
549 are reserved for X11 only. X related programs that are
550 not shipped with X11 should be placed under
551 <filename>/usr</filename> and NOT under
552 <filename>/usr/X11R6</filename> or
553 <filename>/usr/<replaceable
554 >???</replaceable>/X11</filename>.</para>
555 </listitem>
556
557 <listitem>
558 <para><filename>/opt</filename> directory is reserved for
559 manually compiled/installed applications. Packages should
560 never place anything there.</para>
561 </listitem>
562
563 <listitem>
564 <para><filename>/usr/libexec/</filename> is <emphasis
565 >not</emphasis> used in CRUX, thus packages should never
566 install anything there. Use <filename
567 >/usr/lib/<replaceable
568 ><prog></replaceable>/</filename> instead.</para>
569 </listitem>
570 </itemizedlist>
571 </section>
572
573 <section id="Remove-Junk-Files">
574 <title>Remove Junk Files</title>
575
576 <itemizedlist>
577 <listitem>
578 <para>Packages should not contain <quote>junk files</quote>.
579 This includes info pages and other online documentation, man
580 pages excluded (e.g. <filename>usr/doc/*</filename>,
581 <filename>README</filename>, <filename>*.info</filename>,
582 <filename>*.html</filename>, etc).</para>
583 </listitem>
584
585 <listitem>
586 <para>Files related to NLS (national language support), always
587 use <userinput>--disable-nls</userinput> when available.</para>
588 </listitem>
589
590 <listitem>
591 <para>Useless or obsolete binaries (e.g.
592 <filename>/usr/games/banner</filename> and
593 <filename>/sbin/mkfs.minix</filename>).</para>
594 </listitem>
595 </itemizedlist>
596 </section>
597
598 <section id="Pkgfile">
599 <title>Pkgfile</title>
600
601 <itemizedlist>
602 <listitem>
603 <para>Do not add new variables to the <filename>Pkgfile</filename>.
604 Only in very few cases does this actually improve the
605 readability or the quality of the package. Further, the only
606 variables that are guranteed to work with future versions of
607 <userinput>pkgmk</userinput> are <literal>name</literal>,
608 <literal>version</literal>, <literal>release</literal>,
609 and <literal>source</literal>. Other names could be in
610 conflict with internal variables in
611 <userinput>pkgmk</userinput>.</para>
612 </listitem>
613
614 <listitem>
615 <para>Use the <literal>$name</literal> and
616 <literal>$version</literal> variables to make the package
617 easier to update/maintain. For example,
618 <literal>source=(http://xyz.org/$name-$version.tar.gz)</literal>
619 is better than
620 <literal>source=(http://xyz.org/myprog-1.0.3.tar.gz)</literal>
621 since the URL will automatically updated when you modify the
622 <literal>$version</literal> variable.</para>
623 </listitem>
624
625 <listitem>
626 <para>Remember that source is an array, i.e. always do
627 <literal>source=(...)</literal> and not
628 <literal>source=...</literal></para>
629 </listitem>
630 </itemizedlist>
631 </section>
632 </section>
|