aboutsummaryrefslogtreecommitdiff
path: root/en_US.ISO8859-1/books/porters-handbook/book.sgml
blob: aa5d962c4a432a5f712d947727f453a7d1c6c208 (plain) (blame)
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
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
    <chapter id="ports">
      <title>Installing Applications: The Ports collection</title>
      
      <para><emphasis>Contributed by &a.jraynard;.</emphasis></para>
      
      <para>The FreeBSD Ports collection allows you to compile and install a
	very wide range of applications with a minimum of effort.</para>
      
      <para>For all the hype about open standards, getting a program to work
	on different versions of Unix in the real world can be a tedious and
	tricky business, as anyone who has tried it will know. You may be
	lucky enough to find that the program you want will compile cleanly on
	your system, install itself in all the right places and run flawlessly
	&ldquo;out of the box&rdquo;, but this is unfortunately rather rare. With most
	programs, you will find yourself doing a fair bit of head-scratching,
	and there are quite a few programs that will result in premature
	greying, or even chronic alopecia...</para>
      
      <para>Some software distributions have attacked this problem by
	providing configuration scripts. Some of these are very clever, but
	they have an unfortunate tendency to triumphantly announce that your
	system is something you have never heard of and then ask you lots of
	questions that sound like a final exam in system-level Unix
	programming (<literal>Does your system's gethitlist function return a const
	pointer to a fromboz or a pointer to a const fromboz? Do you have
	Foonix style unacceptable exception handling? And if not, why
	not?</literal>).</para>
      
      <para>Fortunately, with the Ports collection, all the hard work
	involved has already been done, and you can just type <command>make install</command>
	and get a working program.</para>
      
      
      <sect1>
	<title>Why Have a Ports Collection?</title>
	
	<para>The base FreeBSD system comes with a very wide range of tools
	  and system utilities, but a lot of popular programs are not in the
	  base system, for good reasons:-</para>
	
	
	  <orderedlist>
	    
	    <listitem>
	      <para>Programs that some people cannot live without and other
		people cannot stand, such as a certain Lisp-based editor.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Programs which are too specialised to put in the base
		system (CAD, databases).</para>
	    </listitem>
	    
	    <listitem>
	      <para>Programs which fall into the &ldquo;I must have a look at that
		when I get a spare minute&rdquo; category, rather than
		system-critical ones (some languages, perhaps).</para>
	    </listitem>
	    
	    <listitem>
	      <para>Programs that are far too much fun to be supplied with a
		serious operating system like FreeBSD ;-)</para>
	    </listitem>
	    
	    <listitem>
	      <para>However many programs you put in the base system, people
		will always want more, and a line has to be drawn somewhere
		(otherwise FreeBSD distributions would become absolutely
		enormous).</para>
	    </listitem>
	    
	  </orderedlist>
	
	
	<para>Obviously it would be unreasonable to expect everyone to port
	  their favourite programs by hand (not to mention a tremendous amount
	  of duplicated work), so the FreeBSD Project came up with an
	  ingenious way of using standard tools that would automate the
	  process.</para>
	
	<para>Incidentally, this is an excellent illustration of how &ldquo;the
	  Unix way&rdquo; works in practice by combining a set of simple but very
	  flexible tools into something very powerful.</para>
	
      </sect1>
      
      <sect1>
	<title>How Does the Ports Collection Work?</title>
	
	<para>Programs are typically distributed on the Internet as a 
	  <xref linkend="ports-tarball" remap="tarball"> consisting of a
	  Makefile and the source code for the program and usually some
	  instructions (which are unfortunately not always as instructive as
	  they could be), with perhaps a configuration script.</para>
	
	<para>The standard scenario is that you FTP down the tarball, extract
	  it  somewhere, glance through the instructions, make any changes
	  that seem  necessary, run the configure script to set things up and
	  use the standard  <command>make</command> program to compile and install the program
	  from the source.</para>
	
	<para>FreeBSD ports still use the tarball mechanism, but use a 
	  <xref linkend="ports-skeleton" remap="skeleton"> to hold the
	  &quot;knowledge&quot; of how to get the program working on FreeBSD,
	  rather than expecting the user to be able to work it out. They also
	  supply their own customised
	  <xref linkend="ports-makefile" remap="Makefile">, so that almost
	  every port can be built in the same way.</para>
	
	<para>If you look at a port skeleton (either on <ulink
	    URL="file://localhost/usr/ports/devel/ElectricFence">your FreeBSD
	    system</ulink> or <ulink
	    URL="ftp://ftp.freebsd.org/pub/FreeBSD/ports/devel/ElectricFence">the FTP site</ulink>) and expect to find all sorts of pointy-headed rocket science lurking there, you may be disappointed by the one or two rather unexciting-looking files and directories you find there. (We will discuss in a minute how to go about <xref
	    linkend="ports-getting" remap="Getting a port">).</para>
	
	<para>&ldquo;How on earth can this do anything?&rdquo; I hear you cry. &ldquo;There
	  is no source code there!&rdquo;</para>
	
	<para>Fear not, gentle reader, all will become clear (hopefully).
	  Let's see what happens if we try and install a port. I have chosen
	  <application>ElectricFence</application>, a useful tool for developers, as the skeleton is
	  more straightforward than most.</para>
	
	<note>
	  <para>If you are trying this at home, you
	  will need to be root.</para>
	</note>
	
	<informalexample>
	  <screen>&prompt.root; <userinput>cd /usr/ports/devel/ElectricFence</userinput>
