diff options
| author | Nik Clayton <nik@FreeBSD.org> | 1998-11-04 22:40:58 +0000 |
|---|---|---|
| committer | Nik Clayton <nik@FreeBSD.org> | 1998-11-04 22:40:58 +0000 |
| commit | 97d01a35671c4adcf7846825ffc40223128bb699 (patch) | |
| tree | 5ed7d3d191486233e160aa55c44f727a7e46caeb | |
| parent | 607a3f4ed3dbd7ad6f50542ec7ee43754e34307e (diff) | |
Notes
| -rw-r--r-- | en/handbook/ports/chapter.sgml | 1062 | ||||
| -rw-r--r-- | en_US.ISO8859-1/books/handbook/ports/chapter.sgml | 1062 | ||||
| -rw-r--r-- | en_US.ISO8859-1/books/porters-handbook/book.sgml | 1062 | ||||
| -rw-r--r-- | en_US.ISO_8859-1/books/handbook/ports/chapter.sgml | 1062 | ||||
| -rw-r--r-- | en_US.ISO_8859-1/books/porters-handbook/book.sgml | 1062 |
5 files changed, 5310 insertions, 0 deletions
diff --git a/en/handbook/ports/chapter.sgml b/en/handbook/ports/chapter.sgml new file mode 100644 index 0000000000..aa5d962c4a --- /dev/null +++ b/en/handbook/ports/chapter.sgml @@ -0,0 +1,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 + “out of the box”, 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 “I must have a look at that + when I get a spare minute” 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 “the + Unix way” 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 + "knowledge" 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>“How on earth can this do anything?” I hear you cry. “There + is no source code there!”</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> +>> Checksum OK for ElectricFence-2.0.5.tar.gz. +===> Extracting for ElectricFence-2.0.5 +===> Patching for ElectricFence-2.0.5 +===> Applying FreeBSD patches for ElectricFence-2.0.5 +===> Configuring for ElectricFence-2.0.5 +===> Building for ElectricFence-2.0.5 +[lots of compiler output...] +===> Installing for ElectricFence-2.0.5 +===> 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 +===> Compressing manual pages for ElectricFence-2.0.5 +===> 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> +>> ElectricFence-2.0.5.tar.gz doesn't seem to exist on this system. +>> 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 “Do you want to link the + ports collection to your CDROM” 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 “the current + directory”) 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 “link tree” 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>></prompt> <userinput>cd /pub/FreeBSD/ports/databases</userinput> +<prompt>></prompt> <userinput>get gnats.tar</userinput> +[tars up the gnats skeleton for us] +<prompt>></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>></prompt> <userinput>cd /pub/FreeBSD/ports</userinput> +<prompt>></prompt> <userinput>get databases.tar</userinput> +[tars up the databases directory for us] +<prompt>></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 +# +# $Id$ +# + +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 <bsd.port.mk></programlisting> + + <para>The lines beginning with a "#" 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 "officially" 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 <bsd.port.mk></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> — a one-line description of + the program.</para> + </listitem> + + <listitem> + <para><filename>DESCR</filename> — a more detailed description.</para> + </listitem> + + <listitem> + <para><filename>PLIST</filename> — 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 & distfile(s) from, and + what the text of the error was.</para> + </listitem> + + <listitem> + <para>Forget it. This is the easiest for most — 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 + “master” 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 “port” here to mean the + result of “porting” 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 + — 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 “delete line 23”, “add + these two lines after line 468” or “change line 197 to + this”. Also known as a “diff”, 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> +>> cku190.tar.gz doesn't seem to exist on this system. +>> 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 — 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 — 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> — 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 “Do you want + to print on A4 or US letter sized paper?”) 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: +--> + diff --git a/en_US.ISO8859-1/books/handbook/ports/chapter.sgml b/en_US.ISO8859-1/books/handbook/ports/chapter.sgml new file mode 100644 index 0000000000..aa5d962c4a --- /dev/null +++ b/en_US.ISO8859-1/books/handbook/ports/chapter.sgml @@ -0,0 +1,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 + “out of the box”, 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 “I must have a look at that + when I get a spare minute” 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 “the + Unix way” 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 + "knowledge" 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>“How on earth can this do anything?” I hear you cry. “There + is no source code there!”</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> +>> Checksum OK for ElectricFence-2.0.5.tar.gz. +===> Extracting for ElectricFence-2.0.5 +===> Patching for ElectricFence-2.0.5 +===> Applying FreeBSD patches for ElectricFence-2.0.5 +===> Configuring for ElectricFence-2.0.5 +===> Building for ElectricFence-2.0.5 +[lots of compiler output...] +===> Installing for ElectricFence-2.0.5 +===> 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 +===> Compressing manual pages for ElectricFence-2.0.5 +===> 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> +>> ElectricFence-2.0.5.tar.gz doesn't seem to exist on this system. +>> 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 “Do you want to link the + ports collection to your CDROM” 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 “the current + directory”) 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 “link tree” 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>></prompt> <userinput>cd /pub/FreeBSD/ports/databases</userinput> +<prompt>></prompt> <userinput>get gnats.tar</userinput> +[tars up the gnats skeleton for us] +<prompt>></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>></prompt> <userinput>cd /pub/FreeBSD/ports</userinput> +<prompt>></prompt> <userinput>get databases.tar</userinput> +[tars up the databases directory for us] +<prompt>></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 +# +# $Id$ +# + +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 <bsd.port.mk></programlisting> + + <para>The lines beginning with a "#" 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 "officially" 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 <bsd.port.mk></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> — a one-line description of + the program.</para> + </listitem> + + <listitem> + <para><filename>DESCR</filename> — a more detailed description.</para> + </listitem> + + <listitem> + <para><filename>PLIST</filename> — 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 & distfile(s) from, and + what the text of the error was.</para> + </listitem> + + <listitem> + <para>Forget it. This is the easiest for most — 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 + “master” 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 “port” here to mean the + result of “porting” 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 + — 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 “delete line 23”, “add + these two lines after line 468” or “change line 197 to + this”. Also known as a “diff”, 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> +>> cku190.tar.gz doesn't seem to exist on this system. +>> 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 — 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 — 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> — 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 “Do you want + to print on A4 or US letter sized paper?”) 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: +--> + diff --git a/en_US.ISO8859-1/books/porters-handbook/book.sgml b/en_US.ISO8859-1/books/porters-handbook/book.sgml new file mode 100644 index 0000000000..aa5d962c4a --- /dev/null +++ b/en_US.ISO8859-1/books/porters-handbook/book.sgml @@ -0,0 +1,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 + “out of the box”, 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 “I must have a look at that + when I get a spare minute” 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 “the + Unix way” 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 + "knowledge" 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>“How on earth can this do anything?” I hear you cry. “There + is no source code there!”</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> +>> Checksum OK for ElectricFence-2.0.5.tar.gz. +===> Extracting for ElectricFence-2.0.5 +===> Patching for ElectricFence-2.0.5 +===> Applying FreeBSD patches for ElectricFence-2.0.5 +===> Configuring for ElectricFence-2.0.5 +===> Building for ElectricFence-2.0.5 +[lots of compiler output...] +===> Installing for ElectricFence-2.0.5 +===> 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 +===> Compressing manual pages for ElectricFence-2.0.5 +===> 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> +>> ElectricFence-2.0.5.tar.gz doesn't seem to exist on this system. +>> 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 “Do you want to link the + ports collection to your CDROM” 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 “the current + directory”) 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 “link tree” 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>></prompt> <userinput>cd /pub/FreeBSD/ports/databases</userinput> +<prompt>></prompt> <userinput>get gnats.tar</userinput> +[tars up the gnats skeleton for us] +<prompt>></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>></prompt> <userinput>cd /pub/FreeBSD/ports</userinput> +<prompt>></prompt> <userinput>get databases.tar</userinput> +[tars up the databases directory for us] +<prompt>></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 +# +# $Id$ +# + +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 <bsd.port.mk></programlisting> + + <para>The lines beginning with a "#" 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 "officially" 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 <bsd.port.mk></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> — a one-line description of + the program.</para> + </listitem> + + <listitem> + <para><filename>DESCR</filename> — a more detailed description.</para> + </listitem> + + <listitem> + <para><filename>PLIST</filename> — 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 & distfile(s) from, and + what the text of the error was.</para> + </listitem> + + <listitem> + <para>Forget it. This is the easiest for most — 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 + “master” 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 “port” here to mean the + result of “porting” 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 + — 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 “delete line 23”, “add + these two lines after line 468” or “change line 197 to + this”. Also known as a “diff”, 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> +>> cku190.tar.gz doesn't seem to exist on this system. +>> 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 — 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 — 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> — 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 “Do you want + to print on A4 or US letter sized paper?”) 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: +--> + diff --git a/en_US.ISO_8859-1/books/handbook/ports/chapter.sgml b/en_US.ISO_8859-1/books/handbook/ports/chapter.sgml new file mode 100644 index 0000000000..aa5d962c4a --- /dev/null +++ b/en_US.ISO_8859-1/books/handbook/ports/chapter.sgml @@ -0,0 +1,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 + “out of the box”, 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 “I must have a look at that + when I get a spare minute” 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 “the + Unix way” 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 + "knowledge" 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>“How on earth can this do anything?” I hear you cry. “There + is no source code there!”</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> +>> Checksum OK for ElectricFence-2.0.5.tar.gz. +===> Extracting for ElectricFence-2.0.5 +===> Patching for ElectricFence-2.0.5 +===> Applying FreeBSD patches for ElectricFence-2.0.5 +===> Configuring for ElectricFence-2.0.5 +===> Building for ElectricFence-2.0.5 +[lots of compiler output...] +===> Installing for ElectricFence-2.0.5 +===> 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 +===> Compressing manual pages for ElectricFence-2.0.5 +===> 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> +>> ElectricFence-2.0.5.tar.gz doesn't seem to exist on this system. +>> 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 “Do you want to link the + ports collection to your CDROM” 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 “the current + directory”) 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 “link tree” 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>></prompt> <userinput>cd /pub/FreeBSD/ports/databases</userinput> +<prompt>></prompt> <userinput>get gnats.tar</userinput> +[tars up the gnats skeleton for us] +<prompt>></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>></prompt> <userinput>cd /pub/FreeBSD/ports</userinput> +<prompt>></prompt> <userinput>get databases.tar</userinput> +[tars up the databases directory for us] +<prompt>></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 +# +# $Id$ +# + +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 <bsd.port.mk></programlisting> + + <para>The lines beginning with a "#" 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 "officially" 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 <bsd.port.mk></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> — a one-line description of + the program.</para> + </listitem> + + <listitem> + <para><filename>DESCR</filename> — a more detailed description.</para> + </listitem> + + <listitem> + <para><filename>PLIST</filename> — 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 & distfile(s) from, and + what the text of the error was.</para> + </listitem> + + <listitem> + <para>Forget it. This is the easiest for most — 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 + “master” 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 “port” here to mean the + result of “porting” 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 + — 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 “delete line 23”, “add + these two lines after line 468” or “change line 197 to + this”. Also known as a “diff”, 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> +>> cku190.tar.gz doesn't seem to exist on this system. +>> 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 — 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 — 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> — 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 “Do you want + to print on A4 or US letter sized paper?”) 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: +--> + diff --git a/en_US.ISO_8859-1/books/porters-handbook/book.sgml b/en_US.ISO_8859-1/books/porters-handbook/book.sgml new file mode 100644 index 0000000000..aa5d962c4a --- /dev/null +++ b/en_US.ISO_8859-1/books/porters-handbook/book.sgml @@ -0,0 +1,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 + “out of the box”, 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 “I must have a look at that + when I get a spare minute” 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 “the + Unix way” 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 + "knowledge" 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>“How on earth can this do anything?” I hear you cry. “There + is no source code there!”</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> +>> Checksum OK for ElectricFence-2.0.5.tar.gz. +===> Extracting for ElectricFence-2.0.5 +===> Patching for ElectricFence-2.0.5 +===> Applying FreeBSD patches for ElectricFence-2.0.5 +===> Configuring for ElectricFence-2.0.5 +===> Building for ElectricFence-2.0.5 +[lots of compiler output...] +===> Installing for ElectricFence-2.0.5 +===> 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 +===> Compressing manual pages for ElectricFence-2.0.5 +===> 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> +>> ElectricFence-2.0.5.tar.gz doesn't seem to exist on this system. +>> 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 “Do you want to link the + ports collection to your CDROM” 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 “the current + directory”) 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 “link tree” 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>></prompt> <userinput>cd /pub/FreeBSD/ports/databases</userinput> +<prompt>></prompt> <userinput>get gnats.tar</userinput> +[tars up the gnats skeleton for us] +<prompt>></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>></prompt> <userinput>cd /pub/FreeBSD/ports</userinput> +<prompt>></prompt> <userinput>get databases.tar</userinput> +[tars up the databases directory for us] +<prompt>></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 +# +# $Id$ +# + +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 <bsd.port.mk></programlisting> + + <para>The lines beginning with a "#" 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 "officially" 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 <bsd.port.mk></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> — a one-line description of + the program.</para> + </listitem> + + <listitem> + <para><filename>DESCR</filename> — a more detailed description.</para> + </listitem> + + <listitem> + <para><filename>PLIST</filename> — 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 & distfile(s) from, and + what the text of the error was.</para> + </listitem> + + <listitem> + <para>Forget it. This is the easiest for most — 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 + “master” 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 “port” here to mean the + result of “porting” 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 + — 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 “delete line 23”, “add + these two lines after line 468” or “change line 197 to + this”. Also known as a “diff”, 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> +>> cku190.tar.gz doesn't seem to exist on this system. +>> 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 — 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 — 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> — 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 “Do you want + to print on A4 or US letter sized paper?”) 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: +--> + |
