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

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

Remove the redundant explanation of maintainer email address hiding; the explanation
is in the Portfile Reference section where it is more appropriate, so just refer to it.

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