&prompt.root; <userinput>make install</userinput>
&gt;&gt; Checksum OK for ElectricFence-2.0.5.tar.gz.
===&gt;  Extracting for ElectricFence-2.0.5
===&gt;  Patching for ElectricFence-2.0.5
===&gt;  Applying FreeBSD patches for ElectricFence-2.0.5
===&gt;  Configuring for ElectricFence-2.0.5
===&gt;  Building for ElectricFence-2.0.5
[lots of compiler output...]
===&gt;  Installing for ElectricFence-2.0.5
===&gt;  Warning: your umask is "0002". If this is not desired, set it to
      an appropriate value and install this port again by ``make reinstall''.
install -c -o bin -g bin -m 444 /usr/ports/devel/ElectricFence/work/ElectricFence-2.0.5/libefence.a /usr/local/lib
install -c -o bin -g bin -m 444 /usr/ports/devel/ElectricFence/work/ElectricFence-2.0.5/libefence.3 /usr/local/man/man3
===&gt;  Compressing manual pages for ElectricFence-2.0.5
===&gt;  Registering installation for ElectricFence-2.0.5</screen>
	</informalexample>
	
	<para>To avoid confusing the issue, I have completely removed the
	  build output.</para>
	
	<para>If you tried this yourself, you may well have got something like
	  this at the start:-</para>
	
	
	  <informalexample id="ports-fetch">
	    <screen>&prompt.root; <userinput>make install</userinput>
&gt;&gt; ElectricFence-2.0.5.tar.gz doesn't seem to exist on this system.
&gt;&gt; Attempting to fetch from ftp://ftp.doc.ic.ac.uk/Mirrors/sunsite.unc.edu/pub/Linux/devel/lang/c/.</screen>
	  </informalexample>
	
	
	<para>The <command>make</command> program has noticed that you did not have a local
	  copy of the source code and tried to FTP it down so it could get the
	  job done. I already had the source handy in my example, so it did
	  not need to fetch it.</para>
	
	<para>Let's go through this and see what the <command>make</command> program was
	  doing.</para>
	
	
	  <procedure>
	    
	    <step>
	      <para>Locate the source code <xref linkend="ports-tarball"
		  remap="tarball."> If it is not available locally, try to
		grab it from an FTP site.</para>
	    </step>
	    
	    <step>
	      <para>Run a <xref linkend="ports-checksum" remap="checksum">
		test on the tarball to make sure it has not been tampered
		with, accidentally truncated, downloaded in ASCII mode, struck
		by neutrinos while in transit, etc.</para>
	    </step>
	    
	    <step>
	      <para>Extract the tarball into a temporary work directory.</para>
	    </step>
	    
	    <step>
	      <para>Apply any <xref linkend="ports-patch" remap="patches">
		needed to get the source to compile and run under FreeBSD.</para>
	    </step>
	    
	    <step>
	      <para>Run any configuration script required by the build
		process and correctly answer any questions it asks.</para>
	    </step>
	    
	    <step>
	      <para>(Finally!) Compile the code.</para>
	    </step>
	    
	    <step>
	      <para>Install the program executable and other supporting
		files, man pages, etc. under the
		<filename>/usr/local</filename> hierarchy, where they will not
		get mixed up with system programs. This also makes sure that
		all the ports you install will go in the same place, instead
		of being flung all over your system.</para>
	    </step>
	    
	    <step>
	      <para>Register the installation in a database. This means that,
		if you do not like the program, you can cleanly <xref
		  linkend="ports-remove" remap="remove"> all traces of it from
		your system.</para>
	    </step>
	    
	  </procedure>
	
	
	<para>Scroll up to the <command>make</command> output and see if you can match these
	  steps to it. And if you were not impressed before, you should be by
	  now!</para>
	
      </sect1>
      
      <sect1 id="ports-getting">
	<title>Getting a FreeBSD Port</title>
	
	<para>There are two ways of getting hold of the FreeBSD port for a
	  program. One requires a <xref linkend="ports-cd" remap="FreeBSD
	    CDROM">, the other involves using an <xref linkend="ports-inet"
	    remap="Internet Connection."></para>
	
	
	<sect2 id="ports-cd">
	  <title>Compiling ports from CDROM</title>
	  
	  <para>If you answered yes to the question &ldquo;Do you want to link the
	    ports  collection to your CDROM&rdquo; during the FreeBSD installation,
	    the initial setting up will already have been done for you.</para>
	  
	  <para>If not, make sure the <emphasis>FreeBSD</emphasis> CDROM is in
	    the drive and mounted on, say, <filename>/cdrom</filename>. Then
	    do</para>
	  
	  <informalexample>
	    <screen>&prompt.root; <userinput>mkdir /usr/ports</userinput>
