4ed359f80d3962808339c6811ef88bb8d9e5aae2
[ikiwiki.git] / docs / howtos / howtoporttodragonfly / index.mdwn
1 # How to port to DragonFly
2
3 [[!toc levels=4 ]]
4
5 This page is intended to provide some useful information to help you port applications to your DragonFly operating system. This system uses the NetBSD Packages Collection (pkgsrc) to manage application ports. A basic knowledge of this collection, of GNU developer tools, and possibly of imake, is required to successfully complete this task. For more information, references to these tools are available in the References section below.
6
7 This paper will focus on applications made for the pkgsrc collection. But many information will also be useful to those who simply wants to port applications to DragonFly without specific context.
8
9 ## Preparing the workspace
10
11 To port software with pkgsrc, two approaches are possible:
12 * Add new packages in pkgsrc.
13 * Modify an existing package.
14
15 In both cases, the source code of the package must be extracted into a work directory before starting the porting work. When a source file of the original application is modified, its original will be stored with the extension “. orig”. The utility mkpatches, that we'll see later in this document, will use the original files as a basis to create patches. Please note that *the version with the extension .orig must always be that of the original distribution package*.
16
17 ### Add a new package
18
19 The page [Creating a new pkgsrc package from scratch](http://www.netbsd.org/docs/pkgsrc/creating.html)
20  gives the main steps required to add a new application to the pkgsrc collection.This tutorial is very well done and summarizes the main steps required to create a new package.
21
22 ### Modify an existing package
23
24 Suppose you would want to modify the application foo/bar from the pkgsrc collection. You then start by visiting its dedicated directory in pkgsrc, and by running the following command:
25
26         cd /usr/pkgsrc/foo/bar
27         bmake patch
28
29 This will restore the changes previously made, which will be a good starting point for the porting. The bmake command could also be used without options to attempt an immediate first compilation. But you might have to change some files first, like the GNU scripts for example.
30
31 Suppose that the foo application of the collection is version 1.0. Let's go into the newly extracted source directory located right here<a name="AEN1" href="#FTN.AEN1">[1]</a>:
32
33         cd /var/obj/pkgsrc/foo/bar/work/foo-1.0
34
35 Voilà, your ready! The porting of the source code can now begin.
36
37 ## Working with GNU developper tools
38
39 If the application to port uses GNU tools like autoconf, GNU scripts shall be the first thing to look at. We'll first make a brief introduction to these tools. Then we will cover some modifications required to adapt their scripts to DragonFly. 
40
41 ### Introduction to GNU tools
42
43 GNU provides a series of very popular tools which aims at helping C and C++ cross-platform application development. These tools are Autoconf, Automake and Libtool. They can operate independently, but they can also be highly integrated.
44
45 Their use in common might not be necessarily easy to master. The GNU Autobook (see the References section), available online for free, can help you find your way with it.
46
47 Briefly, the following files are defined by the developers:
48
49 * Makefile.am and config.h (automake), to generate the Makefile.in files.
50 * configure.ac (autoconf), to generate the configure script.
51
52 The aclocal tool generates the file aclocal.m4, which contains dependencies for the configure script. It is usually run before other tools. The autoconf generated configure script will in turn generate the makefiles from other generated files, like Makefile.in. So, there are several levels of file generation. 
53
54 The first level generation is called bootstrapping (see the Bootstrap section). This process generates a set of files and directories right in the current build directory. For example, in DragonFly 2.8, the files generated by default are:
55
56         autom4te.cache/
57         .deps/
58         configure
59         missing
60         Makefile.in
61         install-sh
62         depcomp
63         config.sub
64         config.guess
65         aclocal.m4
66
67 When porting an application, it is usually not necessary to regenerate these files and directories. You simply need to adjust the Makefile and configure files. But occasionally, you'll have no other choice. The following sections attempt to give you some leads to follow.
68
69 #### Editing configure, config.guess and config.sub
70
71 When the script configure is run, it creates settings suitable for the host platform. In cases where DragonFly is not on the list of supported systems, we'll need to add it. 
72
73 By default, the command uname -m is used to detect the host platform. In our case, it will return the DragonFly label. The host_os variable will be defined after this value and will take the form “dragonflyX” (where X is the version of the host system, ex. 2.8). The configure script then uses this information to define OSARCH. A good place to start the port would be to add the following definition:
74
75         case "${host_os}" in
76              […]
77              dragonfly*)
78              OSARCH=DragonFly
79              ;;
80
81 The host_os variable is normally generated by running config.guess. It can also be explicitly defined by using the “build” option of the configure script.
82
83 Then you can continue by searching through the script to locate:
84
85 * Other occurrences of case "${host_os}".
86 * Occurrences of the “BSD” string.
87 * Changes made to other BSD systems, like NetBSD for example. If the software has already been brought to one of these systems, and it will often be the case, this will allow you to quickly find many of the modifications required for DragonFly. Of course this is not to take for granted.
88
89 Ideally, you would have to review the entire configure script to make sure that all necessary changes were made. Some will prefer to go by trial and error, by first changing what's obvious and then actively testing the results.
90
91 The config.guess file may also need to be reviewed. But the latest versions of this script already include DragonFly in its supported systems. Running it on DragonFly 2.8, for example, returns *i386-unknown-dragonfly2.8*.
92
93 The config.sub file contains a set of subroutines used by the configure script. If this file is not a symlink, it may also need to be changed. But the DragonFly system is already included by default in it, but possibly lightly implemented.
94
95 One special thing to consider in the review of GNU scripts for DragonFly is that some configuration scripts tries to collect all BSD like systems like this:
96
97         case "$uname" in
98                 *BSD*)
99         […]
100         esac
101
102 In our case, uname will contain the string DragonFly, without the “BSD” suffix. This pattern should be searched to explicitly add DragonFly after the sequence:
103
104         case "$uname" in
105                 *BSD*|DragonFly)
106         […]
107         esac
108
109 You might want to solve this problem by forcing variables like host_os and OSARCH to “DragonflyBSD”. But it may be more difficult than simply searching for occurrences of *BSD and applying the necessary changes.
110
111 ### Regenerate GNU scripts
112
113 There may be cases where you would want to regenerate the GNU scripts rather than just port them. Some basic knowledge are required to perform this task. For those who do not have this knowledge, the GNU Autobook is an excellent reference for it. We'll briefly cover the topic here, by giving some basic information and clarifying some difficulties.
114
115 #### Autoconf compatibility
116
117 As mentioned before, autoconf is used to regenerate the configure script. Operating systems are not bundled with the same version of it. We must therefore see to use the correct version of GNU tools if we want to regenerate completelly an application's build scripts.
118
119 #### The makefile.am file
120
121 This file contains macros needed to generate the Makefile.in files, which in turn generates the makefiles. The automake tool defines a syntax of its own. It can generate complex and portable makefiles from a small makefile.am script.
122
123 #### The configure.ac or configure.in file
124
125 This file contains macros necessary to generate the configure script. These are m4 macros, which generates a shell script when you run autoconf. Required changes to this file are similar to those proposed for the configure script itself.
126
127 #### Bootstrap
128
129 The procedure aiming at regenerating all the GNU build files is called *bootstrap*. Some ports are bundled with a script of this name. It runs all the required tools in the correct order. The typical case will define the following sequence:
130
131         aclocal \
132         && automake --gnu --add-missing \
133         && autoconf
134
135 ### Compiling with FreeBSD as build target
136
137 As DragonFly is a FreeBSD fork, many are building it's ports by using the FreeBSD build target. Although it sometimes works well, like for PostgreSQL, this is risky because compile compatibility with FreeBSD is not among DragonFly's goals. You must therefore expect that this shortcut is less and less usable over time, or can possibly generate badly optimized binaries.
138
139 In cases where this method still works, they may still be some changes required in GNU scripts. As mentioned earlier, scripts sometime tries to catch all the BSD variants by using the “*BSD” string. In these cases, without minimal changes, the final results might not entirely be what was anticipated for FreeBSD.
140
141 ## Working with imake and xmkmf
142
143 Arguably, imake and xmkmf could be seen as the old building tools for those wishing to develop portable applications. These tools were designed for the venerable X Window System and its applications, themselves brought to many operating systems, including UNIX®, the BSD family, GNU/Linux, AIX®, Solaris® and Windows®. This section will cover briefly these build tools, because they have been gradually discarded in favor of the GNU build tools.
144
145 X Window normally comes with a lib/X11/config directory, which contains macro files dedicated to xmkmf. This directory contains files with extensions *.cf, *.tmpl and *.rules.
146
147 * *.cf files contains settings specific to it's hosts. X Window comes normally with a DragonFly.cf file.
148 * *. rules files defines macros that implement the rules that can be used in Imakefile files.
149 * *. tmpl files contains templates that defines compile options.
150
151 As for GNU automake, these macros are used to generate makefiles for the operating system that hosts the X Window System. The normal xmkmf's procedure is to define Imakefile files, then to build the makefiles by running xmkmf. This tool will in turn call imake, which is a C preprocessor interface for the make tool. The tool xmkmf will invoke imake with the appropriate arguments for DragonFly.
152
153 When xmkmf is executed with the -a option, it automatically runs make Makefiles, make includes and make depends.
154 Here's a simple Imakefile example:
155
156         BINDIR = /usr/local/bin
157         
158         .SUFFIXES: cpp
159         
160         CXXEXTRA_INCLUDES = -I. -I.. -I/usr/pkg/include
161         LOCAL_LIBRARIES = -L/usr/pkg/lib
162         EXTRA_LIBRARIES = $(XMLIB) $(XTOOLLIB) $(XLIB) $(XMULIB) $(XPMLIB)
163         CXXDEBUGFLAGS = -O2 -g
164         
165         HEADERS = bar.h
166         SRCS = bar.cpp
167         OBJS = bar.o
168         
169         ComplexCplusplusProgramTarget(bar)
170
171 Note the similarity of Imakefile with makefiles. You can see the Imakefile as makefiles with macros.
172
173 In the example above, the ComplexCplusplusProgramTarget macro defines a rule to generate the C++ "bar" binary, according to the parameters that precedes it. Notably, the parameter .SUFFIXES indicates that the source files will have the extension “.cpp”.
174
175 In DragonFly, imake and xmkmf are available by installing the package devel/imake. For more information, links are given in the References section.
176
177 ## Editing the code
178
179 To tailor a program to DragonFly, you can either use the definition used to identify the DragonFly system or use the definitions generated by the GNU tools.
180
181 ### The DragonFly definition
182
183 Idealy, an application's code would be reviewed in full to ensure that it uses the right functions and algorithms for DragonFly.
184
185 In fact, the method mostly used is probably to try to compile, to correct the code when it does not, and to test the final results. When the code is adapted to DragonFly, it may look like this: 
186
187         #if defined(__DragonFly__)
188                 /* code specific to DragonFly */
189         #elsif
190                 /* code for other systems */
191         #endif
192
193 An initial change might be to scan the definitions for the other BSD variants, as FreeBSD or NetBSD. We often see this kind of syntax in the code tree:
194
195         #if defined(__OpenBSD__) || defined(__NetBSD__) || defined(__FreeBSD__) || defined(__Darwin__) || defined(__DragonFly__)
196         #include <fcntl.h>
197         #include <net/route.h>
198         #endif
199
200 ### GNU Tools definition
201
202 Porting code can focus on identifying available functions rather than on identifying host systems. A typical case would be the bcopy function, normally used instead of strcpy on BSD derivatives. Rather than referring to the host system, the code might look like this (from the GNU Autobook<a name="AEN2" href="#FTN.AEN2">[2]</a>):
203
204         #if !HAVE_STRCPY
205         #  if HAVE_BCOPY
206         #    define strcpy(dest, src)   bcopy (src, dest, 1 + strlen (src))
207         #  else /* !HAVE_BCOPY */
208              error no strcpy or bcopy
209         #  endif /* HAVE_BCOPY */
210         #endif /* HAVE_STRCPY */
211
212 This guarantees a form of compatibility between systems at the code level. Unfortunately, this approach is moderately used, which generates more work for porters.
213
214 ### The BSD4.4 Heritage
215
216 Many developers are unaware that a BSD definition was created for BSD4.4 and it's derivatives, as DragonFly, FreeBSD and NetBSD. This definition is used like this (from pkgsrc developer's guide<a name="AEN3" href="#FTN.AEN3">[3]</a>):
217
218         #include <sys/param.h>
219         #if (defined(BSD) && BSD >= 199306)
220         /* BSD-specific code goes here */
221         #else
222         /* non-BSD-specific code goes here */
223         #endif
224
225 The NetBSD group, which maintains pkgsrc, recommends the use of this definition. In fact, it is rarely used. In the specific case of DragonFly, this definition no longer exists. Therefore it must not be used.
226
227 ## Patching for pkgsrc
228
229 Ideally, a port to DragonFly shall always be at the project level. But realistically, it is faster and easier to modify applications at the pkgsrc level.
230
231 Tools for pkgsrc allows you to keep only the patches and some basic information of a package. If you want to use pkgsrc, you'll have to use the tool mkpatches.
232
233 To use this tool, you need to install the pkgtools/pkgdiff package. As indicated earlier in this document, you first need to either extract an existing package or create and extract your own. Then you must keep the original version of each files modified by making a copy of it with the extension .orig. When changes are complete, you can run mkpatches from the directory, say, /usr/pkgsrc/foo/bar. This action will create a set of patches by using the .orig files previously created as a basis. A new directory will be created, here /usr/obj/pkgsrc/foo/bar/work/.newpatches. You then copy this directory like this:
234
235         mkpatches
236         mv patches patches.old
237         cp -Rp /usr/obj/pkgsrc/foo/bar/work/.newpatches patches
238         bmake checksum
239
240 The last command, bmake checksum, will regenerate the verification file distinfo. From that moment, you can run bmake clean and rebuild the package at will. If you have any other changes to add, you can remove the package again and repeat these steps.
241
242 ## Submitting a package in pkgsrc
243
244 If you plan to port a program to DragonFly and wish to share your work, pkgsrc is ideal for you. The first thing to do is to inquire whether the application is already in the collection. If not, you're free to add your work and be registered as a port maintainer.
245
246 This section will attempt to give you some minimal guidance on submitting changes in the pkgsrc collection. This information is incomplete, please consult the page [Submitting and Commiting](http://www.netbsd.org/docs/pkgsrc/submit.html) carefully before submitting anything for real.
247
248 A source code package can be submitted with the gtk-send-pr package (pr=Problem Report), or by visiting the page [NetBSD Problem Report](http://www.netbsd.org/support/send-pr.html). The indications given by the pkgsrc developer's guide in connection with this tool are summarized here:
249
250 “In the form of the problem report, the category should be “pkg”, the synopsis should include the package name and version number, and the description field should contain a short description of your package (contents of the COMMENT variable or DESCR file are OK). The uuencoded package data should go into the “fix” field.” ̶  http://www.netbsd.org/docs/pkgsrc/submit.html#submitting-your-package
251 It is also possible to import new packages in pkgsrc-wip. See [http://pkgsrc-wip.sourceforge.net/](http://pkgsrc-wip.sourceforge.net/) for more information.
252
253 ## References
254
255 [The pkgsrc guide](http://www.netbsd.org/docs/pkgsrc/)
256
257 [The pkgsrc developer's guide](http://www.netbsd.org/docs/pkgsrc/developers-guide.html)
258
259 [[pkgsrc on DragonFly|/docs/howtos/HowToPkgsrc/]]
260
261 [GNU autoconf](http://www.gnu.org/software/autoconf/)
262
263 [GNU automake](http://www.gnu.org/software/automake/)
264
265 [GNU libtool](http://www.gnu.org/software/libtool/)
266
267 [GNU “autobook”, or “GNU AUTOCONF, AUTOMAKE, AND LIBTOOLS”, from Gary V. Vaughan](http://sources.redhat.com/autobook/)
268
269 [imake](http://www.x.org/archive/X11R6.7.0/doc/imake.1.html)
270
271 [xmkmf](http://www.x.org/archive/X11R6.7.0/doc/xmkmf.1.html)
272
273 ## Notes
274
275 <table border="0">
276
277   <tr>
278       <td align="LEFT" valign="TOP" width="5%">
279         <a name="FTN.AEN1" 
280             href="#AEN1">[1]
281         </a>
282       </td>
283       <td align="LEFT" valign="TOP">
284         <p>
285           Previously, the work directory was created directly in the directory dedicated to the ported application, under the pkgsrc directory. But to preserve the integrity of these directories and to be able to compile on another volume, the working files have been moved under /usr/obj. The source code located in /usr/src followed the same path.
286         </p>
287       </td>
288   </tr>
289
290   <tr>
291       <td align="LEFT" valign="TOP" width="5%">
292         <a name="FTN.AEN2" 
293             href="#AEN2">[2]
294         </a>
295       </td>
296       <td align="LEFT" valign="TOP">
297         <p>
298           Source: <a href="http://sources.redhat.com/autobook/autobook/autobook_50.html#SEC50">http://sources.redhat.com/autobook/autobook/autobook_50.html#SEC50</a>. “Copyright (C) 2000, 2006 Gary V. Vaughan. Verbatim copying and distribution of this entire article is permitted in any medium, provided this notice is preserved.”
299         </p>
300       </td>
301   </tr>
302
303   <tr>
304       <td align="LEFT" valign="TOP" width="5%">
305         <a name="FTN.AEN3" 
306             href="#AEN3">[3]
307         </a>
308       </td>
309       <td align="LEFT" valign="TOP">
310         <p>
311           Source: <a href="http://www.netbsd.org/docs/pkgsrc/fixes.html#fixes.build.cpp">http://www.netbsd.org/docs/pkgsrc/fixes.html#fixes.build.cpp</a>. Copyright © 1994-2007 The NetBSD Foundation, Inc.
312         </p>
313       </td>
314   </tr>
315
316 </table>