source: trunk/doc/guide/new/xml/portfiledev.xml @ 27640

Last change on this file since 27640 was 27640, checked in by markd@…, 13 years ago

Added a separate variants section and modified examples.

File size: 20.7 KB
Line 
1<?xml version="1.0" encoding="UTF-8"?>
2<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
3"http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
4<chapter>
5  <title>Portfile Development</title>
6
7  <para>This chapter covers a brief introduction to Portfiles, how to create a
8  local <filename>Portfile</filename> repository for development, and creating
9  Portfiles.</para>
10
11  <section>
12    <title>Portfile Introduction</title>
13
14    <para>A MacPorts <filename>Portfile</filename> is a TCL script that
15    usually contains only the simple keyword/value combinations and Tcl
16    primitives as described in the Portfile Reference section below, though it
17    may also contain arbitrary TCL code. Every port has a corresponding
18    <filename>Portfile</filename>, but Portfiles do not completely define a
19    port's installation behavior since the MacPorts base has default port
20    installation characteristics coded within it. Therefore Portfiles need
21    only specify required options and, when required, non-default
22    characteristics for a port.</para>
23
24    <para>A common way for Portfiles to augment or override MacPorts base
25    default installation phase characteristics is by using
26    <filename>Portfile</filename> phase declaration(s). If you use
27    <filename>Portfile</filename> phase declaration(s), you should know how to
28    identify the "global" section of a <filename>Portfile</filename>. Any
29    statements not contained within a phase declaration, no matter where they
30    are located in a <filename>Portfile</filename>, are said to be in the
31    global section of the <filename>Portfile</filename>, therefore the global
32    section need not be contiguous. Likewise, to remove statements from the
33    global section they must be placed within a phase declaration.</para>
34
35    <para>The main phases you need to be aware of when making a
36    <filename>Portfile</filename> are these:</para>
37
38    <itemizedlist>
39      <listitem>
40        <para>Fetch</para>
41      </listitem>
42
43      <listitem>
44        <para>Extract</para>
45      </listitem>
46
47      <listitem>
48        <para>Patch</para>
49      </listitem>
50
51      <listitem>
52        <para>Configure</para>
53      </listitem>
54
55      <listitem>
56        <para>Build</para>
57      </listitem>
58
59      <listitem>
60        <para>Destroot</para>
61      </listitem>
62    </itemizedlist>
63
64    <para>The default installation phase behavior performed by the MacPorts
65    base works fine for applications that use the standard
66    <command>configure</command>, <command>make</command>, and <command>make
67    install</command> steps, which conform to phases configure, build, and
68    destroot respectively. For applications that do not conform to this
69    standard behavior, any installation phase may be augmented using pre-
70    and/or post- phases, or even overridden or eliminated. See the section
71    "Example Portfiles" below.</para>
72
73    <note>
74      <para>For a detailed description of all port phases, see the section
75      "Portfile Reference" below.</para>
76    </note>
77  </section>
78
79  <section>
80    <title>Local Portfile Repositories</title>
81
82    <para>To create and test <filename>Portfile</filename>s that are not yet
83    committed to subversion, you may create a local
84    <filename>Portfile</filename> repository as shown.</para>
85
86    <orderedlist>
87      <listitem>
88        <para>Open the <filename>sources.conf</filename> file in a text
89        editor.</para>
90
91        <programlisting><prompt>%%</prompt> <userinput>cd ${prefix}/etc/macports/</userinput>
92<prompt>%%</prompt> <userinput>pico sources.conf</userinput></programlisting>
93      </listitem>
94
95      <listitem>
96        <para>Insert a URL pointing to the local repository location before
97        the rsync URL as shown.</para>
98
99        <programlisting>file:///Users/joebob/ports
100rsync://rsync.macports.org/release/ports
101</programlisting>
102
103        <note>
104          <para>The file URL should always appear before the rsync URL so that
105          local <filename>Portfile</filename>s can be tested that are
106          duplicated in the MacPorts tree, because the <command>port</command>
107          command will always operate on the first
108          <filename>Portfile</filename> it encounters.</para>
109        </note>
110      </listitem>
111
112      <listitem>
113        <para>Place the <filename>Portfile</filename>s you create inside a
114        directory whose name matches the port, which should in turn be placed
115        inside a directory that reflect the port's primary category (the first
116        category entry in the <filename>Portfile</filename>).</para>
117
118        <programlisting><prompt>%%</prompt> <userinput>cd /Users/joebob</userinput>
119<prompt>%%</prompt> <userinput>mkdir -p ports/games/bestevergame</userinput>
120<prompt>%%</prompt> <userinput>cd ports/games/bestevergame</userinput>
121<prompt>%%</prompt> <userinput>touch Portfile</userinput></programlisting>
122      </listitem>
123
124      <listitem>
125        <para>After a <filename>Portfile</filename> is created (see below),
126        use the MacPorts <command>portindex</command> command in the local
127        repository's directory to install it into the
128        <filename>Portindex</filename>.</para>
129
130        <programlisting>%% <userinput>cd /Users/joebob/ports</userinput>
131%% <userinput>portindex</userinput></programlisting>
132
133        <screen>Creating software index in /Users/joebob/ports
134Adding port games/bestevergame
135
136Total number of ports parsed:   1
137Ports successfully parsed:      1       
138Ports failed:                   0</screen>
139      </listitem>
140    </orderedlist>
141
142    <para>Once the local port is added to the <filename>Portindex</filename>,
143    it becomes available for searching or installation as with any other
144    <filename>Portfile</filename> in the MacPorts tree as shown.</para>
145
146    <programlisting><prompt>%%</prompt> <userinput>port search bestever</userinput></programlisting>
147
148    <screen>bestevergame   games/bestevergame 1.1   The Best Ever Game</screen>
149  </section>
150
151  <section>
152    <title>Creating a Portfile</title>
153
154    <para>Here we list the individual <filename>Portfile</filename> components
155    for an application that conforms to the the standard <command>
156    configure</command>, <command>make</command>, and <command>make
157    install</command> steps of most open source application installs.</para>
158
159    <orderedlist>
160      <listitem>
161        <para>Subversion ID tag line</para>
162
163        <para>The first line of a new <filename>Portfile</filename> must be
164        set as shown. When a port is committed to subversion, ID tags are
165        expanded to include the last person to commit and the commit
166        time.</para>
167
168        <programlisting># $Id$</programlisting>
169      </listitem>
170
171      <listitem>
172        <para>PortSystem line</para>
173
174        <para>This statement is required for all ports.</para>
175
176        <programlisting>PortSystem        1.0</programlisting>
177      </listitem>
178
179      <listitem>
180        <para>Port name</para>
181
182        <programlisting>name              rrdtool</programlisting>
183      </listitem>
184
185      <listitem>
186        <para>Port version</para>
187
188        <programlisting>version           1.2.23</programlisting>
189      </listitem>
190
191      <listitem>
192        <para>Port categories</para>
193
194        <para>A port may belong to more than one category, but the first
195        (primary) category should match the directory name in the ports tree
196        where the <filename>Portfile</filename> is to reside.</para>
197
198        <programlisting>categories        net</programlisting>
199      </listitem>
200
201      <listitem>
202        <para>Port maintainers</para>
203
204        <para>A port's maintainer is who takes responsibility for the port;
205        ports that are not maintained and fair game to be modified by any
206        committer use <email>nomaintainer@macports.org</email>.</para>
207
208        <programlisting>maintainers       joebob@macports.org</programlisting>
209      </listitem>
210
211      <listitem>
212        <para>Port description</para>
213
214        <programlisting>description       Round Robin Database</programlisting>
215      </listitem>
216
217      <listitem>
218        <para>Port long_description</para>
219
220        <programlisting>long_description  RRDtool is a system to store and display time-series data</programlisting>
221      </listitem>
222
223      <listitem>
224        <para>A port's application homepage</para>
225
226        <programlisting>homepage          http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/</programlisting>
227      </listitem>
228
229      <listitem>
230        <para>Platform statement</para>
231
232        <programlisting>platforms         darwin</programlisting>
233      </listitem>
234
235      <listitem>
236        <para>A port's download URLs</para>
237
238        <programlisting>master_sites      http://oss.oetiker.ch/rrdtool/pub/ \
239                  ftp://ftp.pucpr.br/rrdtool/</programlisting>
240      </listitem>
241
242      <listitem>
243        <para>Port checksums</para>
244
245        <para>The checksums specified in a <filename>Portfile</filename> are
246        checked with the fetched tarball for security.</para>
247
248        <programlisting>checksums         md5 dafa161bc9c61e57636a6085c87c1fe8</programlisting>
249      </listitem>
250
251      <listitem>
252        <para>Port dependencies</para>
253
254        <para>A port's dependencies are ports that must be installed before
255        another port is installed.</para>
256
257        <programlisting>depends_lib       port:perl5.8 \
258                  port:tcl \
259                  port:zlib</programlisting>
260      </listitem>
261
262      <listitem>
263        <para>Port configure arguments (optional)</para>
264
265        <programlisting>configure.args    --prefix=${prefix} \
266                  --enable-perl-site-install \
267                  --mandir=${prefix}/share/man</programlisting>
268      </listitem>
269    </orderedlist>
270  </section>
271
272  <section>
273    <title>Example Portfiles</title>
274
275    <para>In this section we take a look at a complete simple Portfile, and
276    then pre- and post- phase definitions to augment and override the MacPorts
277    default phases.</para>
278
279    <section>
280      <title>A Basic Portfile</title>
281
282      <para></para>
283
284      <programlisting># Id$
285PortSystem      1.0
286
287name                    rrdtool
288version                 1.2.23
289categories              net
290maintainers             joebob@macports.org
291description             Round Robin Database
292long_description        RRDtool is a system to store and display time-series data
293homepage                http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/
294platforms               darwin
295master_sites            http://oss.oetiker.ch/rrdtool/pub/ \
296                        ftp://ftp.pucpr.br/rrdtool/
297
298checksums               md5 dafa161bc9c61e57636a6085c87c1fe8
299
300depends_lib             port:perl5.8 \
301                        port:tcl \
302                        port:zlib
303
304configure.args          --prefix=${prefix} \
305                        --enable-perl-site-install \
306                        --mandir=${prefix}/share/man</programlisting>
307    </section>
308
309    <section>
310      <title>Portfile Using Pre- / Post- Phases</title>
311
312      <para>To augment a port's installation phase, and not override it, you
313      may use pre- and post- installation phases as shown in this
314      example.</para>
315
316      <programlisting>post-destroot {
317# Install example files not installed by the Makefile
318        file mkdir ${destroot}${prefix}/share/doc/${name}/examples
319        file copy ${worksrcpath}/examples/ \
320             ${destroot}${prefix}/share/doc/${name}/examples
321}</programlisting>
322    </section>
323
324    <section>
325      <title>Portfile that Overrides Default Phases</title>
326
327      <para>To override the automatic MacPorts installation phase processing,
328      define your own installation phases as shown in this example.</para>
329
330      <programlisting>destroot {
331        xinstall -m 755 -d ${destroot}${prefix}/bin
332        xinstall -m 755 ${worksrcpath}/cdpr ${destroot}${prefix}/bin
333}</programlisting>
334    </section>
335
336    <section>
337      <title>Portfile Using a StartupItem</title>
338
339      <para>Startupitems may be placed in the global section of a
340      Portfile.</para>
341
342      <programlisting>startupitem.create      yes
343startupitem.name        nmicmpd
344startupitem.executable  "${prefix}/bin/nmicmpd"</programlisting>
345
346      <para>Startupitems keywords may also be used within a variant definition
347      to make their installation conditional.</para>
348
349      <programlisting>variant server {
350    startupitem.create    yes
351    startupitem.start "${prefix}/share/${name}/vm-pop3d.init start"
352    startupitem.stop "${prefix}/share/${name}/vm-pop3d.init stop"
353}</programlisting>
354    </section>
355  </section>
356
357  <section>
358    <title>Port Variants</title>
359
360    <para>Variants are a way for port authors to provide options that may be
361    invoked at install time. They are declared in the global section of a
362    <filename>Portfile</filename> using the "variant" keyword and may provide
363    a description.</para>
364
365    <section>
366      <title>Variants to Modify Options</title>
367
368      <para>The most common use for a variant is to add or remove
369      dependencies, configure arguments, and build arguments from the global
370      <filename>Portfile</filename> section. Here is an example of a port
371      providing four variants that add additional configure arguments to a
372      port. See "Variants" in the Portfile Reference section for full
373      information.</para>
374
375      <programlisting>variant pop     { configure.args-append --enable-pop }
376variant imap    { configure.args-append --enable-imap }
377variant ssl     { configure.args-append --with-ssl }
378variant debug   { configure.args-append --enable-debug }</programlisting>
379
380      <para>In the example variant declaration, the configure argument
381      <literal>--without-x</literal> is removed and a numner of others are
382      appended.</para>
383
384      <programlisting>variant x11 description {Builds port as an X11 program with Lucid widgets} {
385    configure.args-delete   --without-x
386    configure.args-append   --with-x-toolkit=lucid \
387                            --without-carbon \
388                            --with-xpm \
389                            --with-jpeg \
390                            --with-tiff \
391                            --with-gif \
392                            --with-png
393    depends_lib-append      lib:libX11:XFree86 \
394                            lib:libXpm:XFree86 \
395                            port:jpeg \
396                            port:tiff \
397                            port:libungif \
398                            port:libpng
399}</programlisting>
400    </section>
401
402    <section>
403      <title>Variant Actions in a Phase</title>
404
405      <para>If a variant requires options in addition to those provided by
406      keywords using -append and/or -delete, in other words, any actions that
407      would normally take place within a port installation phase, do not try
408      to do this within the variant declaration. Rather, modify the behavior
409      of any affected phases when the variant is invoked using the
410      variant_isset keyword.</para>
411
412      <programlisting>post-destroot {
413    xinstall -m 755 -d ${destroot}${prefix}/etc/
414    xinstall ${worksrcpath}/examples/foo.conf \
415        ${destroot}${prefix}/etc/
416
417    if {[variant_isset] carbon]} {
418        delete ${destroot}${prefix}/bin/emacs
419        delete ${destroot}${prefix}/bin/emacs-${version}
420    }
421}</programlisting>
422    </section>
423
424    <section>
425      <title>Default Variants</title>
426
427      <para>Variants are used to specify actions that lie outside the core
428      functions of an application or port, but there may be some cases where
429      you wish to specify these non-core functions by default. For this
430      purpose you may use the keyword default_variants.</para>
431
432      <programlisting>default_variants +foo +bar</programlisting>
433
434      <note>
435        <para>The default_variant keyword may only be used in the global
436        <filename>Portfile</filename> section.</para>
437      </note>
438    </section>
439  </section>
440
441  <section>
442    <title>Creating Patch Files</title>
443
444    <para>Patch files are files created with the Unix command
445    <command>diff</command> that are applied using the command
446    <command>patch</command> to modify text files to fix bugs or extend
447    functionality.</para>
448
449    <section>
450      <title>Portfile Patches</title>
451
452      <para>If you wish to contribute modifications or fixes to a
453      <filename>Portfile</filename>, you should do so in the form of a
454      patch.</para>
455
456      <orderedlist>
457        <listitem>
458          <para>Make a copy of the <filename>Portfile</filename> you wish to
459          modify; both files must be in the same directory, though it may be
460          any directory.</para>
461
462          <programlisting><prompt>%%</prompt> <userinput>cp Portfile Portfile.org</userinput></programlisting>
463        </listitem>
464
465        <listitem>
466          <para>Edit the file to make it as you want it to be after it is
467          fetched.</para>
468        </listitem>
469
470        <listitem>
471          <para>Now use the Unix command <command>diff -u </command>to create
472          a "unified" diff patch file.</para>
473
474          <programlisting><prompt>%%</prompt> <userinput>diff -u Portfile.org Portfile &gt; Portfile.diff</userinput></programlisting>
475        </listitem>
476
477        <listitem>
478          <para>A patch file that is a "unified" diff file is the easiest to
479          interpret by humans and this type should always be used for ports.
480          The <filename>Portfile</filename> patch below will change the
481          version and checksums when applied.</para>
482
483          <programlisting>--- Portfile.org        2007-07-25 18:52:12.000000000 -0700
484+++ Portfile    2007-07-25 18:53:35.000000000 -0700
485@@ -2,7 +2,7 @@
486 PortSystem             1.0
487 
488 name                   nefu
489-version                        1.4.0
490+version                        1.3.0
491 categories             net
492 maintainers            nomaintainer@macports.org
493 description            A network monitoring daemon.
494@@ -13,9 +13,9 @@
495
496 homepage               http://rsug.itd.umich.edu/software/${name}
497
498 master_sites           ${homepage}/files/
499-checksums              md5 f0953b21cdb5eb327e40d4b215110b71 \
500+checksums              md5 01532e67a596bfff6a54aa36face26ae \
501 extract.suffix  .tgz
502 platforms              darwin
503</programlisting>
504        </listitem>
505      </orderedlist>
506
507      <para>Now you may attach the <filename>Portfile.diff</filename> to a
508      MacPorts Trac ticket for the port author to evaluate.</para>
509    </section>
510
511    <section>
512      <title>Source Code Patches</title>
513
514      <para>Necessary or useful patches to application source code should be
515      sent to the application developer (not the port author) so the
516      modifications may be included in the next version, and the port patch
517      eventually removed.</para>
518
519      <orderedlist>
520        <listitem>
521          <para>Locate the file you wish to patch in its original location
522          within the unpacked source directory and make a duplicate of
523          it.</para>
524
525          <programlisting><prompt>%%</prompt> <userinput>cd foo-1.34/src</userinput>
526<prompt>%%</prompt> <userinput>cp Makefile.in Makefile.in.org</userinput></programlisting>
527        </listitem>
528
529        <listitem>
530          <para>Edit the file to make it as you want it to be after it is
531          fetched.</para>
532        </listitem>
533
534        <listitem>
535          <para>Now use the Unix command <command>diff -u</command> to create
536          a "unified" diff patch file.</para>
537
538          <programlisting><prompt>%%</prompt> <userinput>cd foo-1.34</userinput>
539<prompt>%%</prompt> <userinput>diff -u Makefile.in.org Makefile.in &gt; patch-Makefile.in</userinput></programlisting>
540
541          <note>
542            <para>You must execute the <command>diff</command> command in the
543            top-level of the unpacked source code. Otherwise the
544            <command>patch</command> command will look for the file to be
545            patched in the wrong place and fail.</para>
546          </note>
547        </listitem>
548
549        <listitem>
550          <para>A patch file that is a "unified" diff file is the easiest to
551          interpret by humans and this type should always be used for ports.
552          See the example below where a patch adds <varname>DESTDIR</varname>
553          support to a <filename>Makefile.in</filename> file.</para>
554
555          <programlisting>--- Makefile.in.org   2007-06-01 16:30:47.000000000 -0700
556+++ Makefile.in       2007-06-20 10:10:59.000000000 -0700
557@@ -131,23 +131,23 @@
558        $(INSTALL_DATA)/gdata $(INSTALL_DATA)/perl
559
560 install-lib:
561-       -mkdir -p $(INSTALL_LIB)
562+       -mkdir -p $(DESTDIR)$(INSTALL_LIB)
563        $(PERL) tools/install_lib -s src -l $(INSTALL_LIB) $(LIBS)
564-       cp $(TEXT) $(INSTALL_LIB)/
565+       cp $(TEXT) $(DESTDIR)$(INSTALL_LIB)/</programlisting>
566        </listitem>
567
568        <listitem>
569          <para>Now you may place the patch
570          <filename>patch-Makefile.in</filename> in the path ${portpath}/files
571          of a local repository (or commit it to subversion) and use it in a
572          port using the patchfiles keyword.</para>
573
574          <programlisting>patchfiles              patch-Makefile.in</programlisting>
575        </listitem>
576      </orderedlist>
577    </section>
578  </section>
579</chapter>
Note: See TracBrowser for help on using the repository browser.