&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>ln -s /cdrom/ports/distfiles distfiles</userinput></screen>
	  </informalexample>
	  
	  <para>to enable the ports make mechanism to find the tarballs (it
	    expects to find them in <filename>/usr/ports/distfiles</filename>,
	    which is why we sym-linked the CDROM's tarball directory to that
	    directory).</para>
	  
	  <para>Now, suppose you want to install the gnats program from the
	    databases directory. Here is how to do it:-</para>
	  
	  <informalexample>
	    <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>mkdir databases</userinput>
&prompt.root; <userinput>cp -R /cdrom/ports/databases/gnats databases</userinput>
&prompt.root; <userinput>cd databases/gnats</userinput>
&prompt.root; <userinput>make install</userinput></screen>
	  </informalexample>
	  
	  <para>Or if you are a serious database user and you want to compare
	    all the ones available in the Ports collection, do</para>
	  
	  <informalexample>
	    <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>cp -R /cdrom/ports/databases .</userinput>
&prompt.root; <userinput>cd databases</userinput>
&prompt.root; <userinput>make install</userinput></screen>
	  </informalexample>
	  
	  <para>(yes, that really is a dot on its own after the <command>cp</command> command and
	    not a mistake. It is Unix-ese for &ldquo;the current
	    directory&rdquo;) and the ports make mechanism will automatically compile and
	    install all the ports in the databases directory for you!</para>
	  
	  <para>If you do not like this method, here is a completely different
	    way of doing it:-</para>
	  
	  <para>Create a &ldquo;link tree&rdquo; to it using the
	    <citerefentry><refentrytitle>lndir</refentrytitle><manvolnum>1</manvolnum></citerefentry> command that comes with the
	    <emphasis>XFree86</emphasis> distribution. Find a location with
	    some free space, create a directory there and then cd to it. Then
	    invoke the <citerefentry><refentrytitle>lndir</refentrytitle><manvolnum>1</manvolnum></citerefentry> command with the full
	    pathname of the <filename>ports</filename> directory on the CDROM as the first
	    argument and . (the current directory) as the second. This might
	    be, for example, something like:</para>

	    <informalexample>
	      <screen>&prompt.root; <userinput>lndir /cdrom/ports .</userinput></screen>
	    </informalexample>
	  
	  <para>Then you can build ports directly off the CDROM by building
	    them in the link tree you have created.</para>
	  
	  <para>Note that there are some ports for which we cannot provide the
	    original source in the CDROM due to licensing limitations. In
	    that case, you will need to look at the section on <xref
	      linkend="ports-inet"
	      remap="Compiling ports using an Internet connection."></para>
	  
	</sect2>
	
	<sect2 id="ports-inet">
	  <title>Compiling ports from the Internet</title>
	  
	  <para>If you do not have a CDROM, or you want to make sure you get
	    the very latest version of the port you want, you will need to
	    download the
	    <xref linkend="ports-skeleton" remap="skeleton"> for the port. Now
	    this  might sound like rather a fiddly job full of pitfalls, but
	    it is actually very easy.</para>
	  
	  <para>The key to it is that the FreeBSD FTP server can create
	    on-the-fly
	    <xref linkend="ports-tarball" remap="tarballs"> for you. Here is
	    how it works, with the gnats program in the databases directory as
	    an example (the bits in square brackets are comments. Do not type
	    them in if you are trying this yourself!):-</para>
	  
	  <informalexample>
	    <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>mkdir databases</userinput>
