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
723
724
725
726
727
728
729
730
|
<?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>${WRKDIRPREFIX}${.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 <sys/param.h></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__ >= 9
# if __FreeBSD_version >= 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 <bsd.port.mk></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} > 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=${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-arch-neutral">
<title>Marking a Port as Architecture Neutral</title>
<para>Ports that do not have any architecture-dependent files
or requirements are identified by setting
<literal>NO_ARCH=yes</literal>.</para>
</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>===> foobar-0.1 is marked as broken: fails to link with base -lcrypto.</programlisting>
<programlisting>===> 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>
|