1 |
rane 05/12/16 15:03:59 |
2 |
|
3 |
Added: xml/htdocs/doc/en/articles autotools-practices.xml |
4 |
Log: |
5 |
#115757, new article about autotools, written by flameeyes for linux.com |
6 |
|
7 |
Revision Changes Path |
8 |
1.1 xml/htdocs/doc/en/articles/autotools-practices.xml |
9 |
|
10 |
file : http://www.gentoo.org/cgi-bin/viewcvs.cgi/xml/htdocs/doc/en/articles/autotools-practices.xml?rev=1.1&content-type=text/x-cvsweb-markup&cvsroot=gentoo |
11 |
plain: http://www.gentoo.org/cgi-bin/viewcvs.cgi/xml/htdocs/doc/en/articles/autotools-practices.xml?rev=1.1&content-type=text/plain&cvsroot=gentoo |
12 |
|
13 |
Index: autotools-practices.xml |
14 |
=================================================================== |
15 |
<?xml version='1.0' encoding="UTF-8"?> |
16 |
<!DOCTYPE guide SYSTEM "/dtd/guide.dtd"> |
17 |
<!-- $Header: /var/cvsroot/gentoo/xml/htdocs/doc/en/articles/autotools-practices.xml,v 1.1 2005/12/16 15:03:59 rane Exp $ --> |
18 |
|
19 |
<guide link="/doc/en/articles/autotools-practices.xml"> |
20 |
<title>Best practices with autotools</title> |
21 |
|
22 |
<author title="Author"> |
23 |
<mail link="flameeyes@g.o">Diego Pettenò</mail> |
24 |
</author> |
25 |
|
26 |
<abstract> |
27 |
This article covers some of the most common errors people make when using |
28 |
autotools and ways to achieve better results. |
29 |
</abstract> |
30 |
|
31 |
<!-- The content of this document is licensed under the CC-BY-SA license --> |
32 |
<!-- See http://creativecommons.org/licenses/by-sa/2.5 --> |
33 |
<license/> |
34 |
|
35 |
<version>1.0</version> |
36 |
<date>2005-12-16</date> |
37 |
|
38 |
<chapter> |
39 |
<title>Best practices with autotools</title> |
40 |
<section> |
41 |
<body> |
42 |
|
43 |
<p> |
44 |
The core of GNU's compile chain -- the set of tools used to build GNU software |
45 |
packages -- is the so-called "autotools," a term that refers to the autoconf |
46 |
and automake programs, as well as libtool, autoheader, pkg-config, and |
47 |
sometimes gettext. These tools let you compile GNU software on a wide variety |
48 |
of platforms and Unix and Unix-like operating systems, providing developers a |
49 |
framework to check for the presence of the libraries, functions, and tools that |
50 |
they want to use. While autotools are great in the hands of an experienced |
51 |
developer, they can be quite a handful for the first-time user, and it's not so |
52 |
rare that packages are shipped with working-but-broken autotools support. This |
53 |
article will cover some of the most common errors people make when using |
54 |
autotools and ways to achieve better results. |
55 |
</p> |
56 |
|
57 |
<p> |
58 |
Regardless of anyone's opinion about them, we currently have no valid |
59 |
alternative for autotools. Projects such as Scons are not as portable as |
60 |
autotools, and they don't embody enough knowledge to be useful yet. We have |
61 |
tons of automatic checks with autotools, and a lot of libraries come with an m4 |
62 |
library with macros to check for their presence. |
63 |
</p> |
64 |
|
65 |
<p> |
66 |
The basic structure of an autotooled project is simple. Autoconf takes help of |
67 |
an <path>aclocal.m4</path> file (created by aclocal using the m4 libraries on |
68 |
its search path and <path>acinclude.m4</path> file) to parse the |
69 |
<path>configure.ac</path> file (formerly <path>configure.in</path>) and |
70 |
transform it into a "configure" script. For every directory there should exist |
71 |
an <path>Makefile.am</path>, which automake uses to create Makefile.in |
72 |
templates. The Makefile.in templates are then processed and transformed by the |
73 |
<path>configure</path> script into real Makefiles. You can avoid avoid using |
74 |
automake and just write your own Makefile.in files, but this is quite complex, |
75 |
and you lose a few features of autotools. |
76 |
</p> |
77 |
|
78 |
<p> |
79 |
In a <path>configure.ac</path> file you can use macros you define yourself, the |
80 |
default ones provided by autoconf and aclocal, or external macros provided, for |
81 |
instance, by other packages. In such a case aclocal will create the |
82 |
<path>aclocal.m4</path> file adding the library files it finds on the system's |
83 |
library with the defined macros; this is a critical step to have a working |
84 |
autotooled project, as we'll see in a moment. |
85 |
</p> |
86 |
|
87 |
<p> |
88 |
A <path>Makefile.am</path> is mainly a declaration of intents: you can fill |
89 |
some targets variables with the name of the targets you want to build. These |
90 |
variables are structured in a format like placetoinstall_TYPEOFTARGET. The |
91 |
place is the location in a hierarchical Unix filesystem (bin, lib, include, |
92 |
...), a non-used keyword that can be defined with an arbitrary path (using the |
93 |
keyworddir variable), or the special keyword noinst that marks the targets that |
94 |
need not to be installed (for example private headers, or static libraries used |
95 |
during build). After naming the target, you can use the name (replacing dots |
96 |
with underscores) as the prefix for the variables that affects its build. In |
97 |
this way you can provide special CFLAGS, LDFLAGS, and LDADD variables used |
98 |
during the build of a single target, instead of changing them for all the |
99 |
targets. You can also use variables collected during configure phase, if you |
100 |
passed them to the AC_SUBST macro in <path>configure.ac</path>, so that they |
101 |
are replaced inside makefiles. Also, though defining CFLAGS and LDFLAGS on a |
102 |
per-target basis seems useful, adding static flags in Makefile.am is a bad |
103 |
thing for portability, as you can't tell if the compiler you're using supports |
104 |
them, or if you really need them (-ldl put in LDFLAGS is a good example of a |
105 |
flag needed on Linux but not on FreeBSD); in such cases you should use |
106 |
<path>configure.ac</path> to add these flags. |
107 |
</p> |
108 |
|
109 |
<p> |
110 |
The most commonly used macros in configure.ac are AC_CHECK_HEADERS, |
111 |
AC_CHECK_FUNCTS, and AC_CHECK_LIB, which test for the presence of, |
112 |
respectively, some header files, some library functions, and a given library |
113 |
(with a specific function in it). They are important for portability as they |
114 |
provides a way to check which headers are present and which are not (for |
115 |
example system headers that have different locations in different operating |
116 |
systems), and to check whether a function is present in the system library |
117 |
(asprintf() is missing in OpenBSD for example, while it's present on GNU C |
118 |
library and FreeBSD), and finally to check for the presence of some third-party |
119 |
library or to see if a specific link to a library is needed to get some |
120 |
functions (for example dlopen() function is in libdl library on GNU systems, |
121 |
while it's provided by the system's C library on FreeBSD). |
122 |
</p> |
123 |
|
124 |
<p> |
125 |
Along with testing for the presence or absence of functions or headers (and |
126 |
sometimes libraries) you usually need to change the code's path (for example to |
127 |
avoid the use of missing functions, or to define a drop-in replacement for |
128 |
them). Autoconf is commonly coupled with another tool, autoheader, which |
129 |
creates a <path>config.h.in</path> template, used by configure script to create |
130 |
a <path>config.h</path> header in which are defined a few preprocessor macros |
131 |
in form of HAVE_givenfunction or HAVE_givenheader_H which can be tested with |
132 |
#ifdef/#ifndef directives inside a C or C++ source file to change the code |
133 |
according to the features present. |
134 |
</p> |
135 |
|
136 |
<p> |
137 |
Here are some practices to keep in mind to help you use autotools to create the |
138 |
most portable code possible. |
139 |
</p> |
140 |
|
141 |
<p> |
142 |
<b>The config.h header file should be considered to be an internal header |
143 |
file</b>, so it should be used just by the single package in which it's |
144 |
created. You should avoid editing the <path>config.h.in</path> template to add |
145 |
your own code there, as this requires you to manually update it according to |
146 |
the <path>configure.ac</path> you're writing. |
147 |
</p> |
148 |
|
149 |
<p> |
150 |
Unfortunately a few projects, such as Net-SNMP, export this header file with |
151 |
other libraries' headers, which requires any projects that use their libraries |
152 |
to include them (or provide their own copy of the internal Net-SNMP |
153 |
structures). This is a bad thing, as the autotools structure of a library |
154 |
project should be invisible to software using it (which might not use autotools |
155 |
at all). Also, changes in autotools behavior are anything but rare, so you can |
156 |
have two identical checks with different results due to changes in the way they |
157 |
are executed. If you need to define your own wrappers or replacements in case |
158 |
something is not in the environment you're compiling for, you should do that in |
159 |
private headers that do not get installed (declared as noinst_HEADERS in |
160 |
<path>Makefile.am</path> files). |
161 |
</p> |
162 |
|
163 |
<p> |
164 |
<b>Always provide the m4 files you used</b>. As autotools have been in use for |
165 |
years, many packages (for example libraries) that can be reused by other |
166 |
programs provide an m4 library file in <path>/usr/share/aclocal</path> that |
167 |
makes it possible to check for their presence (for example using the -config |
168 |
scripts) with a simple macro call. These files are used by aclocal to create |
169 |
the <path>aclocal.m4</path> file, and they usually are present on the |
170 |
developers' systems where aclocal is executed to create the release, but when |
171 |
they are for optional dependencies, they can be missing on users' systems. |
172 |
While this is usually not a problem, because users rarely executes aclocal, |
173 |
it's a problem for source distributions, such as Gentoo, where sometimes you |
174 |
need to patch a Makefile.am or the <path>configure.ac</path> and then re-run |
175 |
autoconf without having all the optional dependencies installed (or having |
176 |
different versions, which can be incompatible or bugged, of the same m4 file). |
177 |
</p> |
178 |
|
179 |
<p> |
180 |
To avoid this problem, you should create an m4 subdirectory in your package's |
181 |
directory and then put there the m4 library files you are using. You must then |
182 |
call aclocal with aclocal -I m4 options to search in that directory before the |
183 |
system library. You can then choose whether to put that directory under |
184 |
revision control (CVS, SVN, or whatever else you are using) or just create it |
185 |
for the releases. The latter case is the bare minimum requirement for a |
186 |
package. It minimizes the amount of revision-controlled code and ensures that |
187 |
you're always using the latest m4 version, but has the drawback that anyone who |
188 |
checks out your repository won't be able to execute autoconf without having to |
189 |
look on a release tarball to take the m4 from (and that might not work, as you |
190 |
can have updated the configure.ac to suit a newer macro or added more |
191 |
dependencies). On the other hand, putting the m4 directory under revision |
192 |
control sometimes tempts the developers to change the macros to suit their |
193 |
needs. Although this seems logical, as the m4 files are under your revision |
194 |
control, it will upset many package maintainers, as sometimes new versions of |
195 |
m4 files fix bugs or support newer options and installation paths (for example |
196 |
multilib setups), and having the m4 files modified makes it impossible to just |
197 |
replace them with updated versions. It also mean that when you're going to |
198 |
update an m4 file you must redo the modification against the original. |
199 |
</p> |
200 |
|
201 |
<p> |
202 |
m4 files are always a problem to work with. They must replicate almost the same |
203 |
code from library to library (depending on the way you need to provide |
204 |
CFLAGS/LDFLAGS: with tests or with a -config script). To avoid this problem, |
205 |
the GNOME and FreeDesktop projects developed a tool called pkg-config, which |
206 |
provides both an executable binary and an m4 file to include in configure.ac |
207 |
files, and lets developers check for the presence of a given library (and/or |
208 |
package), provided that the package itself installed a pkg-config .pc data |
209 |
file. This approach simplifies the work of maintaining configure.ac scripts, |
210 |
and requires a lot less time to be processed during execution of configure |
211 |
script, as it uses the information provided by the installed package itself |
212 |
instead of just trying if it's present. On the other hand, this approach means |
213 |
that an error the developers make concerning a dependency can break the user |
214 |
program, as they just hardcode the compiler and linker flags in the data file |
215 |
and the configure script doesn't actually check whether the library works. |
216 |
Fortunately, this doesn't happen too often. |
217 |
</p> |
218 |
|
219 |
<p> |
220 |
To create the configure file, you need PKG_CHECK_MODULES, contained in the |
221 |
<path>pkg.m4</path> library. You should add that file to your m4 directory. If |
222 |
pkg-config dependency is mandatory (as the tool is run by the configure script) |
223 |
you can't be sure that the m4 file you are using is the same as one on users' |
224 |
systems, nor you can be sure that it does not include extra bugs, as it can be |
225 |
older than yours. |
226 |
</p> |
227 |
|
228 |
<p> |
229 |
<b>Always check for the libraries you're going to link to</b>, if you have them |
230 |
as mandatory dependencies. Usually autoconf macros or pkg-config data files |
231 |
define prerequisite libraries that you need to successfully link to your |
232 |
library. Also, some functions that are in extra libraries in some systems |
233 |
(like dlopen() in libdl on Linux and Mac OS X) can be in the libc of another |
234 |
system (the same function is in libc on FreeBSD). In these cases you need to |
235 |
check whether the function can be found without linking to anything, or if you |
236 |
need to use a specific library (for example to avoid linking to a non-existent |
237 |
libdl that would fail where it's not needed). |
238 |
</p> |
239 |
|
240 |
<p> |
241 |
<b>Be careful with GNU extensions</b>. One of the things that makes portability |
242 |
a big pain is the use of extension functions, which are provided by GNU libc |
243 |
but aren't present on other C libraries like BSD's or uClibc. When you use such |
244 |
functions, you should always provide a "drop-in replacement," a function that |
245 |
can provide the same functionality as the library function, maybe with less |
246 |
performance or security, which can be used when the extension function is not |
247 |
present on system's C library. Those functions must be protected by a #ifdef |
248 |
HAVE_function ... #endif block, so that they don't get duplicated when they are |
249 |
already present. Make sure that these functions are not exported by the library |
250 |
to the external users; they should be declared inside an internal header, to |
251 |
avoid breaking other libraries that may be doing similar tricks. |
252 |
</p> |
253 |
|
254 |
<p> |
255 |
<b>Avoid compiling OS-specific code when not needed</b>. When a program |
256 |
optionally supports specific libraries or specific operating systems, it's not |
257 |
rare to have entire source files that are specific to that code path. To avoid |
258 |
compiling them when they're not needed, use the AM_CONDITIONAL macro inside a |
259 |
configure.ac file. This automake macro (usable only if you're using automake to |
260 |
build the project) allows you to define if .. endif blocks inside a Makefile.am |
261 |
file, inside which you can set special variables. You can, for example, add a |
262 |
"platformsrcs" variable that you set to the right source file for the platform |
263 |
to build for, then use in a _SOURCES variable. |
264 |
</p> |
265 |
|
266 |
<p> |
267 |
However, there are two common errors developers make when using AM_CONDITIONAL. |
268 |
The first is the use of AM_CONDITIONAL in an already conditional branch (for |
269 |
example under an info or in a case switch), which leads to automake complaining |
270 |
about a conditional defined only conditionally (AM_CONDITIONAL must be called |
271 |
on global scope, out of every if block, so you must define a variable to |
272 |
contain the status of the conditions and then test against when calling the |
273 |
AM_CONDITIONAL). The other one is that you can't change the targets' variables |
274 |
directly, and you must define "commodity" variables, whose results empty out of |
275 |
the conditional, to add or remove source files and targets. |
276 |
</p> |
277 |
|
278 |
<p> |
279 |
Many projects, to avoid compiling code for specific code paths, add the entire |
280 |
files in #ifdef ... #endif preprocessor conditionals. While this usually works, |
281 |
it makes the code ugly and error-prone, as a single statement out of the |
282 |
conditional block can be compiled where the source file is not needed. It also |
283 |
misleads users sometimes, as the source files seem to be compiled in situations |
284 |
where they don't make sense. |
285 |
</p> |
286 |
|
287 |
<p> |
288 |
<b>Be smart in looking for operating system or hardware platform</b>. Sometimes |
289 |
you need to search for a specific operating system or hardware platform. The |
290 |
right way to do this depends on where you need to know this. If you must know |
291 |
it to enable extra tests on configure, or you must add extra targets on |
292 |
makefiles, you must do the check in configure.ac. On the other hand, if the |
293 |
difference must be known in a source file, for example to enable an optional |
294 |
asm-coded function, you should rely directly on the compiler/preprocessor, so |
295 |
you should use #ifdef directives with the default macros enabled on the target |
296 |
platform (for example __linux__, __i386__, _ARC_PPC, __sparc__, _FreeBSD_ and |
297 |
__APPLE__). |
298 |
</p> |
299 |
|
300 |
<p> |
301 |
<b>Don't run commands in configure.ac</b>. If you need to check for hardware or |
302 |
operating system in a configure.ac, you should avoid using the uname command, |
303 |
despite this being one of the most common way to do such a test. This is |
304 |
actually an error, as this breaks crosscompilation. Autotools supports |
305 |
crosscompile projects from one machine to another using hosts definitions: |
306 |
strings in the form "hardware-vendor-os" (actually, "hardware-vendor-os-libc" |
307 |
when GNU libc is used), such as i686-pc-linux-gnu and |
308 |
x86_64-unknown-freebsd5.4. CHOST is the host definition for the system you're |
309 |
compiling the software for, CBUILD is the host definition for the system you're |
310 |
compiling on; when CHOST and CBUILD differ, you're crosscompiling. |
311 |
</p> |
312 |
|
313 |
<p> |
314 |
In the examples above, the first host definition shows an x86-like system, with |
315 |
a pentium2-equivalent (or later) processor, running a Linux kernel with a GNU |
316 |
libc (usually this refers to a GNU/Linux system). The second refers to an AMD64 |
317 |
system with a FreeBSD 5.4 operating system. (For a GNU/kFreeBSD system, which |
318 |
uses FreeBSD kernel and GNU libc, the host definition is |
319 |
hw-unknown-freebsd-gnu, while for a Gentoo/FreeBSD, using FreeBSD's kernel and |
320 |
libc, but with Gentoo framework, the host definition is hw-gentoo-freebsd5.4.) |
321 |
By using $host and $build variables inside a configure.ac script you can enable |
322 |
or disable specific features based on the operating system or on the hardware |
323 |
platform you're compiling to or on. |
324 |
</p> |
325 |
|
326 |
<p> |
327 |
<b>Don't abuse "automagic" dependencies</b>. One of the most useful features of |
328 |
autotools are the automatic checks for the presence of a library, which are |
329 |
often used to automatically enable support for extra dependencies and such. |
330 |
However, abusing this feature makes the build of a package a bit of a problem. |
331 |
While this is quite useful for first-time users, and although most of the |
332 |
projects having complex dependencies (such as multimedia programs like xine and |
333 |
VLC) use a plugin-based framework that allows them to avoid most of the |
334 |
breakages, "automagic" dependencies are a great pain for packagers, especially |
335 |
ones working on source-based distributions such as Gentoo and ports-like |
336 |
frameworks. When you build something with automagical dependencies you enable |
337 |
the functions supported by the libraries found on the system on which the |
338 |
configure script is run. This means that the output binaries might not work on |
339 |
a system that shares the same base packages but misses one extra library, for |
340 |
example. Also, you can't tell the exact dependencies of a package, as some |
341 |
might be optional and not be built when the libraries are not present. |
342 |
</p> |
343 |
|
344 |
<p> |
345 |
To avoid this, autoconf allows you to add --enable/--disable and |
346 |
--with/--without options to configure scripts. With such options you can |
347 |
forcefully enable or disable a specific option (such as the support for an |
348 |
extra library or for a specific feature), and leave the default to automatic |
349 |
tests. |
350 |
</p> |
351 |
|
352 |
<p> |
353 |
Unfortunately, many developers misunderstand the meaning of the two parameters |
354 |
of the functions used to add those options (AC_ARG_ENABLE and AC_ARG_WITH). |
355 |
They represent the code to execute when a parameter is passed and when one is |
356 |
not. Many developers mistakenly think that the two parameters define the code |
357 |
to execute when the feature is enabled and when is disabled. While this usually |
358 |
works when you pass a parameter just to change the default behavior, many |
359 |
source-based distributions pass parameters also to confirm the default |
360 |
behavior, which leads to errors (features explicitly requested missing). Being |
361 |
able to disable optional features if they don't add dependencies (think of OSS |
362 |
audio support on Linux) is always a good thing for users, who can avoid |
363 |
building extra code if they don't plan to use it, and prevents maintainers from |
364 |
doing dirty caching tricks to enable or disable features as their users |
365 |
request. |
366 |
</p> |
367 |
|
368 |
<p> |
369 |
While autotools were a big problem for both developers and maintainers because |
370 |
there are different incompatible versions that do not get along well together |
371 |
(since they install in the same places, with the same names) and which are used |
372 |
in different combinations, the use of autotools saves maintainers from doing |
373 |
all sorts of dirty tricks to compile software. If you look at ebuild from |
374 |
Gentoo's portage, the few that do not use autotools are the more complex ones, |
375 |
as they need to check variables on very different setups (we can or not have |
376 |
NPTL support; we can be on Linux, FreeBSD, or Mac OS X; we can be using GLIBC |
377 |
or another libc; and so on), while autotools usually take care of that on their |
378 |
own. It's also true that many patches applied by maintainers are to fix broken |
379 |
autotools script in upstream sources, but this is just a little problem |
380 |
compared to the chaos of using special build systems that don't work at all |
381 |
with little environmental changes. |
382 |
</p> |
383 |
|
384 |
<p> |
385 |
Autotools can be quite tricky for newcomers, but when you start using them on a |
386 |
daily basis you find it's a lot easier than having to deal with manual |
387 |
makefiles or other strange build tools such as imake or qmake, or even worse, |
388 |
special autotools-like build scripts that try to recognize the system they are |
389 |
building on. Autotools makes it simple to support new OSes and new hardware |
390 |
platforms, and saves maintainers and porters from having to learn how to |
391 |
custom-build a system to fix compilation. By carefully writing a script, |
392 |
developers can support new platforms without any changes at all. |
393 |
</p> |
394 |
|
395 |
</body> |
396 |
</section> |
397 |
</chapter> |
398 |
</guide> |
399 |
|
400 |
|
401 |
|
402 |
-- |
403 |
gentoo-doc-cvs@g.o mailing list |