&prompt.root; <userinput>cd databases</userinput>
&prompt.root; <userinput>ftp ftp.freebsd.org</userinput>
[log in as `ftp' and give your email address when asked for a
password. Remember to use binary (also known as image) mode!]
<prompt>&gt;</prompt> <userinput>cd /pub/FreeBSD/ports/databases</userinput>
<prompt>&gt;</prompt> <userinput>get gnats.tar</userinput>
[tars up the gnats skeleton for us]
<prompt>&gt;</prompt> <userinput>quit</userinput>
&prompt.root; <userinput>tar xf gnats.tar</userinput>
[extract the gnats skeleton]
&prompt.root; <userinput>cd gnats</userinput>
&prompt.root; <userinput>make install</userinput>
[build and install gnats]</screen>
	  </informalexample>
	  
	  <para>What happened here? We connected to the FTP server in the
	    usual way and went to its <filename>databases</filename> sub-directory. When we gave it
	    the command <command>get gnats.tar</command>, the FTP server <xref
	      linkend="ports-tarball"
	      remap="tarred"> up the gnats directory for us.</para>
	  
	  <para>We then extracted the gnats skeleton and went into the gnats
	    directory to build the port. As we explained <xref
	      linkend="ports-fetch"
	      remap="earlier">, the make process noticed we did not have a
	    copy of the source locally, so it fetched one before extracting,
	    patching and building it.</para>
	  
	  <para>Let's try something more ambitious now. Instead of getting a
	    single port skeleton, let's get a whole sub-directory, for example
	    all the database skeletons in the ports collection. It looks
	    almost the same:-</para>
	  
	  <informalexample>
	    <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>ftp ftp.freebsd.org</userinput>
[log in as `ftp' and give your email address when asked for a
password. Remember to use binary (also known as image) mode!]
<prompt>&gt;</prompt> <userinput>cd /pub/FreeBSD/ports</userinput>
<prompt>&gt;</prompt> <userinput>get databases.tar</userinput>
[tars up the databases directory for us]
<prompt>&gt;</prompt> <userinput>quit</userinput>
&prompt.root; <userinput>tar xf databases.tar</userinput>
[extract all the database skeletons]
&prompt.root; <userinput>cd databases</userinput>
&prompt.root; <userinput>make install</userinput>
[build and install all the database ports]</screen>
	  </informalexample>
	  
	  <para>With half a dozen straightforward commands, we have now got a
	    set of database programs on our FreeBSD machine! All we did that
	    was different from getting a single port skeleton and building it
	    was that we got a whole directory at once, and compiled everything
	    in it at once. Pretty impressive, no?</para>
	  
	  <para>If you expect to be installing many ports, it is probably
	    worth downloading all the ports directories.</para>
	  
	</sect2>
      </sect1>
      
      <sect1 id="ports-skeleton">
	<title>Skeletons</title>
	
	<para>A team of compulsive hackers who have forgotten to eat in a
	  frantic attempt to make a deadline? Something unpleasant lurking in
	  the FreeBSD  attic? No, a skeleton here is a minimal framework that
	  supplies everything needed to make the ports magic work.</para>
	
	
	<sect2 id="ports-makefile">
	  <title><filename>Makefile</filename></title>
	  
	  <para>The most important component of a skeleton is the Makefile.
	    This contains various statements that specify how the port should
	    be compiled and installed. Here is the Makefile for
	    ElectricFence:-</para>
	  
	  <programlisting>
# New ports collection makefile for:  Electric Fence
# Version required:	2.0.5
# Date created: 	13 November 1997
# Whom:			jraynard
#
# &#36;Id&#36;
#

DISTNAME=       ElectricFence-2.0.5
CATEGORIES=     devel
MASTER_SITES=   ${MASTER_SITE_SUNSITE}
MASTER_SITE_SUBDIR=	devel/lang/c

MAINTAINER=	jraynard@freebsd.org

MAN3=           libefence.3

do-install:
        ${INSTALL_DATA} ${WRKSRC}/libefence.a ${PREFIX}/lib
        ${INSTALL_MAN} ${WRKSRC}/libefence.3 ${PREFIX}/man/man3

