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

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

Closes #12511. Add instructions on how to hide email addresses. Add some categories to
"Portfile Best Practices".

File size: 23.1 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    extensions 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 a person who takes responsibility for
205        keeping the port up-to-date. To avoid spam, email addresses are often
206        hidden. To hide email addresses from spambots, use these
207        conventions.</para>
208
209        <itemizedlist>
210          <listitem>
211            <para>For addresses in domain @macports.org, simply omit the
212            domain name.</para>
213          </listitem>
214
215          <listitem>
216            <para>For addresses in other domains, say
217            <email>samj@somedomain.org</email>, use the convention
218            somedomain.org:samj to specify the address.</para>
219          </listitem>
220        </itemizedlist>
221
222        <para>In the example below, the email addresses
223        <email>joebob@macports.org</email> and
224        <email>julesverne@somedomain.org</email> are hidden using this
225        convention.</para>
226
227        <programlisting>maintainers       joebob \
228                  somedomain.org:julesverne</programlisting>
229
230        <note>
231          <para>The address <email>nomaintainer@macports.org</email>
232          designates a port that may be modified by any committer.</para>
233        </note>
234      </listitem>
235
236      <listitem>
237        <para>Port description</para>
238
239        <programlisting>description       Round Robin Database</programlisting>
240      </listitem>
241
242      <listitem>
243        <para>Port long_description</para>
244
245        <programlisting>long_description  RRDtool is a system to store and display time-series data</programlisting>
246      </listitem>
247
248      <listitem>
249        <para>A port's application homepage</para>
250
251        <programlisting>homepage          http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/</programlisting>
252      </listitem>
253
254      <listitem>
255        <para>Platform statement</para>
256
257        <programlisting>platforms         darwin</programlisting>
258      </listitem>
259
260      <listitem>
261        <para>A port's download URLs</para>
262
263        <programlisting>master_sites      http://oss.oetiker.ch/rrdtool/pub/ \
264                  ftp://ftp.pucpr.br/rrdtool/</programlisting>
265      </listitem>
266
267      <listitem>
268        <para>Port checksums</para>
269
270        <para>The checksums specified in a <filename>Portfile</filename> are
271        checked with the fetched tarball for security.</para>
272
273        <programlisting>checksums         md5 dafa161bc9c61e57636a6085c87c1fe8</programlisting>
274      </listitem>
275
276      <listitem>
277        <para>Port dependencies</para>
278
279        <para>A port's dependencies are ports that must be installed before
280        another port is installed.</para>
281
282        <programlisting>depends_lib       port:perl5.8 \
283                  port:tcl \
284                  port:zlib</programlisting>
285      </listitem>
286
287      <listitem>
288        <para>Port configure arguments (optional)</para>
289
290        <programlisting>configure.args    --prefix=${prefix} \
291                  --enable-perl-site-install \
292                  --mandir=${prefix}/share/man</programlisting>
293      </listitem>
294    </orderedlist>
295  </section>
296
297  <section>
298    <title>Example Portfiles</title>
299
300    <para>In this section we take a look at a complete simple Portfile, and
301    then pre- and post- phase definitions to augment and override the MacPorts
302    default phases.</para>
303
304    <section>
305      <title>A Basic Portfile</title>
306
307      <programlisting># Id$
308PortSystem      1.0
309
310name                    rrdtool
311version                 1.2.23
312categories              net
313maintainers             joebob
314description             Round Robin Database
315long_description        RRDtool is a system to store and display time-series data
316homepage                http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/
317platforms               darwin
318master_sites            http://oss.oetiker.ch/rrdtool/pub/ \
319                        ftp://ftp.pucpr.br/rrdtool/
320
321checksums               md5 dafa161bc9c61e57636a6085c87c1fe8
322
323depends_lib             port:perl5.8 \
324                        port:tcl \
325                        port:zlib
326
327configure.args          --prefix=${prefix} \
328                        --enable-perl-site-install \
329                        --mandir=${prefix}/share/man</programlisting>
330    </section>
331
332    <section>
333      <title>Portfile Using Pre- / Post- Phases</title>
334
335      <para>To augment a port's installation phase, and not override it, you
336      may use pre- and post- installation phases as shown in this
337      example.</para>
338
339      <programlisting>post-destroot {
340# Install example files not installed by the Makefile
341        file mkdir ${destroot}${prefix}/share/doc/${name}/examples
342        file copy ${worksrcpath}/examples/ \
343             ${destroot}${prefix}/share/doc/${name}/examples
344}</programlisting>
345    </section>
346
347    <section>
348      <title>Portfile that Overrides Default Phases</title>
349
350      <para>To override the automatic MacPorts installation phase processing,
351      define your own installation phases as shown in this example.</para>
352
353      <programlisting>destroot {
354        xinstall -m 755 -d ${destroot}${prefix}/bin
355        xinstall -m 755 ${worksrcpath}/cdpr ${destroot}${prefix}/bin
356}</programlisting>
357    </section>
358
359    <section>
360      <title>Portfile Using a StartupItem</title>
361
362      <para>Startupitems may be placed in the global section of a
363      Portfile.</para>
364
365      <programlisting>startupitem.create      yes
366startupitem.name        nmicmpd
367startupitem.executable  "${prefix}/bin/nmicmpd"</programlisting>
368
369      <para>Startupitems keywords may also be used within a variant definition
370      to make their installation conditional.</para>
371
372      <programlisting>variant server {
373    startupitem.create    yes
374    startupitem.start "${prefix}/share/${name}/vm-pop3d.init start"
375    startupitem.stop "${prefix}/share/${name}/vm-pop3d.init stop"
376}</programlisting>
377    </section>
378  </section>
379
380  <section>
381    <title>Port Variants</title>
382
383    <para>Variants are a way for port authors to provide options that may be
384    invoked at install time. They are declared in the global section of a
385    <filename>Portfile</filename> using the "variant" keyword and may provide
386    a description.</para>
387
388    <section>
389      <title>Variants to Modify Options</title>
390
391      <para>The most common use for a variant is to add or remove
392      dependencies, configure arguments, and build arguments from the global
393      <filename>Portfile</filename> section. Here is an example of a port
394      providing four variants that add additional configure arguments to a
395      port. See "Variants" in the Portfile Reference section for full
396      information.</para>
397
398      <programlisting>variant pop     { configure.args-append --enable-pop }
399variant imap    { configure.args-append --enable-imap }
400variant ssl     { configure.args-append --with-ssl }
401variant debug   { configure.args-append --enable-debug }</programlisting>
402
403      <para>In the example variant declaration, the configure argument
404      <literal>--without-x</literal> is removed and a numner of others are
405      appended.</para>
406
407      <programlisting>variant x11 description {Builds port as an X11 program with Lucid widgets} {
408    configure.args-delete   --without-x
409    configure.args-append   --with-x-toolkit=lucid \
410                            --without-carbon \
411                            --with-xpm \
412                            --with-jpeg \
413                            --with-tiff \
414                            --with-gif \
415                            --with-png
416    depends_lib-append      lib:libX11:XFree86 \
417                            lib:libXpm:XFree86 \
418                            port:jpeg \
419                            port:tiff \
420                            port:libungif \
421                            port:libpng
422}</programlisting>
423    </section>
424
425    <section>
426      <title>Variant Actions in a Phase</title>
427
428      <para>If a variant requires options in addition to those provided by
429      keywords using -append and/or -delete, in other words, any actions that
430      would normally take place within a port installation phase, do not try
431      to do this within the variant declaration. Rather, modify the behavior
432      of any affected phases when the variant is invoked using the
433      variant_isset keyword.</para>
434
435      <programlisting>post-destroot {
436    xinstall -m 755 -d ${destroot}${prefix}/etc/
437    xinstall ${worksrcpath}/examples/foo.conf \
438        ${destroot}${prefix}/etc/
439
440    if {[variant_isset] carbon]} {
441        delete ${destroot}${prefix}/bin/emacs
442        delete ${destroot}${prefix}/bin/emacs-${version}
443    }
444}</programlisting>
445    </section>
446
447    <section>
448      <title>Default Variants</title>
449
450      <para>Variants are used to specify actions that lie outside the core
451      functions of an application or port, but there may be some cases where
452      you wish to specify these non-core functions by default. For this
453      purpose you may use the keyword default_variants.</para>
454
455      <programlisting>default_variants +foo +bar</programlisting>
456
457      <note>
458        <para>The default_variant keyword may only be used in the global
459        <filename>Portfile</filename> section.</para>
460      </note>
461    </section>
462  </section>
463
464  <section>
465    <title>Patch Files</title>
466
467    <para>Patch files are files created with the Unix command
468    <command>diff</command> that are applied using the command
469    <command>patch</command> to modify text files to fix bugs or extend
470    functionality.</para>
471
472    <section>
473      <title>Creating Portfile Patches</title>
474
475      <para>If you wish to contribute modifications or fixes to a
476      <filename>Portfile</filename>, you should do so in the form of a
477      patch.</para>
478
479      <orderedlist>
480        <listitem>
481          <para>Make a copy of the <filename>Portfile</filename> you wish to
482          modify; both files must be in the same directory, though it may be
483          any directory.</para>
484
485          <programlisting><prompt>%%</prompt> <userinput>cp Portfile Portfile.org</userinput></programlisting>
486        </listitem>
487
488        <listitem>
489          <para>Edit the file to make it as you want it to be after it is
490          fetched.</para>
491        </listitem>
492
493        <listitem>
494          <para>Now use the Unix command <command>diff -u </command>to create
495          a "unified" diff patch file.</para>
496
497          <programlisting><prompt>%%</prompt> <userinput>diff -u Portfile.org Portfile &gt; Portfile.diff</userinput></programlisting>
498        </listitem>
499
500        <listitem>
501          <para>A patch file that is a "unified" diff file is the easiest to
502          interpret by humans and this type should always be used for ports.
503          The <filename>Portfile</filename> patch below will change the
504          version and checksums when applied.</para>
505
506          <programlisting>--- Portfile.org        2007-07-25 18:52:12.000000000 -0700
507+++ Portfile    2007-07-25 18:53:35.000000000 -0700
508@@ -2,7 +2,7 @@
509 PortSystem             1.0
510 
511 name                   nefu
512-version                        1.4.0
513+version                        1.3.0
514 categories             net
515 maintainers            nomaintainer@macports.org
516 description            A network monitoring daemon.
517@@ -13,9 +13,9 @@
518
519 homepage               http://rsug.itd.umich.edu/software/${name}
520
521 master_sites           ${homepage}/files/
522-checksums              md5 f0953b21cdb5eb327e40d4b215110b71 \
523+checksums              md5 01532e67a596bfff6a54aa36face26ae \
524 extract.suffix  .tgz
525 platforms              darwin
526</programlisting>
527        </listitem>
528      </orderedlist>
529
530      <para>Now you may attach the <filename>Portfile.diff</filename> to a
531      MacPorts Trac ticket for the port author to evaluate.</para>
532    </section>
533
534    <section>
535      <title>Creating Source Code Patches</title>
536
537      <para>Necessary or useful patches to application source code should be
538      sent to the application developer (not the port author) so the
539      modifications may be included in the next version, and the port patch
540      eventually removed.</para>
541
542      <orderedlist>
543        <listitem>
544          <para>Locate the file you wish to patch in its original location
545          within the unpacked source directory and make a duplicate of
546          it.</para>
547
548          <programlisting><prompt>%%</prompt> <userinput>cd foo-1.34/src</userinput>
549<prompt>%%</prompt> <userinput>cp Makefile.in Makefile.in.org</userinput></programlisting>
550        </listitem>
551
552        <listitem>
553          <para>Edit the file to make it as you want it to be after it is
554          fetched.</para>
555        </listitem>
556
557        <listitem>
558          <para>Now use the Unix command <command>diff -u</command> to create
559          a "unified" diff patch file.</para>
560
561          <programlisting><prompt>%%</prompt> <userinput>cd foo-1.34</userinput>
562<prompt>%%</prompt> <userinput>diff -u Makefile.in.org Makefile.in &gt; patch-Makefile.in</userinput></programlisting>
563
564          <note>
565            <para>You must execute the <command>diff</command> command in the
566            top-level of the unpacked source code. Otherwise the
567            <command>patch</command> command will look for the file to be
568            patched in the wrong place and fail.</para>
569          </note>
570        </listitem>
571
572        <listitem>
573          <para>A patch file that is a "unified" diff file is the easiest to
574          interpret by humans and this type should always be used for ports.
575          See the example below where a patch adds <varname>DESTDIR</varname>
576          support to a <filename>Makefile.in</filename> file.</para>
577
578          <programlisting>--- Makefile.in.org   2007-06-01 16:30:47.000000000 -0700
579+++ Makefile.in       2007-06-20 10:10:59.000000000 -0700
580@@ -131,23 +131,23 @@
581        $(INSTALL_DATA)/gdata $(INSTALL_DATA)/perl
582
583 install-lib:
584-       -mkdir -p $(INSTALL_LIB)
585+       -mkdir -p $(DESTDIR)$(INSTALL_LIB)
586        $(PERL) tools/install_lib -s src -l $(INSTALL_LIB) $(LIBS)
587-       cp $(TEXT) $(INSTALL_LIB)/
588+       cp $(TEXT) $(DESTDIR)$(INSTALL_LIB)/</programlisting>
589        </listitem>
590
591        <listitem>
592          <para>Now you may place the patch
593          <filename>patch-Makefile.in</filename> in the path ${portpath}/files
594          of a local repository (or commit it to subversion) and use it in a
595          port using the patchfiles keyword.</para>
596
597          <programlisting>patchfiles              patch-Makefile.in</programlisting>
598        </listitem>
599      </orderedlist>
600    </section>
601
602    <section>
603      <title>Manually Applying Patches</title>
604
605      <para>Though MacPorts applies patch files automatically, you may want to
606      know how to apply patch files manually if you want to apply uncommitted
607      Portfile patches or other similar uses.</para>
608
609      <orderedlist>
610        <listitem>
611          <para>Change to the directory containing the file to be patched. In
612          this example, we'll apply a <filename>Portfile</filename> patch to
613          the postfix port.</para>
614
615          <programlisting><prompt>%%</prompt> <userinput>cd /opt/local/var/macports/sources/rsync.macports.org/release/ports/mail/postfix</userinput></programlisting>
616        </listitem>
617
618        <listitem>
619          <para>Now apply the patch that is on the current user's desktop. The
620          patchfile knows the filename of the file to be patched.</para>
621
622          <programlisting><prompt>%%</prompt> <userinput>patch &lt; ~/Desktop/Portfile.diff</userinput></programlisting>
623
624          <screen>patching file Portfile</screen>
625        </listitem>
626      </orderedlist>
627    </section>
628  </section>
629
630  <section>
631    <title>Portfile Best Practices</title>
632
633    <para>This section contains practical guidelines for creating Portfiles
634    that install smoothly and provide consistency between ports.</para>
635
636    <section>
637      <title>Don't Overwrite Config Files</title>
638
639      <para></para>
640    </section>
641
642    <section>
643      <title>Install Docs and Examples</title>
644
645      <para></para>
646    </section>
647
648    <section>
649      <title>Provide User Messages</title>
650
651      <para></para>
652    </section>
653  </section>
654</chapter>
Note: See TracBrowser for help on using the repository browser.