source: trunk/doc-new/guide/xml/portfiledev.xml @ 111935

Last change on this file since 111935 was 111935, checked in by mk@…, 7 years ago

Guide: add a note concerning correct syntax for port group obsolete (Thanks to Clemens.)

File size: 43.5 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 id="development">
5  <title>Portfile Development</title>
6
7  <para>This chapter covers a brief introduction to Portfiles, how to create a
8  local Portfile repository for development, and creating Portfiles.</para>
9
10  <section id="development.introduction">
11    <title>Portfile Introduction</title>
12
13    <para>A MacPorts Portfile is a <ulink
14    url="http://en.wikipedia.org/wiki/Tcl">TCL</ulink> script that usually
15    contains only the simple keyword/value combinations and Tcl extensions as
16    described in the <link linkend="reference">Portfile Reference</link>
17    chapter, though it may also contain arbitrary TCL code. Every port has a
18    corresponding Portfile, but Portfiles do not completely define a port's
19    installation behavior since MacPorts base has default port installation
20    characteristics coded within it. Therefore Portfiles need only specify
21    required options, though some ports may require non-default
22    options.</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 Portfile
27    phase declaration(s), you should know how to identify the
28    <quote>global</quote> section of a Portfile. Any statements not contained
29    within a phase declaration, no matter where they are located in a Portfile,
30    are said to be in the global section of the Portfile; therefore the global
31    section need not be contiguous. Likewise, to remove statements from the
32    global section they must be placed within a phase declaration.</para>
33
34    <para>The main phases you need to be aware of when making a Portfile are
35    these:</para>
36
37    <itemizedlist>
38      <listitem>
39        <para>Fetch</para>
40      </listitem>
41
42      <listitem>
43        <para>Extract</para>
44      </listitem>
45
46      <listitem>
47        <para>Patch</para>
48      </listitem>
49
50      <listitem>
51        <para>Configure</para>
52      </listitem>
53
54      <listitem>
55        <para>Build</para>
56      </listitem>
57
58      <listitem>
59        <para>Destroot</para>
60      </listitem>
61    </itemizedlist>
62
63    <para>The default installation phase behavior performed by the MacPorts
64    base works fine for applications that use the standard
65    <command>configure</command>, <command>make</command>, and <command>make
66    install</command> steps, which conform to phases configure, build, and
67    destroot respectively. For applications that do not conform to this
68    standard behavior, any installation phase may be augmented using <link
69    linkend="development.examples.augment">pre- and/or post- phases</link>, or
70    even <link linkend="development.examples.override">overridden</link> or
71    <link linkend="development.examples.eliminate">eliminated</link>. See
72    <link linkend="development.examples">Example Portfiles</link>
73    below.</para>
74
75    <note>
76      <para>For a detailed description of all port phases, see the <link
77      linkend="reference.phases">Portfile Reference</link> chapter.</para>
78    </note>
79  </section>
80
81  <section id="development.creating-portfile">
82    <title>Creating a Portfile</title>
83
84    <para>Here we list the individual Portfile components for an application
85    that conforms to the standard <command>configure</command>,
86    <command>make</command>, and <command>make install</command> steps of most
87    open source application installs.</para>
88
89    <orderedlist>
90      <listitem>
91        <para>Modeline</para>
92
93        <para>This should be the first line of a Portfile. It sets the correct
94        editing options for vim and emacs. See <link
95        linkend="development.practices.portstyle">Port Style</link> for more
96        information. Its use is optional and up to the port maintainer.</para>
97
98        <programlisting># -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4</programlisting>
99      </listitem>
100
101      <listitem>
102        <para>Subversion ID tag line</para>
103
104        <para>This must be a Portfile's second line (or the first, if a
105        modeline is not used). When a port is committed to the repository, ID
106        tags are expanded to include the filename and the revision number,
107        date and time, and author of the last commit.</para>
108
109        <programlisting># $Id$</programlisting>
110      </listitem>
111
112      <listitem>
113        <para>PortSystem line</para>
114
115        <para>This statement is required for all ports.</para>
116
117        <programlisting>PortSystem          1.0</programlisting>
118      </listitem>
119
120      <listitem>
121        <para>Port name</para>
122
123        <programlisting>name                rrdtool</programlisting>
124      </listitem>
125
126      <listitem>
127        <para>Port version</para>
128
129        <programlisting>version             1.2.23</programlisting>
130      </listitem>
131
132      <listitem>
133        <para>Port categories</para>
134
135        <para>A port may belong to more than one category, but the first
136        (primary) category should match the directory name in the ports tree
137        where the Portfile is to reside.</para>
138
139        <programlisting>categories          net</programlisting>
140      </listitem>
141
142      <listitem>
143        <para>Platform statement</para>
144
145        <programlisting>platforms           darwin</programlisting>
146      </listitem>
147
148<!--
149      <listitem>
150          <para>Port license</para>
151
152        <para>A port's license indicates the class of license employed by the
153        owner. Setting this signals the main intentions of the license with
154        respect to binary and source distribution. It is presently only for
155        informational purposes and MacPorts does not distribute binaries.</para>
156
157        <itemizedlist>
158          <listitem>
159            <para><varname>GPL</varname> – signifies the requirements of GNU
160            General Public    License; the source be available in the same place
161            as the binary.</para>
162
163            <para><varname>LGPL</varname> – use this for the GNU Lesser General
164            Public License,    which mandates that    the source and binary are
165            available in the same place.</para>
166
167            <para><varname>BSD</varname> – covering the original and new BSD
168            license as well as MIT and Apache; these licenses allow for optional
169            inclusion of source code.</para>
170
171            <para><varname>Artistic</varname> – aptly named to indicate the
172            Artistic license and derivatives.</para>
173
174            <para><varname>Artistic-GPL</varname> – dual-licensed under the
175            Artistic and GPL licenses.</para>
176
177            <para><varname>/GFDL</varname> and <varname>/LDP</varname> – these
178            suffixes indicate that the documentation provided is under the GNU
179            Free Documentation License or the Linux Documentation Project</para>
180
181            <para><varname>RESTRICT</varname> – when the licenses are
182            restrictive.</para>
183
184            <para><varname>RESTRICT-EYESONLY</varname> – if the license does not
185            permit distribution.</para>
186
187            <para><varname>PUBLIC</varname> – the code is not copyrighted:
188            anyone can do anything</para>
189          </listitem>
190        </itemizedlist>
191      </listitem>
192-->
193      <listitem>
194        <para>Port maintainers</para>
195
196        <para>A port's maintainers are the people who have agreed to take
197        responsibility for keeping the port up-to-date. The
198        <literal>maintainers</literal> keyword lists the maintainers' email
199        addresses, preferrably in the obfuscated form which hides them
200        from spambots. For more, see the full explanation of the <link
201        linkend="reference.keywords.maintainers">maintainers keyword</link> in
202        the <link linkend="reference.keywords">Global Keywords</link> section
203        of the <link linkend="reference">Portfile Reference</link>
204        chapter.</para>
205
206        <programlisting>maintainers         jdoe \
207                    example.org:julesverne</programlisting>
208      </listitem>
209
210      <listitem>
211        <para>Port description</para>
212
213        <programlisting>description         Round Robin Database</programlisting>
214      </listitem>
215
216      <listitem>
217        <para>Port long_description</para>
218
219        <programlisting>long_description    RRDtool is a system to store and display time-series \
220                    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>A port's download URLs</para>
231
232        <programlisting>master_sites        http://oss.oetiker.ch/rrdtool/pub/ \
233                    ftp://ftp.pucpr.br/rrdtool/</programlisting>
234      </listitem>
235
236      <listitem>
237        <para>Port checksums</para>
238
239        <para>The checksums specified in a Portfile are checked with the
240        fetched tarball for security. For the best security, use rmd160
241        and sha256 checksum types.</para>
242
243        <programlisting>checksums               rmd160  7bbfce4fecc2a8e1ca081169e70c1a298ab1b75a \
244                        sha256  2829fcb7393bac85925090b286b1f9c3cd3fbbf8e7f35796ef4131322509aa53</programlisting>
245
246        <para>To find the correct checksums for a port's distribution file,
247        follow this example:</para>
248
249        <programlisting><prompt>%%</prompt> <userinput>openssl rmd160 rrdtool-1.2.23.tar.gz</userinput>
250<prompt>%%</prompt> <userinput>openssl sha256 rrdtool-1.2.23.tar.gz</userinput></programlisting>
251
252        <screen>RIPEMD160( ... rrdtool-1.2.23.tar.gz)= 7bbfce4fecc2a8e1ca081169e70c1a298ab1b75a
253
254SHA256( ... rrdtool-1.2.23.tar.gz)= 2829fcb7393bac85925090b286b1f9c3cd3fbbf8e7f35796ef4131322509aa53</screen>
255      </listitem>
256
257      <listitem>
258        <para>Port dependencies</para>
259
260        <para>A port's dependencies are ports that must be installed before
261        another port is installed.</para>
262
263        <programlisting>depends_lib         port:perl5.8 \
264                    port:tcl \
265                    port:zlib</programlisting>
266      </listitem>
267
268      <listitem>
269        <para>Port configure arguments (optional)</para>
270
271        <programlisting>configure.args      --enable-perl-site-install \
272                    --mandir=${prefix}/share/man</programlisting>
273      </listitem>
274    </orderedlist>
275  </section>
276
277  <section id="development.examples">
278    <title>Example Portfiles</title>
279
280    <para>In this section we begin by taking a look at a complete simple
281    Portfile; then we see how to <link
282    linkend="development.examples.augment">augment default phases</link> by
283    defining pre- and post- phases, how to <link
284    linkend="development.examples.override">override default phases</link>,
285    and finally how to <link
286    linkend="development.examples.eliminate">eliminate port
287    phases</link>.</para>
288
289    <section id="development.examples.basic">
290      <title>A Basic Portfile</title>
291
292      <programlisting># $Id$
293
294PortSystem          1.0
295
296name                rrdtool
297version             1.2.23
298categories          net
299platforms           darwin
300license             GPL
301maintainers         julesverne
302description         Round Robin Database
303long_description    RRDtool is a system to store and display time-series data
304homepage            http://people.ee.ethz.ch/~oetiker/webtools/rrdtool/
305master_sites        http://oss.oetiker.ch/rrdtool/pub/ \
306                    ftp://ftp.pucpr.br/rrdtool/
307
308checksums           rmd160  7bbfce4fecc2a8e1ca081169e70c1a298ab1b75a \
309                    sha256  2829fcb7393bac85925090b286b1f9c3cd3fbbf8e7f35796ef4131322509aa53
310
311depends_lib         path:bin/perl:perl5 \
312                    port:tcl \
313                    port:zlib
314
315configure.args      --enable-perl-site-install \
316                    --mandir=${prefix}/share/man</programlisting>
317    </section>
318
319    <section id="development.examples.augment">
320      <title>Augment Phases Using pre- / post-</title>
321
322      <para>To augment a port's installation phase, and not override it, you
323      may use pre- and post- installation phases as shown in this
324      example.</para>
325
326      <programlisting>post-destroot {
327    # Install example files not installed by the Makefile
328    file mkdir ${destroot}${prefix}/share/doc/${name}/examples
329    file copy ${worksrcpath}/examples/ \
330        ${destroot}${prefix}/share/doc/${name}/examples
331}</programlisting>
332    </section>
333
334    <section id="development.examples.override">
335      <title>Overriding Phases</title>
336
337      <para>To override the automatic MacPorts installation phase processing,
338      define your own installation phases as shown in this example.</para>
339
340      <programlisting>destroot {
341    xinstall -m 755 -d ${destroot}${prefix}/share/doc/${name}
342    xinstall -m 755 ${worksrcpath}/README ${destroot}${prefix}/share/doc/${name}
343}</programlisting>
344    </section>
345
346    <section id="development.examples.eliminate">
347      <title>Eliminating Phases</title>
348
349      <para>To eliminate a default phase, simply define a phase with no
350      contents as shown.</para>
351
352      <programlisting>build {}</programlisting>
353
354      <note>
355        <para>Because many software packages do not use
356        <option>configure</option>, a keyword is provided to eliminate the
357        <option>configure</option> phase. Another exception is the
358        <option>destroot</option> phase may not be eliminated. See the
359        chapter <link linkend="reference">Portfile Reference</link> for full
360        information.</para>
361      </note>
362    </section>
363
364    <section id="development.examples.startupitem">
365      <title>Creating a StartupItem</title>
366
367      <para>Startupitems may be placed in the global section of a
368      Portfile.</para>
369
370      <programlisting>startupitem.create      yes
371startupitem.name        nmicmpd
372startupitem.executable  "${prefix}/bin/nmicmpd"</programlisting>
373    </section>
374  </section>
375
376  <section id="development.variants">
377    <title>Port Variants</title>
378
379    <para>Variants are a way for port authors to provide options that may be
380    invoked at install time. They are declared in the global section of a
381    Portfile using the <quote>variant</quote> keyword, and should include <link
382    linkend="reference.variants.descriptions">carefully chosen variant
383    descriptions</link>.</para>
384
385    <section id="development.variants.options">
386      <title>Example Variants</title>
387
388      <para>The most common actions for user-selected variants is to add or
389      remove dependencies, configure arguments, and build arguments according
390      to various options a port author wishes to provide. Here is an example
391      of several variants that modify depends_lib and configure arguments for
392      a port.</para>
393
394      <programlisting>variant fastcgi description {Add fastcgi binary} {
395    configure.args-append \
396            --enable-fastcgi \
397            --enable-force-cgi-redirect \
398            --enable-memory-limit
399}
400
401variant gmp description {Add GNU MP functions} {
402    depends_lib-append port:gmp
403    configure.args-append --with-gmp=${prefix}
404
405}
406
407variant sqlite description {Build sqlite support} {
408    depends_lib-append \
409        port:sqlite3
410    configure.args-delete \
411        --without-sqlite \
412        --without-pdo-sqlite
413    configure.args-append \
414        --with-sqlite \
415        --with-pdo-sqlite=${prefix} \
416        --enable-sqlite-utf8
417}</programlisting>
418
419      <note>
420        <para>Variant names may contain only the characters A-Z, a-z, and the
421        underscore character <quote>_</quote>. Therefore, take care to never
422        use hyphens in variant names.</para>
423      </note>
424
425      <para>In the example variant declaration below, the configure argument
426      <literal>--without-x</literal> is removed and a number of others are
427      appended.</para>
428
429      <programlisting>variant x11 description {Builds port as an X11 program with Lucid widgets} {
430    configure.args-delete   --without-x
431    configure.args-append   --with-x-toolkit=lucid \
432                            --without-carbon \
433                            --with-xpm \
434                            --with-jpeg \
435                            --with-tiff \
436                            --with-gif \
437                            --with-png
438    depends_lib-append      lib:libX11:XFree86 \
439                            lib:libXpm:XFree86 \
440                            port:jpeg \
441                            port:tiff \
442                            port:libungif \
443                            port:libpng
444}</programlisting>
445    </section>
446
447    <section id="development.variants.phase">
448      <title>Variant Actions in a Phase</title>
449
450      <para>If a variant requires options in addition to those provided by
451      keywords using -append and/or -delete, in other words, any actions that
452      would normally take place within a port installation phase, do not try
453      to do this within the variant declaration. Rather, modify the behavior
454      of any affected phases when the variant is invoked using the
455      variant_isset keyword.</para>
456
457      <programlisting>post-destroot {
458    xinstall -m 755 -d ${destroot}${prefix}/etc/
459    xinstall ${worksrcpath}/examples/foo.conf \
460        ${destroot}${prefix}/etc/
461
462    if {[variant_isset carbon]} {
463        delete ${destroot}${prefix}/bin/emacs
464        delete ${destroot}${prefix}/bin/emacs-${version}
465    }
466}</programlisting>
467    </section>
468
469    <section id="development.variants.default">
470      <title>Default Variants</title>
471
472      <para>Variants are used to specify actions that lie outside the core
473      functions of an application or port, but there may be some cases where
474      you wish to specify these non-core functions by default. For this
475      purpose you may use the keyword default_variants.</para>
476
477      <programlisting>default_variants    +foo +bar</programlisting>
478
479      <!-- TODO: add warning not to use default_variant at the moment -->
480
481      <note>
482        <para>The default_variant keyword may only be used in the global
483        Portfile section.</para>
484      </note>
485    </section>
486  </section>
487
488  <section id="development.patches">
489    <title>Patch Files</title>
490
491    <para>Patch files are files created with the Unix command
492    <command>diff</command> that are applied using the command
493    <command>patch</command> to modify text files to fix bugs or extend
494    functionality.</para>
495
496    <section id="development.patches.portfile">
497      <title>Creating Portfile Patches</title>
498
499      <para>If you wish to contribute modifications or fixes to a Portfile,
500      you should do so in the form of a patch. Follow the steps below to
501      create Portfile patch files</para>
502
503      <orderedlist>
504        <listitem>
505          <para>Make a copy of the Portfile you wish to modify; both files
506          must be in the same directory, though it may be any
507          directory.</para>
508
509          <programlisting><prompt>%%</prompt> <userinput>cp -p Portfile Portfile.orig</userinput></programlisting>
510        </listitem>
511
512        <listitem>
513          <para>Edit the file to make it as you want it to be after it is
514          fetched.</para>
515        </listitem>
516
517        <listitem>
518          <para>Now use the Unix command <command>diff -u </command>to create
519          a <quote>unified</quote> diff patch file. Put the name of the port in
520          the patchfile, for example, Portfile-rrdtool.diff.</para>
521
522          <programlisting><prompt>%%</prompt> <userinput>diff -u Portfile.orig Portfile &gt; Portfile-rrdtool.diff</userinput></programlisting>
523        </listitem>
524
525        <listitem>
526          <para>A patch file that is a <quote>unified</quote> diff file is the
527          easiest to interpret by humans and this type should always be used
528          for ports. The Portfile patch below will change the version and
529          checksums when applied.</para>
530
531          <programlisting>--- Portfile.orig        2011-07-25 18:52:12.000000000 -0700
532+++ Portfile    2011-07-25 18:53:35.000000000 -0700
533@@ -2,7 +2,7 @@
534 PortSystem          1.0
535 name                foo
536 
537-version             1.3.0
538+version             1.4.0
539 categories          net
540 maintainers         nomaintainer
541 description         A network monitoring daemon.
542@@ -13,9 +13,9 @@
543 
544 homepage            http://rsug.itd.umich.edu/software/${name}
545 
546 master_sites        ${homepage}/files/
547-checksums           rmd160 f0953b21cdb5eb327e40d4b215110b71
548+checksums           rmd160 01532e67a596bfff6a54aa36face26ae
549 extract.suffix      .tgz
550 platforms           darwin
551</programlisting>
552        </listitem>
553      </orderedlist>
554
555      <para>Now you may attach the patch file to a MacPorts Trac ticket for
556      the port author to evaluate.</para>
557    </section>
558
559    <section id="development.patches.source">
560      <title>Creating Source Code Patches</title>
561
562      <para>Necessary or useful patches to application source code should
563      generally be sent to the application developer rather than the port
564      author so the modifications may be included in the next version of the
565      application.</para>
566
567      <para>Generally speaking, you should create one patch file for each file
568      to be patched. Patchfile filenames should uniquely distinguish the file
569      and generally be of the form
570      <filename>patch-</filename><replaceable>&lt;directory&gt;</replaceable>-<replaceable>&lt;filename&gt;.diff</replaceable>,
571      as shown in this example:
572      <filename>patch-src-Makefile.in.diff</filename>.</para>
573
574      <para>You may use patch files that patch multiple files under these
575      conditions:</para>
576
577      <itemizedlist>
578        <listitem>
579          <para>You find existing patch files that do so.</para>
580        </listitem>
581
582        <listitem>
583          <para>If fixing a particular problem or bug requires changes in
584          multiple files -in those cases the patch filename should reference
585          the problem or bug, for example:
586          <filename>patch-</filename><replaceable>&lt;destroot_variable_fix&gt;.diff</replaceable></para>
587        </listitem>
588      </itemizedlist>
589
590      <para>To create a patch to modify a single file, follow the steps
591      below.</para>
592
593      <orderedlist>
594        <listitem>
595          <para>Locate the file you wish to patch in its original location
596          within the unpacked source directory and make a duplicate of
597          it.</para>
598
599          <programlisting><prompt>%%</prompt> <userinput>cd ~/Downloads/foo-1.34/src</userinput>
600<prompt>%%</prompt> <userinput>cp -p Makefile.in Makefile.in.orig</userinput></programlisting>
601        </listitem>
602
603        <listitem>
604          <para>Edit the file and modify the text to reflect your
605          corrections.</para>
606        </listitem>
607
608        <listitem>
609          <para>Now <command>cd</command> to the top-level directory of the
610          unpacked source, and use the Unix command <command>diff -u</command>
611          to create a <quote>unified</quote> diff patch file.</para>
612
613          <programlisting><prompt>%%</prompt> <userinput>cd ~/Downloads/foo-1.34</userinput>
614<prompt>%%</prompt> <userinput>diff -u src/Makefile.in.orig src/Makefile.in &gt; patch-src-Makefile.in.diff</userinput></programlisting>
615
616          <para>You should execute the <command>diff</command> command from
617          the top-level directory of the unpacked source code, because during
618          the patch phase MacPorts by default uses the patch argument
619          <option>-p0</option>, which does not strip prefixes with any leading
620          slashes from file names found in the patch file (as opposed to
621          <option>-p1</option> that strips one, etc), and any path not
622          relative to the top-level directory of the unpacked source will fail
623          during the patch phase.</para>
624
625          <note>
626            <para>If you find an existing source file patch you wish to use
627            that contains leading path information (diff was executed from a
628            directory higher than the top-level source directory), you will
629            need to use the <link linkend="reference.phases.patch">patch phase
630            keyword</link> <code>patch.pre_args</code> to specify a
631            <option>-px</option> value for how many prefixes with leading
632            slashes are to be stripped off.</para>
633          </note>
634        </listitem>
635
636        <listitem>
637          <para>A patch file that is a <quote>unified</quote> diff file is the
638          easiest to interpret by humans and this type should always be used
639          for ports. See the example below where a patch adds
640          <varname>DESTDIR</varname> support to a
641          <filename>Makefile.in</filename> file.</para>
642
643          <programlisting>--- src/Makefile.in.orig   2007-06-01 16:30:47.000000000 -0700
644+++ src/Makefile.in       2007-06-20 10:10:59.000000000 -0700
645@@ -131,23 +131,23 @@
646        $(INSTALL_DATA)/gdata $(INSTALL_DATA)/perl
647
648 install-lib:
649-       -mkdir -p $(INSTALL_LIB)
650+       -mkdir -p $(DESTDIR)$(INSTALL_LIB)
651        $(PERL) tools/install_lib -s src -l $(INSTALL_LIB) $(LIBS)
652-       cp $(TEXT) $(INSTALL_LIB)/
653+       cp $(TEXT) $(DESTDIR)$(INSTALL_LIB)/</programlisting>
654        </listitem>
655
656        <listitem>
657          <para>Place the patch
658          <filename>patch-src-Makefile.in.diff</filename> in the directory
659          <filename>${portpath}/files</filename> and use it in a port using
660          the <code>patchfiles</code> keyword. <varname>${portpath}</varname>
661          may be in a local Portfile repository during development, or
662          <filename>files/</filename> may be in a port's
663          <varname>${portpath}</varname> in the global MacPorts
664          repository.</para>
665
666          <programlisting>patchfiles          patch-src-Makefile.in.diff</programlisting>
667        </listitem>
668      </orderedlist>
669    </section>
670
671    <section id="development.patches.applying">
672      <title>Manually Applying Patches</title>
673
674      <para>MacPorts applies patch files automatically, but you may want to
675      know how to apply patch files manually if you want to test patch files
676      you have created or you wish to apply uncommitted Portfile
677      patches.</para>
678
679      <orderedlist>
680        <listitem>
681          <para>Change to the directory containing the file to be patched. In
682          this example, we'll apply a Portfile patch to the postfix
683          port.</para>
684
685          <programlisting><prompt>%%</prompt> <userinput>cd $(port dir postfix)</userinput></programlisting>
686        </listitem>
687
688        <listitem>
689          <para>Now apply the patch from your Downloads folder, or wherever you
690          put it. The patchfile knows the name of the file to be patched.</para>
691
692          <programlisting><prompt>%%</prompt> <userinput>patch -p0 &lt; ~/Downloads/Portfile-postfix.diff</userinput></programlisting>
693
694          <screen>patching file Portfile</screen>
695        </listitem>
696      </orderedlist>
697    </section>
698  </section>
699
700  <section id="development.local-repositories">
701    <title>Local Portfile Repositories</title>
702
703    <para>To create and test Portfiles that are not yet committed to
704    Subversion, you may create a local Portfile repository as shown. Replace
705    the hypothetical user <filename>julesverne</filename> with your username
706    in the example below.</para>
707
708    <orderedlist>
709      <listitem>
710        <para>Open the <filename>sources.conf</filename> file in a text
711        editor. For example, to open it into TextEdit:</para>
712
713        <programlisting><prompt>%%</prompt> <userinput>open -e ${prefix}/etc/macports/sources.conf</userinput></programlisting>
714      </listitem>
715
716      <listitem>
717        <para>Insert a URL pointing to your local repository location before
718        the rsync URL as shown.</para>
719
720        <programlisting>file:///Users/julesverne/ports
721rsync://rsync.macports.org/release/ports [default]
722</programlisting>
723
724        <note>
725          <para>The file URL should always appear before the rsync URL so that
726          local Portfiles can be tested that are duplicated in the MacPorts
727          tree, because the <command>port</command> command will always
728          operate on the first Portfile it encounters.</para>
729        </note>
730      </listitem>
731
732      <listitem>
733        <para>Place the Portfiles you create inside a directory whose name
734        matches the port, which should in turn be placed inside a directory
735        that reflects the port's primary category (the first category entry in
736        the Portfile). For example, to create the directory for a hypothetical
737        port <quote>bestevergame</quote> and to begin editing its Portfile in
738        TextEdit, you can use these commands:</para>
739
740        <programlisting><prompt>%%</prompt> <userinput>mkdir -p ~/ports/games/bestevergame</userinput>
741<prompt>%%</prompt> <userinput>cd ~/ports/games/bestevergame</userinput>
742<prompt>%%</prompt> <userinput>touch Portfile</userinput>
743<prompt>%%</prompt> <userinput>open -e Portfile</userinput></programlisting>
744
745        <para>See other sections in the Guide for help writing Portfiles. If
746        you've already written the Portfile elsewhere, you can instead copy
747        the Portfile into this directory.</para>
748      </listitem>
749
750      <listitem>
751        <para>If your Portfile needs to apply any patches to the port's source
752        files, create a <filename>files</filename> directory and place the
753        patchfiles in it, and reference the patchfiles in your Portfile, as
754        explained in
755        <link linkend="development.patches.source">Creating Source Code Patches</link>.</para>
756      </listitem>
757
758      <listitem>
759        <para>After you create or update your Portfile, use the MacPorts
760        <command>portindex</command> command in the local repository's
761        directory to create or update the index of the ports in your local
762        repository.</para>
763
764        <programlisting>%% <userinput>cd ~/ports</userinput>
765%% <userinput>portindex</userinput></programlisting>
766
767        <screen>Creating software index in /Users/julesverne/ports
768Adding port games/bestevergame
769
770Total number of ports parsed:   1
771Ports successfully parsed:      1
772Ports failed:                   0</screen>
773      </listitem>
774    </orderedlist>
775
776    <para>Once the local port is added to the <filename>PortIndex</filename>,
777    it becomes available for searching or installation as with any other
778    Portfile in the MacPorts tree:</para>
779
780    <programlisting><prompt>%%</prompt> <userinput>port search bestever</userinput></programlisting>
781
782    <screen>bestevergame @1.1 (games)
783    The Best Ever Game</screen>
784  </section>
785
786  <section id="development.practices">
787    <title>Portfile Best Practices</title>
788
789    <para>This section contains practical guidelines for creating Portfiles
790    that install smoothly and provide consistency between ports. The following
791    sections are on the TODO list.</para>
792
793    <section id="development.practices.portstyle">
794      <title>Port Style</title>
795
796      <para>Portfiles may be thought of as a table of keys and values in two
797      columns separated by spaces (not tabs), so you should set your editor to
798      use soft tabs, which are tabs emulated by spaces. By default, the top
799      line of all Portfiles should use a modeline that defines soft tabs for
800      the vim and emacs editors as shown.</para>
801
802      <programlisting># -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- vim:fenc=utf-8:ft=tcl:et:sw=4:ts=4:sts=4</programlisting>
803
804      <para>The left column should consist of single words, and will be
805      separated from the more complex right side by spaces in multiples of
806      four. Variable assignments and variant declarations are exceptions, and
807      may be considered a single word on the left side, with a single space
808      between words.</para>
809
810      <programlisting>set libver "8.5"
811
812
813variant mysql5 { ... }</programlisting>
814
815      <para>Frequently multiple items are necessary in the second column. For
816      example, to set multiple source download locations, multiple
817      <code>master_sites</code> must be defined. Unless the second column
818      items are few and short you should place each additional item on a new
819      line and separate lines with a backslash. Indent the lines after the
820      first line to make it clear the items are second column values and also
821      to emphasize the unity of the block.</para>
822
823      <programlisting>destroot.keepdirs    ${destroot}${prefix}/var/run \
824                     ${destroot}${prefix}/var/log \
825                     ${destroot}${prefix}/var/cache/mrtg</programlisting>
826    </section>
827
828    <section id="development.practices.dont-overwrite">
829      <title>Don't Overwrite Config Files</title>
830
831      <para>TODO:</para>
832    </section>
833
834    <section id="development.practices.install-docs">
835      <title>Install Docs and Examples</title>
836
837      <para>TODO:</para>
838    </section>
839
840    <section id="development.practices.provide-messages">
841      <title>Provide User Messages</title>
842
843      <para>TODO:</para>
844    </section>
845
846    <section id="development.practices.use-variables">
847      <title>Use Variables</title>
848
849      <para>TODO: Set variables so changing paths may be done in one place;
850      use them anytime it makes updates simpler: distname
851      ${name}-src-${version}</para>
852    </section>
853
854
855    <section id="development.practices.rename-replace-port">
856      <title>Renaming or replacing a port</title>
857
858      <para>If there is the need to replace a port with another port or a
859      renaming is necessary for some reason, the port should be marked as
860      <code>replaced_by</code>.</para>
861     
862      <para>As an illustration of a typical workflow the port
863      <quote>skrooge-devel</quote> shall be taken. This port had been used for
864      testing new versions of skrooge, but it turned out to have become
865      unnecessary due to the fact that skrooge's developers currently prefer a
866      distribution via port <quote>skrooge</quote> instead. </para>
867     
868      <para>At the end of this section the use of the obsolete PortGroup is suggested
869      as an even shorter approach to the below described workflow.</para>
870
871      <section id="development.replaced_by">
872      <title>The long way</title>
873
874      <para>Skrooge's original devel port file looked like this:</para>
875
876<programlisting># -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: t -*- vim:fenc=utf-8:et:sw=4:ts=4:sts=4
877# $Id$
878
879PortSystem          1.0
880PortGroup           kde4    1.1
881
882fetch.type          svn
883svn.url             svn://anonsvn.kde.org/home/kde/trunk/extragear/office/skrooge
884svn.revision        1215845
885
886name                skrooge-devel
887version             0.8.0-${svn.revision}
888
889categories          kde finance
890maintainers         mk pixilla openmaintainer
891description         Skrooge
892long_description    Personal finance management tool for KDE4, with the aim of being highly intuitive, while \
893                    providing powerful functions such as reporting (including graphics), persistent \
894                    Undo/Redo, encryption, and much more...
895
896conflicts           skrooge
897
898platforms           darwin
899license             GPL-3
900
901homepage            http://skrooge.org
902master_sites        http://skrooge.org/files/
903
904livecheck.type      none
905
906distname            skrooge
907
908depends_lib-append  port:kdelibs4 \
909                    port:libofx \
910                    port:qca-ossl \
911                    port:kdebase4-runtime \
912                    port:oxygen-icons</programlisting>
913
914        <para>The following steps have to be taken to ensure a smooth transition
915        for a MacPorts user updating his local installation using
916        <userinput>sudo port upgrade</userinput>:</para>
917
918    <orderedlist>
919      <listitem>
920        <para> add the line <code>replaced_by foo</code> where foo is the
921        port this one is replaced by; when a user upgrades this port,
922        MacPorts will instead install the replacement port</para>
923                <programlisting>replaced_by         skrooge</programlisting>
924      </listitem>
925
926      <listitem>
927        <para> increase the version, revision, or epoch, so that users who
928        have this port installed will get notice in <code>port
929        outdated</code> that they should upgrade it and trigger the above
930        process</para>
931                <programlisting>revision            1</programlisting>
932      </listitem>
933
934      <listitem>
935        <para> clear distfiles (have a line reading only
936        <code>distfiles</code>) so that no distfile is downloaded for this
937        stub port</para>
938                <programlisting>distfiles</programlisting>
939      </listitem>
940
941      <listitem>
942        <para> delete master_sites since there aren't any distfiles to
943        download</para>
944      </listitem>
945
946      <listitem>
947        <para> disable livecheck</para>
948        <programlisting>livecheck.type      none</programlisting>
949      </listitem>
950
951      <listitem>
952        <para> add a pre-configure block with a <code>ui_error</code> and
953        <code>return -code error</code> explaining to users who try to
954        install this port that the port has been replaced</para>
955                <programlisting>pre-configure {
956    ui_error "Please do not install this port since it has been replaced by 'skrooge'."
957    return -code error
958}</programlisting>
959      </listitem>
960    </orderedlist>
961
962        <para>With above modifications the port file eventually looks like
963        this:</para>
964
965<programlisting># -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: t -*- vim:fenc=utf-8:et:sw=4:ts=4:sts=4
966# $Id$
967
968PortSystem          1.0
969
970name                skrooge-devel
971svn.revision        1215845
972version             0.8.0-${svn.revision}
973revision            1
974
975replaced_by         skrooge
976
977categories          kde finance
978maintainers         mk pixilla openmaintainer
979description         Skrooge
980long_description    Personal finance management tool for KDE4, with the aim of being highly intuitive, while \
981                    providing powerful functions such as reporting (including graphics), persistent \
982                    Undo/Redo, encryption, and much more...
983
984platforms           darwin
985license             GPL-3
986
987homepage            http://skrooge.org
988
989livecheck.type      none
990
991pre-configure {
992    ui_error "Please do not install this port since it has been replaced by 'skrooge'."
993    return -code error
994}
995
996distfiles</programlisting>
997
998        <para>A user upgrading ports will experience the following for port
999  <quote>skrooge-devel</quote>:</para>
1000        <programlisting><prompt>%%</prompt> <userinput>sudo port upgrade skrooge-devel</userinput></programlisting>
1001        <screen>--->  skrooge-devel is replaced by skrooge
1002--->  Computing dependencies for skrooge
1003--->  Fetching skrooge
1004--->  Verifying checksum(s) for skrooge
1005--->  Extracting skrooge
1006--->  Configuring skrooge
1007--->  Building skrooge
1008--->  Staging skrooge into destroot
1009--->  Deactivating skrooge-devel @0.8.0-1215845_0
1010--->  Cleaning skrooge-devel
1011--->  Computing dependencies for skrooge
1012--->  Installing skrooge @0.8.0.6_0
1013--->  Activating skrooge @0.8.0.6_0
1014##########################################################
1015# Don't forget that dbus needs to be started as the local
1016# user (not with sudo) before any KDE programs will launch
1017# To start it run the following command:                 
1018# launchctl load /Library/LaunchAgents/org.freedesktop.dbus-session.plist
1019##########################################################
1020 
1021######################################################
1022#  Programs will not start until you run the command
1023#  'sudo chown -R $USER ~/Library/Preferences/KDE' 
1024#  replacing $USER with your username.             
1025######################################################
1026--->  Cleaning skrooge</screen>
1027
1028        <para>In case a user actually tries to install the obsolete port
1029        <quote>skrooge-devel</quote> it would be pointed out by an error message that
1030  this is impossible now:</para>
1031        <programlisting><prompt>%%</prompt> <userinput>sudo port install skrooge-devel</userinput></programlisting>
1032        <screen>--->  Fetching skrooge-devel
1033--->  Verifying checksum(s) for skrooge-devel
1034--->  Extracting skrooge-devel
1035--->  Configuring skrooge-devel
1036Error: Please do not install this port since it has been replaced by 'skrooge'.
1037Error: Target org.macports.configure returned:
1038Log for skrooge-devel is at: /opt/local/var/macports/logs/_opt_local_var_macports_sources_rsync.macports.org_release_ports_kde_skrooge-devel/main.log
1039Error: Status 1 encountered during processing.
1040To report a bug, see &lt;http://guide.macports.org/#project.tickets&gt;</screen>
1041
1042        </section>
1043
1044    <section id="development.obsolete-portgroup">
1045    <title>The shortcut: PortGroup obsolete</title>
1046
1047        <para>Using the PortGroup obsolete makes the task described in the previous subsection
1048        much easier:</para>
1049
1050        <programlisting>
1051# -*- coding: utf-8; mode: tcl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; truncate-lines: t -*- vim:fenc=utf-8:et:sw=4:ts=4:sts=4
1052# $Id$
1053PortSystem          1.0
1054replaced_by         skrooge
1055PortGroup           obsolete 1.0
1056name                skrooge-devel
1057svn.revision        1215845
1058version             0.8.0-${svn.revision}
1059revision            2</programlisting>
1060
1061        <para>The PortGroup defines a number of reasonable defaults for a port that is only
1062        there to inform users that they should uninstall it and install something else
1063        instead. You might want to override some of the defaults though. For details have
1064        a look at the PortGroup's source code in
1065        <filename>${prefix}/var/macports/sources/rsync.macports.org/release/ports/_resources/port1.0/group/obsolete-1.0.tcl</filename>.</para>
1066
1067      <note>
1068        <para>It is important to specify <varname>replaced_by</varname> BEFORE the
1069            <varname>PortGroup</varname> line!</para>
1070      </note>
1071
1072    </section>
1073
1074    </section>
1075   
1076   
1077    <section id="development.practices.removing-port">
1078      <title>Removing a port</title>
1079
1080      <para>If a port has to be removed from MacPorts one should consider
1081      the hints concerning replacing it by some alternative port given
1082      <link linkend="development.practices.rename-replace-port">above</link>.
1083      If there is no replacement for it, insert a pre-configure
1084      block as described there to alert the user about why the port is not
1085      allowed for installation anymore.</para>
1086
1087      <para>It is recommended to wait about a year before the port directory
1088      is actually being removed from MacPorts' Subversion repository.</para>
1089 
1090        </section>
1091   
1092  </section>
1093
1094  <section id="development.buildbot">
1095  <title>MacPorts' buildbot</title>
1096
1097      <para>The <ulink url="https://build.macports.org/">buildbot</ulink> is a port
1098      build-service currently supporting building of all committed ports for Snow Leopard,
1099      Lion, and Mountain Lion using the MacPorts AutoBuild
1100      (<ulink url="http://svn.macports.org/repository/macports/contrib/mpab/">MPAB</ulink>)
1101      scripts.</para>
1102     
1103      <para>Every time a maintainer commits changes to MacPorts' central SVN repository
1104      the buildbot will check whether a rebuild of the corresponding port(s) would
1105      be necessary. If the port(s) in question are distributable their binary
1106      archives will be kept for subsequent distribution for the three most current
1107      versions of the Mac OS X operating system.</para>
1108     
1109      <para>If a build error occurred for a port its maintainer will be informed via
1110      an email so that problems which did not surface on the maintainer's machine will
1111      not go unnoticed.
1112     
1113      Port maintainers will find the
1114      <ulink url="https://build.macports.org/waterfall">waterfall</ulink>
1115      and the
1116      <ulink url="https://build.macports.org/builders">builders</ulink>
1117      views most useful since they give information about the build status and offer
1118      the possibility to build ones port(s) on specific builders.</para>
1119     
1120      <para>Thus the buildbot helps to keep MacPorts consistent on various
1121      OSX versions, i.e. a maintainer does not need access to these versions anymore in
1122      order to assure that the port(s) maintained build without problems. Currently only
1123      the default port variants will be build and kept.</para>
1124
1125  </section>
1126 
1127</chapter>
Note: See TracBrowser for help on using the repository browser.