aboutsummaryrefslogtreecommitdiff
path: root/en_US.ISO8859-1/books/porters-handbook/porting-dads/chapter.xml
blob: 602772097a2b1f0477f8b4d55dfd0ab8c99fd10b (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
<?xml version="1.0" encoding="iso-8859-1"?>
<!--
     The FreeBSD Documentation Project

     $FreeBSD$
-->

<chapter xmlns="http://docbook.org/ns/docbook"
  xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
  xml:id="porting-dads">

  <title>Dos and Don'ts</title>

  <sect1 xml:id="dads-intro">
    <title>Introduction</title>

    <para>Here is a list of common dos and don'ts that are encountered
      during the porting process.  Check the port against this list,
      but also check ports in the <link
	xlink:href="http://www.FreeBSD.org/cgi/query-pr-summary.cgi?query">PR
	database</link> that others have submitted.  Submit any
      comments on ports you check as described in <link
	xlink:href="&url.articles.contributing;/contrib-how.html#CONTRIB-GENERAL">Bug
	Reports and General Commentary</link>.  Checking ports in the
      PR database will both make it faster for us to commit them, and
      prove that you know what you are doing.</para>
  </sect1>

  <sect1 xml:id="porting-wrkdir">
    <title><varname>WRKDIR</varname></title>

    <para>Do not write anything to files outside
      <varname>WRKDIR</varname>.  <varname>WRKDIR</varname> is the
      only place that is guaranteed to be writable during the port
      build (see <link
	xlink:href="&url.books.handbook;/ports-using.html#PORTS-CD">
	installing ports from a CDROM</link> for an example of
      building ports from a read-only tree).  If you need to modify
      one of the <filename>pkg-<replaceable>*</replaceable></filename>
      files, do so by <link linkend="pkg-names">redefining a
	variable</link>, not by writing over it.</para>
  </sect1>

  <sect1 xml:id="porting-wrkdirprefix">
    <title><varname>WRKDIRPREFIX</varname></title>

    <para>Make sure your port honors <varname>WRKDIRPREFIX</varname>.
      Most ports do not have to worry about this.  In particular, if
      you are referring to a <varname>WRKDIR</varname> of another
      port, note that the correct location is
      <filename>WRKDIRPREFIXPORTSDIR/<replaceable>subdir</replaceable>/<replaceable>name</replaceable>/work</filename>
      not
      <filename>PORTSDIR/<replaceable>subdir</replaceable>/<replaceable>name</replaceable>/work</filename>
      or
      <filename>.CURDIR/../../<replaceable>subdir</replaceable>/<replaceable>name</replaceable>/work</filename>
      or some such.</para>

    <para>Also, if you are defining <varname>WRKDIR</varname>
      yourself, make sure you prepend
      <literal>&dollar;{WRKDIRPREFIX}&dollar;{.CURDIR}</literal> in
      the front.</para>
  </sect1>

  <sect1 xml:id="porting-versions">
    <title>Differentiating Operating Systems and OS Versions</title>

    <para>You may come across code that needs modifications or
      conditional compilation based upon what version of &os; Unix it
      is running under.  The preferred way to tell &os; versions apart
      are the <literal>__FreeBSD_version</literal> and
      <literal>__FreeBSD__</literal> macros defined in <link
	xlink:href="http://svnweb.freebsd.org/base/head/sys/sys/param.h?view=markup">sys/param.h</link>.
      If this file is not included add the code,</para>

      <programlisting>#include &lt;sys/param.h&gt;</programlisting>

      <para>to the proper place in the <filename>.c</filename>
	file.</para>

      <para><literal>__FreeBSD__</literal> is defined in all versions
	of &os; as their major version number.  For example, in &os;
	9.x, <literal>__FreeBSD__</literal> is defined to be
	<literal>9</literal>.</para>

      <programlisting>#if __FreeBSD__ &gt;= 9
#  if __FreeBSD_version &gt;= 901000
	 /* 9.1+ release specific code here */
#  endif
#endif</programlisting>
  </sect1>

  <sect1 xml:id="dads-after-port-mk">
    <title>Writing Something After
      <filename>bsd.port.mk</filename></title>

    <para>Do not write anything after the
      <literal>.include &lt;bsd.port.mk&gt;</literal> line.  It
      usually can be avoided by including
      <filename>bsd.port.pre.mk</filename> somewhere in the middle of
      your <filename>Makefile</filename> and
      <filename>bsd.port.post.mk</filename> at the end.</para>

    <note>
      <para>Include either the
	<filename>bsd.port.pre.mk</filename>/<filename>bsd.port.post.mk</filename>
	pair or <filename>bsd.port.mk</filename> only; do not mix
	these two usages.</para>
    </note>

    <para><filename>bsd.port.pre.mk</filename> only defines a few
      variables, which can be used in tests in the
      <filename>Makefile</filename>,
      <filename>bsd.port.post.mk</filename> defines the rest.</para>

    <para>Here are some important variables defined in
      <filename>bsd.port.pre.mk</filename> (this is not the complete
      list, please read <filename>bsd.port.mk</filename> for the
      complete list).</para>

    <informaltable frame="none" pgwide="0">
      <tgroup cols="2">
	<thead>
	  <row>
	    <entry>Variable</entry>
	    <entry>Description</entry>
	  </row>
	</thead>

	<tbody>
	  <row>
	    <entry><varname>ARCH</varname></entry>
	    <entry>The architecture as returned by <command>uname
		-m</command> (e.g., <literal>i386</literal>)</entry>
	  </row>

	  <row>
	    <entry><varname>OPSYS</varname></entry>
	    <entry>The operating system type, as returned by
	      <command>uname -s</command> (e.g.,
	      <literal>FreeBSD</literal>)</entry>
	  </row>

	  <row>
	    <entry><varname>OSREL</varname></entry>
	    <entry>The release version of the operating system
	      (e.g., <literal>2.1.5</literal> or
	      <literal>2.2.7</literal>)</entry>
	  </row>

	  <row>
	    <entry><varname>OSVERSION</varname></entry>
	    <entry>The numeric version of the operating system; the
	      same as <link
		linkend="freebsd-versions"><literal>__FreeBSD_version</literal></link>.</entry>
	  </row>

	  <row>
	    <entry><varname>LOCALBASE</varname></entry>
	    <entry>The base of the <quote>local</quote> tree (e.g.,
	      <literal>/usr/local</literal>)</entry>
	  </row>

	  <row>
	    <entry><varname>PREFIX</varname></entry>

	    <entry>Where the port installs itself (see
	      <link linkend="porting-prefix">more on
		<varname>PREFIX</varname></link>).</entry>
	  </row>
	</tbody>
      </tgroup>
    </informaltable>

    <note>
      <para>If you have to define the variable
	<varname>MASTERDIR</varname>, do so before including
	<filename>bsd.port.pre.mk</filename>.</para>
    </note>

    <para>Here are some examples of things you can write after
      <filename>bsd.port.pre.mk</filename>:</para>

    <programlisting># no need to compile lang/perl5 if perl5 is already in system
.if ${OSVERSION} &gt; 300003
BROKEN=	perl is in system
.endif</programlisting>

    <para>You did remember to use tab instead of spaces after
      <literal>BROKEN=</literal> and
      <!-- smiley -->:-).</para>
  </sect1>

  <sect1 xml:id="dads-sh-exec">
    <title>Use the <function>exec</function> Statement in Wrapper
      Scripts</title>

    <para>If the port installs a shell script whose purpose is to
      launch another program, and if launching that program is the
      last action performed by the script, make sure to launch the
      program using the <function>exec</function> statement, for
      instance:</para>

    <programlisting>#!/bin/sh
