/[doc]/head/en_US.ISO8859-1/books/porters-handbook/slow-porting/chapter.xml
ViewVC logotype

Contents of /head/en_US.ISO8859-1/books/porters-handbook/slow-porting/chapter.xml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 54293 - (show annotations) (download) (as text)
Thu Jun 25 16:18:51 2020 UTC (4 years ago) by blackend
File MIME type: text/sgml
File size: 23503 byte(s)
Fix a typo.

1 <?xml version="1.0" encoding="iso-8859-1"?>
2 <!--
3 The FreeBSD Documentation Project
4
5 $FreeBSD$
6 -->
7 <chapter xmlns="http://docbook.org/ns/docbook"
8 xmlns:xlink="http://www.w3.org/1999/xlink" version="5.0"
9 xml:id="slow-porting">
10
11 <title>Slow Porting</title>
12
13 <para>Okay, so it was not that simple, and the port required some
14 modifications to get it to work. In this section, we will
15 explain, step by step, how to modify it to get it to work with the
16 ports paradigm.</para>
17
18 <sect1 xml:id="slow-work">
19 <title>How Things Work</title>
20
21 <para>First, this is the sequence of events which occurs when the
22 user first types <command>make</command> in the port's
23 directory. Having
24 <filename>bsd.port.mk</filename> in another window while
25 reading this really helps to understand it.</para>
26
27 <para>But do not worry, not many people understand exactly how
28 <filename>bsd.port.mk</filename> is working...
29 <!-- smiley --><emphasis>:-)</emphasis></para>
30
31 <procedure>
32 <step>
33 <para>The <buildtarget>fetch</buildtarget> target is run. The
34 <buildtarget>fetch</buildtarget> target is responsible for
35 making sure that the tarball exists locally in
36 <varname>DISTDIR</varname>. If
37 <buildtarget>fetch</buildtarget> cannot find the required
38 files in <varname>DISTDIR</varname> it will look up the URL
39 <varname>MASTER_SITES</varname>, which is set in the
40 Makefile, as well as our FTP mirrors where we put distfiles
41 as backup. It will then attempt to fetch the named
42 distribution file with <varname>FETCH</varname>, assuming
43 that the requesting site has direct access to the Internet.
44 If that succeeds, it will save the file in
45 <varname>DISTDIR</varname> for future use and
46 proceed.</para>
47 </step>
48
49 <step>
50 <para>The <buildtarget>extract</buildtarget> target is run.
51 It looks for the port's distribution file (typically a
52 compressed tarball) in
53 <varname>DISTDIR</varname> and unpacks it into a temporary
54 subdirectory specified by <varname>WRKDIR</varname>
55 (defaults to <filename>work</filename>).</para>
56 </step>
57
58 <step>
59 <para>The <buildtarget>patch</buildtarget> target is run.
60 First, any patches defined in <varname>PATCHFILES</varname>
61 are applied. Second, if any patch files named
62 <filename>patch-<replaceable>*</replaceable></filename> are
63 found in <varname>PATCHDIR</varname> (defaults to the
64 <filename>files</filename> subdirectory), they are applied
65 at this time in alphabetical order.</para>
66 </step>
67
68 <step>
69 <para>The <buildtarget>configure</buildtarget> target is run.
70 This can do any one of many different things.</para>
71
72 <orderedlist>
73 <listitem>
74 <para>If it exists, <filename>scripts/configure</filename>
75 is run.</para>
76 </listitem>
77
78 <listitem>
79 <para>If <varname>HAS_CONFIGURE</varname> or
80 <varname>GNU_CONFIGURE</varname> is set,
81 <filename>WRKSRC/configure</filename> is run.</para>
82 </listitem>
83 </orderedlist>
84 </step>
85
86 <step>
87 <para>The <buildtarget>build</buildtarget> target is run.
88 This is responsible for descending into the port's private
89 working directory (<varname>WRKSRC</varname>) and building
90 it.</para>
91 </step>
92
93 <step>
94 <para>The <buildtarget>stage</buildtarget> target is run.
95 This puts the final set of built files into a temporary
96 directory (<varname>STAGEDIR</varname>, see
97 <xref linkend="staging"/>). The hierarchy of this directory
98 mirrors that of the system on which the package will be
99 installed.</para>
100 </step>
101
102 <step>
103 <para>The <buildtarget>package</buildtarget> target is run.
104 This creates a package using the files from the temporary
105 directory created during the
106 <buildtarget>stage</buildtarget> target and the port's
107 <filename>pkg-plist</filename>.</para>
108 </step>
109
110 <step>
111 <para>The <buildtarget>install</buildtarget> target is run.
112 This installs the package created during the
113 <buildtarget>package</buildtarget> target into the host
114 system.</para>
115 </step>
116 </procedure>
117
118 <para>The above are the default actions. In addition,
119 define targets
120 <buildtarget>pre-<replaceable>something</replaceable></buildtarget>
121 or
122 <buildtarget>post-<replaceable>something</replaceable></buildtarget>,
123 or put scripts with those names, in the
124 <filename>scripts</filename> subdirectory, and they will be
125 run before or after the default actions are done.</para>
126
127 <para>For example, if there is a
128 <buildtarget>post-extract</buildtarget> target defined in the
129 <filename>Makefile</filename>, and a file
130 <filename>pre-build</filename> in the
131 <filename>scripts</filename> subdirectory, the
132 <buildtarget>post-extract</buildtarget> target will be called
133 after the regular extraction actions, and
134 <filename>pre-build</filename> will be executed before
135 the default build rules are done. It is recommended to
136 use <filename>Makefile</filename> targets if the actions are
137 simple enough, because it will be easier for someone to figure
138 out what kind of non-default action the port requires.</para>
139
140 <para>The default actions are done by the
141 <buildtarget>do-<replaceable>something</replaceable></buildtarget>
142 targets from <filename>bsd.port.mk</filename>.
143 For example, the commands to extract a port are in the target
144 <buildtarget>do-extract</buildtarget>. If
145 the default target does not do the job right, redefine the
146 <buildtarget>do-<replaceable>something</replaceable></buildtarget>
147 target in the <filename>Makefile</filename>.</para>
148
149 <note>
150 <para>The <quote>main</quote> targets (for example,
151 <buildtarget>extract</buildtarget>,
152 <buildtarget>configure</buildtarget>, etc.) do nothing more
153 than make sure all the stages up to that one are completed and
154 call the real targets or scripts, and they are not intended to
155 be changed. To fix the extraction, fix
156 <buildtarget>do-extract</buildtarget>, but never ever change
157 the way <buildtarget>extract</buildtarget> operates!
158 Additionally, the target
159 <buildtarget>post-deinstall</buildtarget> is invalid and is
160 not run by the ports infrastructure.</para>
161 </note>
162
163 <para>Now that what goes on when the user types <command>make
164 install</command> is better understood, let us go through the
165 recommended steps to create the perfect port.</para>
166 </sect1>
167
168 <sect1 xml:id="slow-sources">
169 <title>Getting the Original Sources</title>
170
171 <para>Get the original sources (normally) as a compressed tarball
172 (<filename>foo.tar.gz</filename> or
173 <filename><replaceable>foo</replaceable>.tar.bz2</filename>) and
174 copy it into <varname>DISTDIR</varname>. Always use
175 <emphasis>mainstream</emphasis> sources when and where
176 possible.</para>
177
178 <para>Set the variable
179 <varname>MASTER_SITES</varname> to reflect where the original
180 tarball resides. Shorthand definitions exist
181 for most mainstream sites in <filename>bsd.sites.mk</filename>.
182 Please use these sites&mdash;and the associated
183 definitions&mdash;if at all possible, to help avoid the problem
184 of having the same information repeated over again many times in
185 the source base. As these sites tend to change over time, this
186 becomes a maintenance nightmare for everyone involved. See
187 <xref linkend="makefile-master_sites"/> for details.</para>
188
189 <para>If there is no FTP/HTTP site that is well-connected to
190 the net, or can only find sites that have irritatingly
191 non-standard formats, put a copy on a reliable
192 FTP or HTTP server (for example, a home
193 page).</para>
194
195 <para>If a convenient and reliable place to put the distfile
196 cannot be found, we can <quote>house</quote> it ourselves on
197 <systemitem>ftp.FreeBSD.org</systemitem>; however, this is the
198 least-preferred solution. The distfile must be placed into
199 <filename>~/public_distfiles/</filename> of someone's
200 <systemitem>freefall</systemitem> account. Ask the person who
201 commits the port to do this. This person will also set
202 <varname>MASTER_SITES</varname> to
203 <literal>LOCAL/<replaceable>username</replaceable></literal>
204 where <literal><replaceable>username</replaceable></literal> is
205 their &os; cluster login.</para>
206
207 <para>If the port's distfile changes all the time without any
208 kind of version update by the author, consider putting the
209 distfile on a home page and listing it as the first
210 <varname>MASTER_SITES</varname>. Try to talk the
211 port author out of doing this; it really does help to establish
212 some kind of source code control. Hosting a specific version
213 will prevent users from getting
214 <errorname>checksum mismatch</errorname> errors, and also reduce
215 the workload of maintainers of our FTP site. Also, if there is
216 only one master site for the port, it is recommended to
217 house a backup on a home page and list it as the second
218 <varname>MASTER_SITES</varname>.</para>
219
220 <para>If the port requires additional patches that are
221 available on the Internet, fetch them too and put them in
222 <varname>DISTDIR</varname>. Do not worry if they come from a
223 site other than where the main source tarball comes, we have a
224 way to handle these situations (see the description of <link
225 linkend="porting-patchfiles">PATCHFILES</link> below).</para>
226 </sect1>
227
228 <sect1 xml:id="slow-modifying">
229 <title>Modifying the Port</title>
230
231 <para>Unpack a copy of the tarball in a private directory and make
232 whatever changes are necessary to get the port to compile
233 properly under the current version of &os;. Keep
234 <emphasis>careful track</emphasis> of steps, as they will be
235 needed to automate the process shortly. Everything, including
236 the deletion, addition, or modification of files has to be
237 doable using an automated script or patch file when the port is
238 finished.</para>
239
240 <para>If the port requires significant user
241 interaction/customization to compile or install, take
242 a look at one of Larry Wall's classic
243 <application>Configure</application> scripts and perhaps do
244 something similar. The goal of the new ports
245 collection is to make each port as <quote>plug-and-play</quote>
246 as possible for the end-user while using a minimum of disk
247 space.</para>
248
249 <note>
250 <para>Unless explicitly stated, patch files, scripts, and other
251 files created and contributed to the &os; ports
252 collection are assumed to be covered by the standard BSD
253 copyright conditions.</para>
254 </note>
255 </sect1>
256
257 <sect1 xml:id="slow-patch">
258 <title>Patching</title>
259
260 <para>In the preparation of the port, files that have been added
261 or changed can be recorded with &man.diff.1; for later feeding
262 to &man.patch.1;. Doing this with a typical file involves
263 saving a copy of the original file before making any changes
264 using a <filename>.orig</filename> suffix.</para>
265
266 <screen>&prompt.user; <userinput>cp <replaceable>file</replaceable> <replaceable>file</replaceable>.orig</userinput></screen>
267
268 <para>After all changes have been made, <command>cd</command> back
269 to the port directory. Use <command>make makepatch</command> to
270 generate updated patch files in the <filename>files</filename>
271 directory.</para>
272
273 <tip>
274 <para>Use <varname>BINARY_ALIAS</varname> to substitute
275 hardcoded commands during the build and avoid patching
276 build files. See <xref linkend="binary-alias" /> for
277 more information.</para>
278 </tip>
279
280 <sect2 xml:id="slow-patch-rules">
281 <title>General Rules for Patching</title>
282
283 <para>Patch files are stored in <varname>PATCHDIR</varname>,
284 usually <filename>files/</filename>, from where they will be
285 automatically applied. All patches must be relative to
286 <varname>WRKSRC</varname>. Typically
287 <varname>WRKSRC</varname> is a subdirectory of
288 <varname>WRKDIR</varname>, the directory where the distfile is
289 extracted. Use <command>make -V WRKSRC</command> to see the
290 actual path. The patch names are to follow these
291 rules:</para>
292
293 <itemizedlist>
294 <listitem>
295 <para>Avoid having more than one patch modify the same file.
296 For example, having both
297 <filename>patch-foobar.c</filename> and
298 <filename>patch-foobar.c2</filename> making changes to
299 <filename>${WRKSRC}/foobar.c</filename> makes them fragile
300 and difficult to debug.</para>
301 </listitem>
302
303 <listitem>
304 <para>When creating names for patch files, replace each
305 underscore (<literal>_</literal>) with two underscores
306 (<literal>__</literal>) and each slash
307 (<literal>/</literal>) with one underscore
308 (<literal>_</literal>). For example, to patch a file
309 named <filename>src/freeglut_joystick.c</filename>, name
310 the corresponding patch
311 <filename>patch-src_freeglut__joystick.c</filename>. Do
312 not name patches like <filename>patch-aa</filename> or
313 <filename>patch-ab</filename>. Always use the path and
314 file name in patch names. Using <command>make
315 makepatch</command> automatically generates the correct
316 names.</para>
317 </listitem>
318
319 <listitem>
320 <para>A patch may modify multiple files if the changes are
321 related and the patch is named appropriately. For
322 example,
323 <filename>patch-add-missing-stdlib.h</filename>.</para>
324 </listitem>
325
326 <listitem>
327 <para>Only use characters <literal>[-+._a-zA-Z0-9]</literal>
328 for naming patches. In particular, <emphasis>do not use
329 <literal>::</literal> as a path separator,</emphasis>
330 use <literal>_</literal> instead.</para>
331 </listitem>
332 </itemizedlist>
333
334
335 <para>Minimize the amount of non-functional whitespace changes
336 in patches. It is common in the Open Source world for
337 projects to share large amounts of a code base, but obey
338 different style and indenting rules. When taking a working
339 piece of functionality from one project to fix similar areas
340 in another, please be careful: the resulting patch may be full
341 of non-functional changes. It not only increases the size of
342 the ports repository but makes it hard to find out what
343 exactly caused the problem and what was changed at all.</para>
344
345 <para>If a file must be deleted, do it in the
346 <buildtarget>post-extract</buildtarget> target rather than as
347 part of the patch.</para>
348
349 </sect2>
350
351 <sect2 xml:id="slow-patch-manual">
352 <title>Manual Patch Generation</title>
353
354 <note>
355 <para>Manual patch creation is usually not necessary.
356 Automatic patch generation as described earlier in this
357 section is the preferred method. However, manual patching
358 may be required occasionally.</para>
359 </note>
360
361 <para>Patches are saved into files named
362 <filename>patch-*</filename> where
363 <replaceable>*</replaceable> indicates the pathname of the
364 file that is patched, such as
365 <filename>patch-Imakefile</filename> or
366 <filename>patch-src-config.h</filename>.</para>
367
368 <para>After the file has been modified, &man.diff.1; is used to
369 record the differences between the original and the modified
370 version. <option>-u</option> causes &man.diff.1; to produce
371 <quote>unified</quote> diffs, the preferred form.</para>
372
373 <screen>&prompt.user; <userinput>diff -u <replaceable>file</replaceable>.orig <replaceable>file</replaceable> &gt; patch-<replaceable>pathname-file</replaceable></userinput></screen>
374
375 <para>When generating patches for new, added files,
376 <option>-N</option> is used to tell &man.diff.1; to treat the
377 non-existent original file as if it existed but was
378 empty:</para>
379
380 <screen>&prompt.user; <userinput>diff -u -N <replaceable>newfile</replaceable>.orig <replaceable>newfile</replaceable> &gt; patch-<replaceable>pathname-newfile</replaceable></userinput></screen>
381
382 <para>Do not add <literal>&dollar;FreeBSD&dollar;</literal> RCS
383 strings in patches. When patches are added to the
384 <application>Subversion</application> repository with
385 <command>svn add</command>, the
386 <literal>fbsd:nokeywords</literal> property is set to
387 <literal>yes</literal> automatically so keywords in the patch
388 are not modified when committed. The property can be added
389 manually with <command>svn propset fbsd:nokeywords yes
390 <replaceable>files...</replaceable></command>.</para>
391
392 <para>Using the recurse (<option>-r</option>) option to
393 &man.diff.1; to generate patches is fine, but please look at
394 the resulting patches to make sure there is no unnecessary
395 junk in there. In particular, diffs between two backup files,
396 <filename>Makefile</filename>s when the port uses
397 <command>Imake</command> or GNU <command>configure</command>,
398 etc., are unnecessary and have to be deleted. If it was
399 necessary to edit <filename>configure.in</filename> and run
400 <command>autoconf</command> to regenerate
401 <command>configure</command>, do not take the diffs of
402 <command>configure</command> (it often grows to a few thousand
403 lines!). Instead, define
404 <literal>USES=autoreconf</literal> and take the
405 diffs of <filename>configure.in</filename>.</para>
406
407 </sect2>
408
409 <sect2 xml:id="slow-patch-automatic-replacements">
410 <title>Simple Automatic Replacements</title>
411
412 <para>Simple replacements can be performed directly from the
413 port <filename>Makefile</filename> using the in-place mode of
414 &man.sed.1;. This is useful when changes use the value of a
415 variable:</para>
416
417 <programlisting>post-patch:
418 @${REINPLACE_CMD} -e 's|/usr/local|${PREFIX}|g' ${WRKSRC}/Makefile</programlisting>
419
420 <important>
421 <para>Only use &man.sed.1; to replace variable content. You
422 must use patch files instead of &man.sed.1; to replace
423 static content.</para>
424 </important>
425
426 <para>Quite often, software being ported uses the CR/LF
427 convention in source files. This may cause problems with
428 further patching, compiler warnings, or script execution (like
429 <literal>/bin/sh^M not found</literal>.) To quickly convert
430 all files from CR/LF to just LF, add this entry to the port
431 <filename>Makefile</filename>:</para>
432
433 <programlisting>USES= dos2unix</programlisting>
434
435 <para>A list of specific files to convert can be given:</para>
436
437 <programlisting>USES= dos2unix
438 DOS2UNIX_FILES= util.c util.h</programlisting>
439
440 <para>Use <varname>DOS2UNIX_REGEX</varname> to convert a group
441 of files across subdirectories. Its argument is a
442 &man.find.1;-compatible regular expression. More on the
443 format is in &man.re.format.7;. This option is useful for
444 converting all files of a given extension. For example,
445 convert all source code files, leaving binary files
446 intact:</para>
447
448 <programlisting>USES= dos2unix
449 DOS2UNIX_REGEX= .*\.([ch]|cpp)</programlisting>
450
451 <para>A similar option is <varname>DOS2UNIX_GLOB</varname>,
452 which runs <command>find</command> for each element listed
453 in it.</para>
454
455 <programlisting>USES= dos2unix
456 DOS2UNIX_GLOB= *.c *.cpp *.h</programlisting>
457
458
459 <para>The base directory for the conversion can be set. This
460 is useful when there are multiple distfiles and several
461 contain files which require line-ending conversion.</para>
462
463 <programlisting>USES= dos2unix
464 DOS2UNIX_WRKSRC= ${WRKDIR}</programlisting>
465 </sect2>
466
467 <sect2 xml:id="slow-patch-extra">
468 <title>Patching Conditionally</title>
469
470 <para>Some ports need patches that are only applied for specific
471 &os; versions or when a particular option is enabled or
472 disabled. Conditional patches are specified by placing the
473 full paths to the patch files in
474 <varname>EXTRA_PATCHES</varname>.</para>
475
476 <example xml:id="slow-patch-extra-ex1">
477 <title>Applying a Patch for a Specific &os; Version</title>
478
479 <programlisting>.include &lt;bsd.port.options.mk&gt;
480
481 # Patch in the iconv const qualifier before this
482 .if ${OPSYS} == FreeBSD &amp;&amp; ${OSVERSION} &lt; 1100069
483 EXTRA_PATCHES= ${PATCHDIR}/extra-patch-fbsd10
484 .endif
485
486 .include &lt;bsd.port.mk&gt;</programlisting>
487 </example>
488
489 <example xml:id="slow-patch-extra-ex2">
490 <title>Optionally Applying a Patch</title>
491
492 <para>When an <link linkend="makefile-options">option</link>
493 requires a patch, use
494 <varname><replaceable>opt</replaceable>_EXTRA_PATCHES</varname>
495 and
496 <varname><replaceable>opt</replaceable>_EXTRA_PATCHES_OFF</varname>
497 to make the patch conditional on the
498 <literal><replaceable>opt</replaceable></literal> option.
499 See <xref linkend="options-variables"/> for more
500 information.</para>
501
502 <programlisting>OPTIONS_DEFINE= FOO BAR
503 FOO_EXTRA_PATCHES= ${PATCHDIR}/extra-patch-foo
504 BAR_EXTRA_PATCHES_OFF= ${PATCHDIR}/extra-patch-bar.c \
505 ${PATCHDIR}/extra-patch-bar.h</programlisting>
506 </example>
507
508 <example xml:id="slow-patch-extra-ex-dirs">
509 <title>Using <varname>EXTRA_PATCHES</varname> With a
510 Directory</title>
511
512 <para>Sometime, there are many patches that are needed for a
513 feature, in this case, it is possible to point
514 <varname>EXTRA_PATCHES</varname> to a directory, and it will
515 automatically apply all files named
516 <filename>patch-<replaceable>*</replaceable></filename> in
517 it.</para>
518
519 <para>Create a subdirectory in
520 <filename>${PATCHDIR}</filename>, and move the patches in
521 it. For example:</para>
522
523 <screen>&prompt.user; <userinput>ls -l <replaceable>files/foo-patches</replaceable></userinput>
524 -rw-r--r-- 1 root wheel 350 Jan 16 01:27 patch-Makefile.in
525 -rw-r--r-- 1 root wheel 3084 Jan 18 15:37 patch-configure</screen>
526
527 <para>Then add this to the <filename>Makefile</filename>:</para>
528
529 <programlisting>OPTIONS_DEFINE= FOO
530 FOO_EXTRA_PATCHES= ${PATCHDIR}/foo-patches</programlisting>
531
532 <para>The framework will then use all the files named
533 <filename>patch-<replaceable>*</replaceable></filename> in
534 that directory.</para>
535 </example>
536 </sect2>
537 </sect1>
538
539 <sect1 xml:id="slow-configure">
540 <title>Configuring</title>
541
542 <para>Include any additional customization commands in the
543 <filename>configure</filename> script and save it in the
544 <filename>scripts</filename> subdirectory. As mentioned above,
545 it is also possible do this with <filename>Makefile</filename>
546 targets and/or scripts with the name
547 <filename>pre-configure</filename> or
548 <filename>post-configure</filename>.</para>
549 </sect1>
550
551 <sect1 xml:id="slow-user-input">
552 <title>Handling User Input</title>
553
554 <para>If the port requires user input to build, configure, or
555 install, set <varname>IS_INTERACTIVE</varname> in the
556 <filename>Makefile</filename>. This will allow
557 <quote>overnight builds</quote> to skip it. If the user
558 sets the variable <envar>BATCH</envar> in their environment (and
559 if the user sets the variable <envar>INTERACTIVE</envar>, then
560 <emphasis>only</emphasis> those ports requiring interaction are
561 built). This will save a lot of wasted time on the set of
562 machines that continually build ports (see below).</para>
563
564 <para>It is also recommended that if there are reasonable default
565 answers to the questions,
566 <varname>PACKAGE_BUILDING</varname> be used to turn off the
567 interactive script when it is set. This will allow us to build
568 the packages for CDROMs and FTP.</para>
569 </sect1>
570 </chapter>

Properties

Name Value
svn:keywords FreeBSD=%H
svn:mime-type text/sgml

  ViewVC Help
Powered by ViewVC 1.1.27