|
|
Many of the files in this directory are shared between the coreutils, |
|
|
diffutils, tar and gettext packages -- and others, so if you |
|
|
change them, try to ensure that you don |
|
|
That |
|
|
that makes it easy. |
|
|
|
|
|
- The lib/ sources are split into modules. Usually the module of a |
|
|
lib/foo.h and lib/foo.c is called "foo" - not unexpected, hey! -, but |
|
|
in more ambiguous cases you can look up the module a file belongs to |
|
|
by doing "grep lib/foo.c modules/*". |
|
|
|
|
|
- For every module there is an autoconf macro file, usually called |
|
|
m4/foo.m4 according to the module name. When you modify lib/foo.h or |
|
|
lib/foo.c, remember to modify m4/foo.m4 as well! |
|
|
What if you don |
|
|
doesn |
|
|
So you might need to create one. |
|
|
|
|
|
- A module which defines a replacement function (i.e. a function which is |
|
|
compiled only on systems which lack it or where it exists but doesn |
|
|
work satisfactorily) has a .m4 file with typically the following structure: |
|
|
|
|
|
AC_DEFUN([gl_FUNC_FOO], |
|
|
[ |
|
|
AC_REPLACE_FUNCS(foo) |
|
|
if test $ac_cv_func_foo = no; then |
|
|
gl_PREREQ_FOO |
|
|
fi |
|
|
]) |
|
|
|
|
|
# Prerequisites of lib/foo.c. |
|
|
AC_DEFUN([gl_PREREQ_FOO], [ |
|
|
dnl Many AC_CHECK_* invocations. |
|
|
]) |
|
|
|
|
|
- A module which is compiled on all platforms can define multiple functions |
|
|
and be spread across multiple source files (although each time you do |
|
|
this you should consider splitting the module, if the source files could |
|
|
be independent). The .m4 file has typically the following structure: |
|
|
|
|
|
AC_DEFUN([gl_FOO], |
|
|
[ |
|
|
dnl Prerequisites of lib/foo.c. |
|
|
dnl Many AC_CHECK_* invocations. |
|
|
|
|
|
dnl Prerequisites of lib/foobar.c. |
|
|
dnl Many AC_CHECK_* invocations. |
|
|
]) |
|
|
|
|
|
- When a module FOO depends on a module BAR, you do *not* generally need |
|
|
to write |
|
|
|
|
|
AC_DEFUN([gl_FOO], |
|
|
[ |
|
|
AC_REQUIRE([gl_BAR]) |
|
|
... |
|
|
]) |
|
|
|
|
|
because the maintainers might want to use locally modified / renamed copies |
|
|
of the module BAR. |
|
|
|
|
|
- If the autoconf tests for the modules FOO and BAR have some checks in |
|
|
common, still list them separately. Autoconf has two mechanisms for |
|
|
avoiding that a configure file runs the same test twice: AC_REQUIRE |
|
|
and AC_CACHE_CHECK. Trying to omit the checks leads to maintenance |
|
|
problems: If FOO depends on BAR, and you omit a check from FOO |
|
|
later on, when someone modifies bar.c and removes the check from bar.m4, |
|
|
he will not remember that foo.c needs the check as well. |
|
|
|
|
|
- Now, how can you find the prerequisites of lib/foo.c? Try this: |
|
|
"grep '#.*if' lib/foo.c | grep -v endif" |
|
|
and for each HAVE_* macro search in the autoconf documentation what could |
|
|
be the autoconf macro that provides it. This is only an approximation; in |
|
|
general you should look at all preprocessor directives in lib/foo.c. |
|
|
|
|
|
- In AC_RUN_IFELSE invocations, try to put as much information about failed |
|
|
tests as possible in the exit code. The exit code is 0 for success and any |
|
|
value between 1 and 127 for failure. The exit code is printed in config.log; |
|
|
therefore when an AC_RUN_IFELSE invocation failed, it is possible to analyze |
|
|
the failure immediately if sufficient information is contained in the exit |
|
|
code. |
|
|
|
|
|
For a program that performs a single test, the typical idiom is: |
|
|
|
|
|
if (do_test1 ()) |
|
|
return 1; |
|
|
return 0; |
|
|
|
|
|
For a test that performs a test with some preparation, the typical idiom is |
|
|
to return an enumerated value: |
|
|
|
|
|
if (prep1 ()) |
|
|
return 1; |
|
|
else if (prep2 ()) |
|
|
return 2; |
|
|
else if (prep3 ()) |
|
|
return 3; |
|
|
else if (do_test1 ()) |
|
|
return 4; |
|
|
return 0; |
|
|
|
|
|
For multiple independent tests in a single program, you can return a bit |
|
|
mask with up to 7 bits: |
|
|
|
|
|
int result = 0; |
|
|
if (do_test1 ()) |
|
|
result |= 1; |
|
|
if (do_test2 ()) |
|
|
result |= 2; |
|
|
if (do_test3 ()) |
|
|
result |= 4; |
|
|
return result; |
|
|
|
|
|
For more than 7 independent tests, you have to map some possible test |
|
|
failures to same bit. |
|
|
|
|
|
- After ANY modifications of an m4 file, you should increment its serial |
|
|
number (in the first line). Also, if this first line features a particular |
|
|
release, _remove_ this release stamp. Example: Change |
|
|
|
|
|
# setenv.m4 serial 2 (gettext-0.11.1) |
|
|
|
|
|
into |
|
|
|
|
|
# setenv.m4 serial 3 |
|
|
|