exec %%LOCALBASE%%/bin/java -jar %%DATADIR%%/foo.jar "$@"</programlisting>

    <para>The <function>exec</function> statement replaces the shell
      process with the specified program.  If
      <function>exec</function> is omitted, the shell process remains
      in memory while the program is executing, and needlessly
      consumes system resources.</para>
  </sect1>

  <sect1 xml:id="dads-rational">
    <title>Do Things Rationally</title>

    <para>The <filename>Makefile</filename> should do things simply
      and reasonably.  If you can make it a couple of lines shorter or
      more readable, then do so.  Examples include using a make
      <literal>.if</literal> construct instead of a shell
      <literal>if</literal> construct, not redefining
      <buildtarget>do-extract</buildtarget> if you can redefine
      <varname>EXTRACT*</varname> instead, and using
      <varname>GNU_CONFIGURE</varname> instead of
      <literal>CONFIGURE_ARGS
	+= --prefix=&dollar;{PREFIX}</literal>.</para>

    <para>If you find yourself having to write a lot of new code to
      try to do something, please go back and review
      <filename>bsd.port.mk</filename> to see if it contains an
      existing implementation of what you are trying to do.  While
      hard to read, there are a great many seemingly-hard problems for
      which <filename>bsd.port.mk</filename> already provides a
      shorthand solution.</para>
  </sect1>

  <sect1 xml:id="dads-cc">
    <title>Respect Both <varname>CC</varname> and
      <varname>CXX</varname></title>

    <para>The port must respect both <varname>CC</varname> and
      <varname>CXX</varname> variables.  What we mean by this is that
      the port must not set the values of these variables absolutely,
      overriding existing values; instead, it may append whatever
      values it needs to the existing values.  This is so that build
      options that affect all ports can be set globally.</para>

    <para>If the port does not respect these variables,
      please add
      <literal>NO_PACKAGE=ignores either cc or cxx</literal> to the
      <filename>Makefile</filename>.</para>

    <para>An example of a <filename>Makefile</filename> respecting
      both <varname>CC</varname> and <varname>CXX</varname>
      variables follows.  Note the <varname>?=</varname>:</para>

    <programlisting>CC?= gcc</programlisting>

    <programlisting>CXX?= g++</programlisting>

    <para>Here is an example which respects neither
      <varname>CC</varname> nor <varname>CXX</varname>
      variables:</para>

    <programlisting>CC= gcc</programlisting>

    <programlisting>CXX= g++</programlisting>

    <para>Both <varname>CC</varname> and <varname>CXX</varname>
      variables can be defined on &os; systems in
      <filename>/etc/make.conf</filename>.  The first example defines
      a value if it was not previously set in
      <filename>/etc/make.conf</filename>, preserving any system-wide
      definitions.  The second example clobbers anything previously
      defined.</para>
  </sect1>

  <sect1 xml:id="dads-cflags">
    <title>Respect <varname>CFLAGS</varname></title>

    <para>The port must respect the <varname>CFLAGS</varname>
      variable.  What we mean by this is that the port must not set
      the value of this variable absolutely, overriding the existing
      value; instead, it may append whatever values it needs to the
      existing value.  This is so that build options that affect all
      ports can be set globally.</para>

    <para>If it does not, please add
      <literal>NO_PACKAGE=ignores cflags</literal> to the
      <filename>Makefile</filename>.</para>

    <para>An example of a <filename>Makefile</filename> respecting
      the <varname>CFLAGS</varname> variable follows.  Note the
      <varname>+=</varname>:</para>

    <programlisting>CFLAGS+= -Wall -Werror</programlisting>

    <para>Here is an example which does not respect the
      <varname>CFLAGS</varname> variable:</para>

    <programlisting>CFLAGS= -Wall -Werror</programlisting>

    <para>The <varname>CFLAGS</varname> variable is defined on
      &os; systems in <filename>/etc/make.conf</filename>.  The first
      example appends additional flags to the
      <varname>CFLAGS</varname> variable, preserving any system-wide
      definitions.  The second example clobbers anything previously
      defined.</para>

    <para>You should remove optimization flags from the third party
      <filename>Makefile</filename>s.  System
      <varname>CFLAGS</varname> contains system-wide optimization
      flags.  An example from an unmodified
      <filename>Makefile</filename>:</para>

    <programlisting>CFLAGS= -O3 -funroll-loops -DHAVE_SOUND</programlisting>

    <para>Using system optimization flags, the
      <filename>Makefile</filename> would look similar to the
      following example:</para>

    <programlisting>CFLAGS+= -DHAVE_SOUND</programlisting>
  </sect1>

  <sect1 xml:id="dads-pthread">
    <title>Threading Libraries</title>

    <para>The threading library must be linked to the binaries using
      a special flag <literal>-pthread</literal> on &os;.  If a port
      insists on linking <literal>-lpthread</literal> directly, patch
      it to use <literal>-pthread</literal>.</para>

    <note>
      <para>If building the port errors out with
	<literal>unrecognized option '-pthread'</literal>, it may be
	desirable to use <command>cc</command> as linker by setting
	<varname>CONFIGURE_ENV</varname> to
	<literal>LD=${CC}</literal>.  The <literal>-pthread</literal>
	option is not supported by <command>ld</command>
	directly.</para>
    </note>
  </sect1>

  <sect1 xml:id="dads-feedback">
    <title>Feedback</title>

    <para>Do send applicable changes/patches to the original
      author/maintainer for inclusion in next release of the code.
      This will only make your job that much easier for the next
      release.</para>
  </sect1>

  <sect1 xml:id="dads-readme">
    <title><filename>README.html</filename></title>

    <para><filename>README.html</filename> is not part of the port,
      but generated by <command>make readme</command>.  Do not
      include this file in patches or commits.</para>

    <note>
      <para>If <command>make readme</command> fails, make sure that
	the default value of <varname>ECHO_MSG</varname> has not
	been modified by the port.</para>
    </note>
  </sect1>

  <sect1 xml:id="dads-noinstall">
    <title>Marking a Port Not Installable with
      <varname>BROKEN</varname>, <varname>FORBIDDEN</varname>, or
      <varname>IGNORE</varname></title>

    <para>In certain cases users should be prevented from installing
      a port.  To tell a user that a port should not be installed,
      there are several <command>make</command> variables that can be
      used in a port's <filename>Makefile</filename>.  The value of
      the following <command>make</command> variables will be the
      reason that is given back to users for why the port refuses to
      install itself.  Please use the correct <command>make</command>
      variable as each make variable conveys radically different
      meanings to both users, and to automated systems that depend on
      the <filename>Makefile</filename>s, such as
      <link linkend="build-cluster">the ports build cluster</link>,
      <link linkend="freshports">FreshPorts</link>, and
      <link linkend="portsmon">portsmon</link>.</para>

    <sect2 xml:id="dads-noinstall-variables">
      <title>Variables</title>

      <itemizedlist>
	<listitem>
	  <para><varname>BROKEN</varname> is reserved for ports that
	    currently do not compile, install, deinstall, or run
	    correctly.  It should be used for ports where the problem
	    is believed to be temporary.</para>

	  <para>If instructed, the build cluster will still attempt
	    to try to build them to see if the underlying problem has
	    been resolved.  (However, in general, the cluster is run
	    without this.)</para>

	  <para>For instance, use <varname>BROKEN</varname> when a
	    port:</para>

	  <itemizedlist>
	    <listitem>
	      <para>does not compile</para>
	    </listitem>

	    <listitem>
	      <para>fails its configuration or installation
		process</para>
	    </listitem>

	    <listitem>
	      <para>installs files outside of
		<filename>${PREFIX}</filename></para>
	    </listitem>

	    <listitem>
	      <para>does not remove all its files cleanly upon
		deinstall (however, it may be acceptable, and
		desirable, for the port to leave user-modified files
		behind)</para>
	    </listitem>

	    <listitem>
	      <para>has runtime issues on systems where it is
		supposed to run fine.</para>
	    </listitem>
	  </itemizedlist>
	</listitem>

	<listitem>
	  <para><varname>FORBIDDEN</varname> is used for ports that
	    contain a security vulnerability or induce grave concern
	    regarding the security of a &os; system with a given port
	    installed (e.g., a reputably insecure program or a program
	    that provides easily exploitable services).  Ports should
	    be marked as <varname>FORBIDDEN</varname> as soon as a
	    particular piece of software has a vulnerability and there
	    is no released upgrade.  Ideally ports should be upgraded
	    as soon as possible when a security vulnerability is
	    discovered so as to reduce the number of vulnerable &os;
	    hosts (we like being known for being secure), however
	    sometimes there is a noticeable time gap between
	    disclosure of a vulnerability and an updated release of
	    the vulnerable software.  Do not mark a port
	    <varname>FORBIDDEN</varname> for any reason other than
	    security.</para>
	</listitem>

	<listitem>
	  <para><varname>IGNORE</varname> is reserved for ports that
	    should not be built for some other reason.  It should be
	    used for ports where the problem is believed to be
	    structural.  The build cluster will not, under any
	    circumstances, build ports marked as
	    <varname>IGNORE</varname>.  For instance, use
	    <varname>IGNORE</varname> when a port:</para>

	  <itemizedlist>
	    <listitem>
	      <para>does not work on the installed version of
		&os;</para>
	    </listitem>

	    <listitem>
	      <para>has a distfile which may not be automatically
		fetched due to licensing restrictions</para>
	    </listitem>

	    <listitem>
	      <para>does not work with some other currently
		installed port (for instance, the port depends on
		<package role="port">www/apache20</package> but
		<package role="port">www/apache22</package> is
		installed)</para>
	    </listitem>
	  </itemizedlist>

	  <note>
	    <para>If a port would conflict with a currently
	      installed port (for example, if they install a file in
	      the same place that performs a different function),
	      <link linkend="conflicts">use
		<varname>CONFLICTS</varname> instead</link>.
	      <varname>CONFLICTS</varname> will set
	      <varname>IGNORE</varname> by itself.</para>
	  </note>
	</listitem>

	<listitem>
	  <para>If a port should be marked <varname>IGNORE</varname>
	    only on certain architectures, there are two other
	    convenience variables that will automatically set
	    <varname>IGNORE</varname> for you:
	    <varname>ONLY_FOR_ARCHS</varname> and
	    <varname>NOT_FOR_ARCHS</varname>.  Examples:</para>

	  <programlisting>ONLY_FOR_ARCHS=	i386 amd64</programlisting>

	  <programlisting>NOT_FOR_ARCHS=	ia64 sparc64</programlisting>

	  <para>A custom <varname>IGNORE</varname> message can be
	    set using <varname>ONLY_FOR_ARCHS_REASON</varname> and
	    <varname>NOT_FOR_ARCHS_REASON</varname>.  Per
	    architecture entries are possible with
	    <varname>ONLY_FOR_ARCHS_REASON_<replaceable>ARCH</replaceable></varname>
	    and
	    <varname>NOT_FOR_ARCHS_REASON_<replaceable>ARCH</replaceable></varname>.</para>
	</listitem>

	<listitem>
	  <para>If a port fetches i386 binaries and installs them,
	    <varname>IA32_BINARY_PORT</varname> should be set.  If
	    this variable is set, it will be checked whether the
	    <filename>/usr/lib32</filename> directory is available for
	    IA32 versions of libraries and whether the kernel has IA32
	    compatibility compiled in.  If one of these two
	    dependencies is not satisfied, <varname>IGNORE</varname>
	    will be set automatically.</para>
	</listitem>
      </itemizedlist>
    </sect2>

    <sect2 xml:id="dads-noinstall-notes">
      <title>Implementation Notes</title>

      <para>The strings should not be quoted.  Also, the wording of
	the string should be somewhat different due to the way the
	information is shown to the user.  Examples:</para>

      <programlisting>BROKEN=	fails to link with base -lcrypto</programlisting>

      <programlisting>IGNORE=	unsupported on recent versions</programlisting>

      <para>resulting in the following output from
	<command>make describe</command>:</para>

      <programlisting>===&gt;  foobar-0.1 is marked as broken: fails to link with base -lcrypto.</programlisting>

      <programlisting>===&gt;  foobar-0.1 is unsupported on recent versions.</programlisting>
    </sect2>
  </sect1>

  <sect1 xml:id="dads-deprecated">
    <title>Marking a Port for Removal with
      <varname>DEPRECATED</varname> or
      <varname>EXPIRATION_DATE</varname></title>

    <para>Do remember that <varname>BROKEN</varname> and
      <varname>FORBIDDEN</varname> are to be used as a temporary
      resort if a port is not working.  Permanently broken ports
      should be removed from the tree entirely.</para>

    <para>When it makes sense to do so, users can be warned about
      a pending port removal with <varname>DEPRECATED</varname> and
      <varname>EXPIRATION_DATE</varname>.  The former is simply a
      string stating why the port is scheduled for removal; the latter
      is a string in ISO 8601 format (YYYY-MM-DD).  Both will be shown
      to the user.</para>

    <para>It is possible to set <varname>DEPRECATED</varname>
      without an <varname>EXPIRATION_DATE</varname> (for instance,
      recommending a newer version of the port), but the converse
      does not make any sense.</para>

    <para>There is no set policy on how much notice to give.
      Current practice seems to be one month for security-related
      issues and two months for build issues.  This also gives any
      interested committers a little time to fix the problems.</para>
  </sect1>

  <sect1 xml:id="dads-dot-error">
    <title>Avoid Use of the <literal>.error</literal>
      Construct</title>

    <para>The correct way for a <filename>Makefile</filename> to
      signal that the port can not be installed due to some external
      factor (for instance, the user has specified an illegal
      combination of build options) is to set a non-blank value to
      <varname>IGNORE</varname>.  This value will be formatted and
      shown to the user by <command>make install</command>.</para>

    <para>It is a common mistake to use <literal>.error</literal>
      for this purpose.  The problem with this is that many automated
      tools that work with the ports tree will fail in this situation.
      The most common occurrence of this is seen when trying to build
      <filename>/usr/ports/INDEX</filename> (see
      <xref linkend="make-describe"/>).  However, even more trivial
      commands such as <command>make maintainer</command> also fail in
      this scenario.  This is not acceptable.</para>

    <example xml:id="dot-error-breaks-index">
      <title>How to Avoid Using <literal>.error</literal></title>

      <para>The first of the
	next two <filename>Makefile</filename> snippets will cause
	<command>make index</command> to fail, while the second one
	will not:</para>

      <programlisting>.error "option is not supported"</programlisting>

      <programlisting>IGNORE=option is not supported</programlisting>
    </example>
  </sect1>

  <sect1 xml:id="dads-sysctl">
    <title>Usage of <filename>sysctl</filename></title>

    <para>The usage of <filename>sysctl</filename> is discouraged
      except in targets.  This is because the evaluation of any
      <literal>makevar</literal>s, such as used during
      <command>make index</command>, then has to run the command,
      further slowing down that process.</para>

    <para>Usage of &man.sysctl.8; should always be done with the
      <varname>SYSCTL</varname> variable, as it contains the fully
      qualified path and can be overridden, if one has such a
      special need.</para>
  </sect1>

  <sect1 xml:id="dads-rerolling-distfiles">
    <title>Rerolling Distfiles</title>

    <para>Sometimes the authors of software change the content of
      released distfiles without changing the file's name.  You have
      to verify that the changes are official and have been performed
      by the author.  It has happened in the past that the distfile
      was silently altered on the download servers with the intent to
      cause harm or compromise end user security.</para>

    <para>Put the old distfile aside, download the new one, unpack
      them and compare the content with &man.diff.1;.  If you see
      nothing suspicious, you can update
      <filename>distinfo</filename>.  Be sure to summarize the
      differences in your PR or commit log, so that other people know
      that you have taken care to ensure that nothing bad has
      happened.</para>

    <para>You might also want to contact the authors of the software
      and confirm the changes with them.</para>
  </sect1>

  <sect1 xml:id="dads-avoiding-linuxisms">
    <title>Avoiding Linuxisms</title>

    <para>Do not use <filename>/proc</filename> if there are any
      other ways of getting the information, e.g.,
      <function>setprogname(argv[0])</function> in
      <function>main()</function> and then &man.getprogname.3; if
      you want to <quote>know your name</quote>.</para>

    <para>Do not rely on behaviour that is undocumented by
      <acronym>POSIX</acronym>.</para>

    <para>Do not record timestamps in the critical path of the
      application if it also works without.  Getting timestamps may be
      slow, depending on the accuracy of timestamps in the
      <acronym>OS</acronym>.  If timestamps are really needed,
      determine how precise they have to be and use an
      <acronym>API</acronym> which is documented to just deliver the
      needed precision.</para>

    <para>A number of simple syscalls (for example
      &man.gettimeofday.2;, &man.getpid.2;) are much faster on &linux;
      than on any other operating system due to caching and the
      vsyscall performance optimizations.  Do not rely on them being
      cheap in performance-critical applications.  In general, try
      hard to avoid syscalls if possible.</para>

    <para>Do not rely on &linux;-specific socket behaviour.  In
      particular, default socket buffer sizes are different (call
      &man.setsockopt.2; with <literal>SO_SNDBUF</literal> and
      <literal>SO_RCVBUF</literal>, and while &linux;'s &man.send.2;
      blocks when the socket buffer is full, &os;'s will fail and
      set <literal>ENOBUFS</literal> in errno.</para>

    <para>If relying on non-standard behaviour is required,
      encapsulate it properly into a generic <acronym>API</acronym>,
      do a check for the behaviour in the configure stage, and stop
      if it is missing.</para>

    <para>Check the
      <link xlink:href="http://www.freebsd.org/cgi/man.cgi">man
	pages</link> to see if the function used is a
      <acronym>POSIX</acronym> interface (in the
      <quote>STANDARDS</quote> section of the man page).</para>

    <para>Do not assume that <filename>/bin/sh</filename> is
      <application>bash</application>.  Ensure that a command line
      passed to &man.system.3; will work with a
      <acronym>POSIX</acronym> compliant shell.</para>

    <para>A list of common <application>bash</application>isms is
      available <link
	xlink:href="https://wiki.ubuntu.com/DashAsBinSh">here</link>.</para>

    <para>Check that headers are included in the
      <acronym>POSIX</acronym> or man page recommended way, e.g.,
      <filename>sys/types.h</filename> is often forgotten, which is
      not as much of a problem for &linux; as it is for &os;.</para>

    <para>Compile threaded applications with
      <quote>-pthread</quote>, not <quote>-lpthread</quote> or
      variations thereof.</para>
  </sect1>

  <sect1 xml:id="dads-misc">
    <title>Miscellanea</title>

    <para>The files <filename>pkg-descr</filename> and
      <filename>pkg-plist</filename> should each be double-checked.
      If you are reviewing a port and feel they can be worded better,
      do so.</para>

    <para>Do not copy more copies of the GNU General Public License
      into our system, please.</para>

    <para>Please be careful to note any legal issues! Do not let us
      illegally distribute software!</para>
  </sect1>
</chapter>