From owner-freebsd-ports Sun Mar 17 11:35:19 1996 Return-Path: owner-ports Received: (from root@localhost) by freefall.freebsd.org (8.7.3/8.7.3) id LAA00948 for ports-outgoing; Sun, 17 Mar 1996 11:35:19 -0800 (PST) Received: from news1.gtn.com (news1.gtn.com [192.109.159.3]) by freefall.freebsd.org (8.7.3/8.7.3) with ESMTP id LAA00935 Sun, 17 Mar 1996 11:35:12 -0800 (PST) Received: (from uucp@localhost) by news1.gtn.com (8.7.2/8.7.2) id UAA25016; Sun, 17 Mar 1996 20:15:29 +0100 (MET) Received: (from andreas@localhost) by knobel.gun.de (8.7.5/8.7.3) id UAA09099; Sun, 17 Mar 1996 20:11:08 +0100 (MET) From: Andreas Klemm Message-Id: <199603171911.UAA09099@knobel.gun.de> Subject: HOWTO make a FreeBSD port To: doc@freebsd.org Date: Sun, 17 Mar 1996 20:11:08 +0100 (MET) Cc: ports@freebsd.org X-Mailer: ELM [version 2.4ME+ PL13 (25)] MIME-Version: 1.0 Content-Type: text/plain; charset=US-ASCII Content-Transfer-Encoding: 7bit Sender: owner-ports@freebsd.org X-Loop: FreeBSD.org Precedence: bulk Hi ! I've tried to make a little guide how to create a port. Ok, it still doesn't cover every detail, but is perhaps a good guidance for the "very beginner". Please could someone, who is experienced in writing smgl documents, convert this into sgml (if you like this document) ? I think it should be included into the FreeBSD Handbook in the ports section as an "life" example. Additionally you native English speakers should correct a bit my chicken English if needed ;-)) BTW: Satoshi, a new port is coming, guess what ;-)) Regards Andreas /// ======================================================================= From: Andreas Klemm How to create a FreeBSD port Let's say we want to create a port of the program mapedit, that is heavily used by WEB authors to create clickable image maps. In the first step we create a new directory in the ports directory structure, where all port files will reside: # mkdir -p /usr/ports/www/mapedit In the first step we'll create a small and simple Makefile with a minimum configuration. The first aim is to automatically get the source archive from the ftp server. After that we'll find out step for step, which additional thinks we have do define there. The starting Makefile contains only four lines: -------------------------------------------------------------------------------- DISTNAME= mapedit1.5 CATEGORIES= www MASTER_SITES= ftp://ftp.boutell.com/pub/boutell/mapedit/ .include -------------------------------------------------------------------------------- When choosing a DISTNAME it's a good starting point, to take the name of the source archive, since many other variables and assumptions in the bsd.port.mk file are based on that name. The name of the tar archive we want to get is mapedit1.5.tar.Z. Therefore we choose the distname mapedit1.5. Let's type 'make extract' at the command prompt to get and extract the sources and see what's happening: # make extract >> mapedit1.5.tar.gz doesn't seem to exist on this system. >> Attempting to fetch from ftp://ftp.boutell.com/pub/boutell/mapedit/. Not bad. Make detected, that mapedit1.5.tar.Z isn't stored in /usr/ports/distfiles and automtically tries to get the file via ftp from the master site. The only thing we have to manage now is, that we have to change the suffix ".tar.gz" since our source isn't compressed with GNU zip. When browsing through /usr/share/mk/bsd.port.mk we see the following definition: DISTFILES - Name(s) of archive file(s) containing distribution (default: ${DISTNAME}${EXTRACT_SUFX}). This means, that we have to change the variable EXTRACT_SUFX, to get the ftp part managed, Makefile now looks like this: ------------------------------------------------------------------------------- DISTNAME= mapedit1.5 CATEGORIES= www EXTRACT_SUFX= .tar.Z MASTER_SITES= ftp://ftp.boutell.com/pub/boutell/mapedit/ .include ------------------------------------------------------------------------------- Let's see what's happening now: # make extract ------------------------------------------------------------------------------- 1 >> mapedit1.5.tar.Z doesn't seem to exist on this system. 2 >> Attempting to fetch from ftp://ftp.boutell.com/pub/boutell/mapedit/. 3 Receiving file: mapedit1.5.tar.Z 4 100% 0 71407 bytes. ETA: 0:00 5 mapedit1.5.tar.Z: 71407 bytes received in 49.25 seconds, 1.42 K/s. 6 >> No MD5 checksum file. 7 ===> Extracting for mapedit1.5 ------------------------------------------------------------------------------- This looks better. Line 1 shows, that ncftp now tries to get the correct file from the ftp server. The transmission went on without any error (lines 3-5). Line 6 is normal. We'll create a md5 file later. This file will then reside in the files subdir. Line 7 informs us, that the tar archive was automatically extracted in the subdir 'work'. After the transmission (lines 1-5) we have now the source archive locally stored on disk: /usr/ports/distfiles/mapedit1.5.tar.Z After the extraction of the sources (line 7) we have a workdir /usr/ports/www/mapedit/work/mapedit1.5 The toplevel directory of the workdir shows us, that this is an X11 program. By defining USE_IMAKE and USE_X11 in the Makefile, we achieve, that imake will be started up automatically before the compilation of the sources (in the workdir) starts. Makefile looks now like that: -------------------------------------------------------------------------------- DISTNAME= mapedit1.5 CATEGORIES+= www EXTRACT_SUFX= .tar.Z USE_IMAKE= True USE_X11= True MASTER_SITES= ftp://ftp.boutell.com/pub/boutell/mapedit/ .include -------------------------------------------------------------------------------- If we type 'make' again in the port toplevel directory (/usr/ports/www/mapedit), we'll notice that make is clever and remembers, that the source is already here, and that it was extrected in a previous step. This is done by 0 Byte file in the workdir, that act as a marker. In this case the file /usr/ports/www/mapedit1.5/work/.extract_done prevents a new extraction. # make -------------------------------------------------------------------------------- 1 >> No MD5 checksum file. 2 ===> Patching for mapedit1.5 3 ===> Configuring for mapedit1.5 4 mv -f Makefile Makefile.bak 5 imake -DUseInstalled -I/usr/X11R6/lib/X11/config 6 make Makefiles 7 make includes 8 make depend 9 gccmakedep -- -I/usr/X11R6/include -DCSRG_BASED -DFUNCPROTO=15 -DNARROWPROTO -DANSI -- gd.c mapedit.c 10 In file included from gd.c:1: 11 /usr/include/malloc.h:2: warning: #warning "this file includes which is obsoleted, use instead" -------------------------------------------------------------------------------- As we can see in line 5, imake was now properly called, before starting the compilation, that would have started after the 'make depend'. The error message informs us now, that we should make some modification to the sources, since FreeBSD prefers the header file . This will be a good example, how we add patches to this port. So that even the patching of the sources is done automatically by make. All we have to do is to change the sources in the workdir, make context diffs and place them into a subdir called patches. # grep malloc work/mapedit1.5/* work/mapedit1.5/gd.c:#include work/mapedit1.5/mapedit.c:#include Save the files you want to modify later # cp work/mapedit1.5/gd.c work/mapedit1.5/gd.c.orig # cp work/mapedit1.5/mapedit.c work/mapedit1.5/mapedit.c.orig Modify the files # vi `grep -l malloc work/mapedit1.5/*` For example: #ifdef __FreeBSD__ #include #else #include #endif Create the directory for the patches, and collect the context diffs: # mkdir /usr/ports/www/mapedit/patches You have to stay in the workdir directory ! # cd /usr/ports/www/mapedit/work/mapedit1.5 # diff -c gd.c.orig gd.c.orig > ../../patches/patch-aa # diff -c mapedit.c.orig mapedit.c.orig > ../../patches/patch-ab Now we want to test, if everything runs fine, including this new patch feature: # cd ../.. # topdir of the port /usr/port/www/mapedit # make clean -------------------------------------------------------------------------------- ===> Cleaning for mapedit1.5 -------------------------------------------------------------------------------- Please note, doing a make clean removes the whole work directory ! At this point we'll create a checksum file (md5 file), so this step is done, too. # make makesum This creates a md5 file in /usr/ports/www/mapedit/files/md5 with the following content: MD5 (mapedit1.5.tar.Z) = 7ad4bd45951dc2e07bad032379e96ed2 This makes sure, that people using your port, have grabbed the correct source archive and that it's not corrupt. Again we start the port by typing simply 'make' # make -------------------------------------------------------------------------------- 1 Checksums OK. 2 ===> Extracting for mapedit1.5 3 ===> Patching for mapedit1.5 4 ===> Applying FreeBSD patches for mapedit1.5 5 ===> Configuring for mapedit1.5 6 mv -f Makefile Makefile.bak 7 imake -DUseInstalled -I/usr/X11R6/lib/X11/config 8 make Makefiles 9 make includes 10 make depend 11 gccmakedep -- -I/usr/X11R6/include -DCSRG_BASED -DFUNCPROTO=15 -DNARROWPROTO -DANSI -- gd.c mapedit.c 12 ===> Building for mapedit1.5 13 gcc -m486 -O2 -I/usr/X11R6/include -DCSRG_BASED -DFUNCPROTO=15 -DNARROWPROTO -DANSI -c gd.c 14 gcc -m486 -O2 -I/usr/X11R6/include -DCSRG_BASED -DFUNCPROTO=15 -DNARROWPROTO -DANSI -c mapedit.c 15 rm -f mapedit 16 gcc -o mapedit -m486 -O2 -L/usr/X11R6/lib gd.o mapedit.o -lXaw -lXmu -L/usr/X11R6/lib -lXt -lX11 -lXt -lSM -lICE -lXExExt -lXext -lX11 -lm -------------------------------------------------------------------------------- What's new ? After creating the md5 file, we'll get informed now, that we got the correct sources and that they aren't coruppted (line 1) In the following we see a successfully running port. We are now ready to install the package by simply typing # make install -------------------------------------------------------------------------------- Checksums OK. ===> Installing for mapedit1.5 /usr/bin/install -c -s mapedit /usr/X11R6/bin/mapedit install in . done make: don't know how to make mapedit.man. Stop *** Error code 2 ... -------------------------------------------------------------------------------- Oh, what happened now ... Well, the package comes without manual page. We have to tell 'make' this circumstance in the Makefile, too, by defining NO_INSTALL_MANPAGES. Makefile now looks like this: -------------------------------------------------------------------------------- DISTNAME= mapedit1.5 CATEGORIES+= www EXTRACT_SUFX= .tar.Z USE_IMAKE= True USE_X11= True NO_INSTALL_MANPAGES= True MASTER_SITES= ftp://ftp.boutell.com/pub/boutell/mapedit/ .include -------------------------------------------------------------------------------- After that modification we repeat the 'make install' step. Now the output is: -------------------------------------------------------------------------------- Checksums OK. ===> Installing for mapedit1.5 /usr/bin/install -c -s mapedit /usr/X11R6/bin/mapedit install in . done ** Missing package files for mapedit1.5 - installation not recorded. *** Error code 1 ... -------------------------------------------------------------------------------- Ok, well done. We only have to create some missing files for package management, so that the package can be recorded properly as installed. This is needed to be able to use the package management utilities like pkg_delete and friends. For this purpose we create the following files in a separate pkg directory: COMMENT a one line description of the package -------------------------------------------------------------------------------- mapedit - a WWW authoring tool to create clickable maps -------------------------------------------------------------------------------- DESCR a short description of the package (a "screen full") -------------------------------------------------------------------------------- mapedit was made for the purpose "blah", etc, etc etc, from foo@bar.com -------------------------------------------------------------------------------- PLIST a list of installed files that belong to the package The PLIST file is hevily used by the package management utilities like pkg_delete. A suitable PLIST file for mapedit would be: -------------------------------------------------------------------------------- /usr/X11R6/bin/mapedit -------------------------------------------------------------------------------- A new test. We hope, it's the final one ;-) # make clean all install -------------------------------------------------------------------------------- ===> Cleaning for mapedit1.5 Checksums OK. ===> Extracting for mapedit1.5 ===> Patching for mapedit1.5 ===> Applying FreeBSD patches for mapedit1.5 ===> Configuring for mapedit1.5 mv -f Makefile Makefile.bak imake -DUseInstalled -I/usr/X11R6/lib/X11/config make Makefiles make includes make depend gccmakedep -- -I/usr/X11R6/include -DCSRG_BASED -DFUNCPROTO=15 -DNARROWPROTO -DANSI -- gd.c mapedit.c ===> Building for mapedit1.5 gcc -m486 -O2 -I/usr/X11R6/include -DCSRG_BASED -DFUNCPROTO=15 -DNARROWPROTO -DANSI -c gd.c gcc -m486 -O2 -I/usr/X11R6/include -DCSRG_BASED -DFUNCPROTO=15 -DNARROWPROTO -DANSI -c mapedit.c rm -f mapedit gcc -o mapedit -m486 -O2 -L/usr/X11R6/lib gd.o mapedit.o -lXaw -lXmu -L/us r/X11R6/lib -lXt -lX11 -lXt -lSM -lICE -lXExExt -lXext -lX11 -lm ===> Installing for mapedit1.5 /usr/bin/install -c -s mapedit /usr/X11R6/bin/mapedit install in . done -------------------------------------------------------------------------------- Ok, well done ! Now we should finally add a note into Makefile, who's the maintainer of this packages. So the very last Makefile looks like this: -------------------------------------------------------------------------------- # New ports collection makefile for: mapedit # Version required: 1.5 # Date created: Sun Mar 17 20:00:31 MET 1996 # Whom: Andreas Klemm # DISTNAME= mapedit1.5 CATEGORIES+= www EXTRACT_SUFX= .tar.Z MAINTAINER= andreas@knobel.gun.de USE_IMAKE= True USE_X11= True NO_INSTALL_MANPAGES= True MASTER_SITES= ftp://ftp.boutell.com/pub/boutell/mapedit/ .include -------------------------------------------------------------------------------- That's it folks. After doing the port you can send it as compressed tar archive uuencoded to the maintainer of the ports collection. # cd /usr/ports/www/mapedit # make clean # cd .. # tar cvzf mapedit.tar.gz mapedit # uuencode mapedit.tar.gz < mapedit.tar.gz > mapedit.tar.gz.uue # mail -s "new port www/mapedit" PortsMaintainer < mapedit.tar.gz.uue This is only an example, normally one has to say some more things about the port ;-) And don't forget to send it as user, not as root ;-)) -- andreas@knobel.gun.de /\/\___ Wiechers & Partner Datentechnik GmbH Andreas Klemm ___/\/\/ $$ Support Unix - aklemm@wup.de $$ pgp p-key http://www-swiss.ai.mit.edu/~bal/pks-toplev.html >>> powered by <<< ftp://sunsite.unc.edu/pub/Linux/system/Printing/aps-491.tgz >>> FreeBSD <<< "Ich bleibe bei der Aussage und trotze den Flames. :-)" Ulli Horlacher 02/96