.include &lt;bsd.port.mk&gt;</programlisting>
	  
	  <para>The lines beginning with a &quot;#&quot; sign are comments for
	    the benefit of human readers (as in most Unix script
	    files).</para>
	  
	  <para><literal>DISTNAME</literal> specifies the name of the <xref
	      linkend="ports-tarball" remap="tarball">, but without the
	    extension.</para>
	  
	  <para><literal>CATEGORIES</literal> states what kind of program this is. In
	    this case, a utility for developers.</para>
	  
	  <para><literal>MASTER_SITES</literal> is the URL(s) of the master FTP site,
	    which is used to retrieve the <xref linkend="ports-tarball"
	      remap="tarball"> if it is not available on the local system.
	    This is a site which is regarded as reputable, and is normally the
	    one from which the program is officially  distributed (in so far
	    as any software is &quot;officially&quot; distributed on the
	    Internet).</para>
	  
	  <para><literal>MAINTAINER</literal> is the email address of the person who is
	    responsible for updating the skeleton if, for example a new
	    version of the program comes out.</para>
	  
	  <para>Skipping over the next few lines for a minute, the line
	    <literal>.include &lt;bsd.port.mk&gt;</literal> says
	    that the other statements and commands  needed for this port are
	    in a standard file called <filename>bsd.port.mk</filename>. As
	    these are the same for all ports, there is no point in duplicating
	    them all over the place, so they are kept in a single standard
	    file.</para>
	  
	  <para>This is probably not the place to go into a detailed
	    examination of how Makefiles work; suffice it to say that the line
	    starting with <literal>MAN3</literal> ensures that the ElectricFence man page is
	    compressed after installation, to help conserve your precious disk
	    space. The original port did not provide an <maketarget>install</maketarget> target,
	    so the three lines from <maketarget>do-install</maketarget> ensure that the files
	    produced by this port are placed in the correct
	    destination.</para>
	  
	</sect2>
	
	<sect2>
	  <title>The <filename>files</filename> directory</title>
	  
	  <para>The file containing the <xref linkend="ports-checksum"
	      remap="checksum"> for the port is called
	    <filename>md5</filename>, after the MD5 algorithm used for ports
	    checksums. It lives in a directory with the slightly confusing
	    name of <filename>files</filename>.</para>
	  
	  <para>This directory can also contain other miscellaneous files that
	    are required by the port and do not belong anywhere else.</para>
	  
	</sect2>
	
	<sect2>
	  <title>The <filename>patches</filename> directory</title>
	  
	  <para>This directory contains the <xref linkend="ports-patch"
	      remap="patches"> needed to make everything work properly under
	    FreeBSD.</para>
	  
	</sect2>
	
	<sect2>
	  <title>The <filename>pkg</filename> directory</title>
	  
	  <para>This program contains three quite useful files:-</para>
	  
	  
	    <itemizedlist>
	      
	      <listitem>
		<para><filename>COMMENT</filename> &mdash; a one-line description of
		  the program.</para>
	      </listitem>
	      
	      <listitem>
		<para><filename>DESCR</filename> &mdash; a more detailed description.</para>
	      </listitem>
	      
	      <listitem>
		<para><filename>PLIST</filename> &mdash; a list of all the files
		  that will be created when the program is installed.</para>
	      </listitem>
	      
	    </itemizedlist>
	  
	  
	</sect2>
      </sect1>
      
      <sect1 id="ports-troubleshooting">
	<title>What to do when a port does not work.</title>
	
	<para>Oh. You can do one of four (4) things :</para>
	
	
	  <orderedlist>
	    
	    <listitem>
	      <para>Fix it yourself. Technical details on how ports work can
		be found in
		<xref linkend="porting" remap="Porting applications."></para>
	    </listitem>
	    
	    <listitem>
	      <para>Gripe. This is done by e-mail <emphasis>only</emphasis>! Send such e-mail to
		the &a.ports; and please include the name/version of the port,
		where you got both the port source &amp; distfile(s) from, and
		what the text of the error was.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Forget it. This is the easiest for most &mdash; very few of the
		programs in ports can be classified as essential!</para>
	    </listitem>
	    
	    <listitem>
	      <para>Grab the pre-compiled package from a ftp server. The
		&ldquo;master&rdquo; package collection is on FreeBSD's FTP server in
		the <ulink
		  URL="ftp://ftp.FreeBSD.org/pub/FreeBSD/packages/">packages
		  directory</ulink>, though check your local mirror first,
		please! These are more likely to work (on the whole) than
		trying to compile from source and a lot faster besides! Use
		the <citerefentry><refentrytitle>pkg_add</refentrytitle><manvolnum>1</manvolnum></citerefentry>  program to install a
		package file on your system.</para>
	    </listitem>
	    
	  </orderedlist>
	
	
      </sect1>
      
      <sect1>
	<title>I Want to Make a Port!</title>
	
	<para>Great! Please see the <xref linkend="porting"
	    remap="guidelines"> for detailed instructions on how to do
	  this.</para>
	
      </sect1>
      
      <sect1>
	<title>Some Questions and Answers</title>
	
	
	  <itemizedlist>
	    
	    <listitem>
	      <para>Q. I thought this was going to be a discussion about
		modems??!</para>
	      
	      <para>A. Ah. You must be thinking of the serial ports on the
		back of your computer. We are using &ldquo;port&rdquo; here to mean the
		result of &ldquo;porting&rdquo; a program from one version of Unix to
		another. (It is an unfortunate bad habit of computer people to
		use the same word to refer to several completely different
		things).</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I thought you were supposed to use packages to install
		extra programs?</para>
	      
	      <para>A. Yes, that is usually the quickest and easiest way of
		doing it.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. So why bother with ports then?</para>
	      
	      <para>A. Several reasons:-</para>
	      
	      
		<orderedlist>
		  
		  <listitem>
		    <para>The licensing conditions on some software
		      distributions require that they be distributed as source
		      code, not binaries.</para>
		  </listitem>
		  
		  <listitem>
		    <para>Some people do not trust binary distributions. At
		      least with source code you can (in theory) read through
		      it and look for potential problems yourself.</para>
		  </listitem>
		  
		  <listitem>
		    <para>If you have some local patches, you will need the
		      source to add them yourself.</para>
		  </listitem>
		  
		  <listitem>
		    <para>You might have opinions on how a program should be
		      compiled that differ from the person who did the package
		      &mdash; some people have strong views on what optimisation
		      setting should be used, whether to build debug versions
		      and then strip them or not, etc. etc.</para>
		  </listitem>
		  
		  <listitem>
		    <para>Some people like having code around, so they can
		      read it if they get bored, hack around with it, borrow
		      from it (licence terms permitting, of course!) and so
		      on.</para>
		  </listitem>
		  
		  <listitem>
		    <para>If you ain't got the source, it ain't software!
		      <!-- smiley -->;-)</para>
		  </listitem>
		  
		</orderedlist>
	      
	    </listitem>
	    
	    <listitem>
	      <para><anchor id="ports-patch"> Q. What is a patch?</para>
	      
	      <para>A. A patch is a small (usually) file that specifies how to
		go from one version of a file to another. It contains text
		that says, in effect, things like &ldquo;delete line 23&rdquo;, &ldquo;add
		these two lines after line 468&rdquo; or &ldquo;change line 197 to
		  this&rdquo;. Also known as a &ldquo;diff&rdquo;, since it is generated by a
		program of that name.</para>
	    </listitem>
	    
	    <listitem>
	      <para><anchor id="ports-tarball"> Q. What is all this about
		tarballs?</para>
	      
	      <para>A. It is a file ending in <filename>.tar</filename> or
		<filename>.tar.gz</filename> (with variations like
		<filename>.tar.Z</filename>, or even <filename>.tgz</filename>
		if you are trying to squeeze the names into a DOS
		filesystem).</para>
	      
	      <para>Basically, it is a directory tree that has been archived
		into a single file (<filename>.tar</filename>) and optionally
		compressed (<filename>.gz</filename>). This technique was
		originally used for <emphasis>T</emphasis>ape
		<emphasis>AR</emphasis>chives (hence the name <command>tar</command>), but it is
		a widely used way of distributing program source code around
		the Internet.</para>
	      
	      <para>You can see what files are in them, or even extract them
		yourself, by using the standard Unix tar program, which comes
		with the base FreeBSD system, like this:-</para>
	      
	      <informalexample>
		<screen>&prompt.user; <userinput>tar tvzf foobar.tar.gz</userinput>		
&prompt.user; <userinput>tar xzvf foobar.tar.gz</userinput>
&prompt.user; <userinput>tar tvf foobar.tar</userinput>
&prompt.user; <userinput>tar xvf foobar.tar</userinput>
		</screen>
	      </informalexample>
	    </listitem>
	    
	    <listitem>
	      <para><anchor id="ports-checksum"> Q. And a checksum?</para>
	      
	      <para>A. It is a number generated by adding up all the data in
		the file you want to check. If any of the characters change,
		the checksum will no longer be equal to the total, so a simple
		comparison will allow you to spot the difference. (In
		practice, it is done in a more complicated way to spot
		problems like position-swapping, which will not show up with a
		simplistic addition).</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I did what you said for <xref linkend="ports-cd"
		  remap="compiling ports from a CDROM"> and it worked great
		until I tried to install the kermit port:-</para>

		<informalexample>
		  <screen>&prompt.root; <userinput>make install</userinput>
&gt;&gt; cku190.tar.gz doesn't seem to exist on this system.
&gt;&gt; Attempting to fetch from ftp://kermit.columbia.edu/kermit/archives/.</screen>
		</informalexample>
		<para>Why can it not be found? Have I got a dud CDROM?</para>
	      
	      <para>A. The licensing terms for kermit do not allow us to put
		the tarball for it on the CDROM, so you will have to fetch it
		by hand &mdash; sorry! The reason why you got all those error
		messages was because you were not connected to the Internet at
		the time. Once you have downloaded it from any of the sites
		above, you can re-start the process (try and choose the
		nearest site to you, though, to save your time and the
		Internet's bandwidth).</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I did that, but when I tried to put it into
		<filename>/usr/ports/distfiles</filename> I got some error
		about not having permission.</para>
	      
	      <para>A. The ports mechanism looks for the tarball in
		<filename>/usr/ports/distfiles</filename>, but you will not be
		able to copy anything there because it is sym-linked to the
		CDROM, which is read-only. You can tell it to look somewhere
		else by doing</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>make  DISTDIR=/where/you/put/it install</userinput></screen>
	      </informalexample>
	    </listitem>
	    
	    <listitem>
	      <para>Q. Does the ports scheme only work if you have everything
		in <filename>/usr/ports</filename>? My system administrator
		says I must put everything under
		<filename>/u/people/guests/wurzburger</filename>, but it does
		not seem to work.</para>
	      
	      <para>A. You can use the <makevar>PORTSDIR</makevar> and <makevar>PREFIX</makevar> variables to tell
		the ports mechanism to use different directories. For
		instance,</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>make PORTSDIR=/u/people/guests/wurzburger/ports install</userinput></screen>
	      </informalexample>
	      
	      <para>will compile the port in
		<filename>/u/people/guests/wurzburger/ports</filename> and
		install everything under <filename>/usr/local</filename>.</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>make PREFIX=/u/people/guests/wurzburger/local install</userinput></screen>
	      </informalexample>
	      
	      <para>will compile it in <filename>/usr/ports</filename> and
		install it in
		<filename>/u/people/guests/wurzburger/local</filename>.</para>
	      
	      <para>And of course</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>make PORTSDIR=.../ports PREFIX=.../local install</userinput></screen>
	      </informalexample>
	      
	      <para>will combine the two (it is too long to fit on the page if
		I write it in full, but I am sure you get the idea).</para>
	      
	      <para>If you do not fancy typing all that in every time you
		install a port (and to be honest, who would?), it is a good
		idea to put these variables into your environment.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I do not have a FreeBSD CDROM, but I would like to have
		all the tarballs handy on my system so I do not have to wait
		for a download every time I install a port. Is there an easy
		way to get them all at once?</para>
	      
	      <para>A. To get every single tarball for the ports collection,
		do</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>make fetch</userinput></screen>
	      </informalexample>
	      
	      <para>For all the tarballs for a single ports directory,
		do</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>cd /usr/ports/directory</userinput>
&prompt.root; <userinput>make fetch</userinput></screen>
	      </informalexample>
	      
	      <para>and for just one port &mdash; well, I think you have guessed
		already.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I know it is probably faster to fetch the tarballs from
		one of the FreeBSD mirror sites close by. Is there any way to
		tell the port to fetch them from servers other than ones
		listed in the MASTER_SITES?</para>
	      
	      <para>A. Yes. If you know, for example, <hostid role="fqdn">ftp.FreeBSD.ORG</hostid> is much
		closer than sites listed in <makevar>MASTER_SITES</makevar>, do as following
		example.</para>

		<informalexample>
		  <screen>&prompt.root; <userinput>cd /usr/ports/directory</userinput>
&prompt.root; <userinput>make MASTER_SITE_OVERRIDE=ftp://ftp.FreeBSD.ORG/pub/FreeBSD/distfiles/ fetch</userinput></screen>
		</informalexample>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I want to know what files make is going to need before
		it tries to pull them down.</para>
	      
	      <para>A. <command>make fetch-list</command> will display a list of the files
		needed for a port.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. Is there any way to stop the port from compiling? I
		want to do some hacking on the source before I install it, but
		it is a bit tiresome having  to watch it and hit control-C
		every time.</para>
	      
	      <para>A. Doing <command>make extract</command> will stop it after it has fetched
		and extracted the source code.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I am trying to make my own port and I want to be able
		to stop it compiling until I have had a chance to see if my
		patches worked properly. Is there something like <command>make
		extract</command>, but for patches?</para>
	      
	      <para>A. Yep, <command>make patch</command> is what you want. You will probably
		find the <makevar>PATCH_DEBUG</makevar> option useful as well. And by the way,
		thank you for your efforts!</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I have heard that some compiler options can cause bugs.
		Is this true? How can I make sure that I compile ports with
		the right settings?</para>
	      
	      <para>A. Yes, with version 2.6.3 of <command>gcc</command> (the version shipped
		with FreeBSD 2.1.0 and 2.1.5), the <option>-O2</option> option could result in
		buggy code unless you used the <option>-fno-strength-reduce</option> option as
		well. (Most of the ports don't use <option>-O2</option>). You
		<emphasis>should</emphasis> be able to specify the compiler
		options used by something like</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>make CFLAGS='-O2 -fno-strength-reduce' install</userinput></screen>
	      </informalexample>
	      
	      <para>or by editing <filename>/etc/make.conf</filename>, but
		unfortunately not all ports respect this. The surest way is to
		do <command>make configure</command>, then go into the source directory and
		inspect the Makefiles by hand, but this can get tedious if the
		source has lots of sub-directories, each with their own
		Makefiles.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. There are so many ports it is hard to find the one I
		want. Is there a list anywhere of what ports are available?</para>
	      
	      <para>A. Look in the <filename>INDEX</filename> file in <filename>/usr/ports</filename>.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I went to install the <literal>foo</literal> port but the system
		suddenly stopped compiling it and starting compiling the
		<literal>bar</literal>
		port. What's going on?</para>
	      
	      <para>A. The <literal>foo</literal> port needs something that is supplied with
		<literal>bar</literal> &mdash; for instance, if <literal>foo</literal> uses graphics, <literal>bar</literal> might have
		a library with useful graphics processing routines. Or <literal>bar</literal>
		might be a tool that is needed to compile the <literal>foo</literal>
		port.</para>
	    </listitem>
	    
	    <listitem>
	      <para><anchor id="ports-remove">  Q. I installed the <literal>grizzle</literal>
		program from the ports and frankly it is a complete waste of
		disk space. I want to delete it but I do not know where it put
		all the files. Any clues?</para>
	      
	      <para>A. No problem, just do</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>pkg_delete grizzle-6.5</userinput></screen>
	      </informalexample>
	    </listitem>
	    
	    <listitem>
	      <para>
		Q. Hang on a minute, you have to know the version number to
		use that command. You do not seriously expect me to remember
		that, do you??</para>
	      
	      <para>A. Not at all, you can find it out by doing</para>
	      
	      <informalexample>
		<screen>&prompt.root; <userinput>pkg_info -a | grep grizzle</userinput>
Information for grizzle-6.5:
grizzle-6.5 - the combined piano tutorial, LOGO interpreter and shoot 'em up arcade game.</screen>
	      </informalexample>
	    </listitem>
	    
	    <listitem>
	      <para>Q. Talking of disk space, the ports directory seems to be
		taking up an awful lot of room. Is it safe to go in there and
		delete things?</para>
	      
	      <para>A. Yes, if you have installed the program and are fairly
		certain you will not need the source again, there is no point
		in keeping it hanging around. The best way to do this
		is</para>
	      
	      <informalexample>
	    <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>make clean</userinput></screen>
	      </informalexample>
	      
	      <para>which will go through all the ports subdirectories and
		delete everything except the skeletons for each port.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I tried that and it still left all those tarballs or
		whatever you called them in the <filename>distfiles</filename>
		directory. Can I delete those as well?</para>
	      
	      <para>A. Yes, if you are sure you have finished with them, those
		can go as well.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I like having lots and lots of programs to play with.
		Is there any way of installing all the ports in one go?</para>
	      
	      <para>A. Just do</para>
	      
	      <informalexample>
	    <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>make install</userinput></screen>
	      </informalexample>
	    </listitem>
	    
	    <listitem>
	      <para>Q. OK, I tried that, but I thought it would take a very
		long time so I went to bed and left it to get on with it. When
		I looked at the computer this morning, it had only done three
		and a half ports. Did something go wrong?</para>
	      
	      <para>A. No, the problem is that some of the ports need to ask
		you questions that we cannot answer for you (eg &ldquo;Do you want
		to print on A4 or US letter sized paper?&rdquo;) and they need to
		have someone on hand to answer them.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. I really do not want to spend all day staring at the
		monitor. Any better ideas?</para>
	      
	      <para>A. OK, do this before you go to bed/work/the local
		park:-</para>
	      
	      <informalexample>
	    <screen>&prompt.root <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>make -DBATCH install</userinput></screen>
	      </informalexample>
	      
	      <para>This will install every port that does
		<emphasis>not</emphasis> require user input. Then, when you
		come back, do</para>
	      
	      <informalexample>
	    <screen>&prompt.root; <userinput>cd /usr/ports</userinput>
&prompt.root; <userinput>make -DIS_INTERACTIVE install</userinput></screen>
	      </informalexample>
	      
	      <para>to finish the job.</para>
	    </listitem>
	    
	    <listitem>
	      <para>Q. At work, we are using <literal>frobble</literal>, which is in your ports
		collection, but we have altered it quite a bit to get it to do
		what we need. Is there any way of making our own packages, so
		we can distribute it more easily around our sites?</para>
	      
	      <para>A. No problem, assuming you know how to make patches for
		your changes:-</para>
	      
	      <informalexample>
	    <screen>&prompt.root; <userinput>cd /usr/ports/somewhere/frobble</userinput>
&prompt.root; <userinput>make extract</userinput>
&prompt.root; <userinput>cd work/frobble-2.8</userinput>
[Apply your patches]
&prompt.root; <userinput>cd ../..</userinput>
&prompt.root; <userinput>make package</userinput></screen>
	      </informalexample>
	    </listitem>
	    
	    <listitem>
	      <para>Q. This ports stuff is really clever. I am desperate to
		find out how you did it. What is the secret?</para>
	      
	      <para>A. Nothing secret about it at all, just look at the
		<filename>bsd.ports.mk</filename> and
		<filename>bsd.ports.subdir.mk</filename> files in your <ulink
		  URL="file://localhost/usr/share/mk/">makefiles
		  directory.</ulink></para>

	      <note>
		<para>Readers with an aversion to intricate shell-scripts are
		  advised not to follow this link...)</para>
	      </note>
	    </listitem>
	    
	  </itemizedlist>
	  
	
	
      </sect1>
    </chapter>


<!--
     Local Variables:
     mode: sgml
     sgml-declaration: "../chapter.decl"
     sgml-indent-data: t
     sgml-omittag: nil 
     sgml-shorttag: nil 
     sgml-always-quote-attributes: t 
     sgml-minimize-attributes: max
     sgml-parent-document: ("../handbook.sgml" "part" "chapter")
     End: 
-->