X-Git-Url: http://erislabs.net/gitweb/?a=blobdiff_plain;f=doc%2Fgnulib.texi;h=34353d3eb2a20efc9fea46f74a4fd5acf8d9da28;hb=75e3b3670b7703b47beeeb923cc4f246693dc7d9;hp=36da884bc047b56314042da4c9e6151d9ef5b3cd;hpb=2b41521150b0141c6bf6730f1820e78efc90e02a;p=gnulib.git diff --git a/doc/gnulib.texi b/doc/gnulib.texi index 36da884bc..34353d3eb 100644 --- a/doc/gnulib.texi +++ b/doc/gnulib.texi @@ -1,20 +1,20 @@ \input texinfo @c -*-texinfo-*- -@comment $Id: gnulib.texi,v 1.1 2004-09-19 13:17:06 karl Exp $ +@comment $Id: gnulib.texi,v 1.10 2005-06-27 22:36:50 jas Exp $ @comment %**start of header @setfilename gnulib.info @settitle GNU Gnulib -@syncodeindex pg cp @syncodeindex fn cp +@syncodeindex pg cp @comment %**end of header -@set UPDATED $Date: 2004-09-19 13:17:06 $ +@set UPDATED $Date: 2005-06-27 22:36:50 $ @copying This manual is for GNU Gnulib (updated @value{UPDATED}), which is a library of common routines intended to be shared at the source level. -Copyright @copyright{} 2004 Free Software Foundation, Inc. +Copyright @copyright{} 2004, 2005 Free Software Foundation, Inc. @quotation Permission is granted to copy, distribute and/or modify this document @@ -33,7 +33,7 @@ Software Foundation raise funds for GNU development.'' @dircategory Software development @direntry -* gnulib: (gnulib). Source files to share among distributions. +* Gnulib: (gnulib). Source files to share among distributions. @end direntry @titlepage @@ -65,8 +65,9 @@ Software Foundation raise funds for GNU development.'' @node Gnulib @chapter Gnulib -This is not a real manual. It's just a place to store random notes -until someone (you?) gets around to actually writing a manual. +This manual contains some bare-bones documentation, but not much more. +It's mostly been a place to store notes until someone (you?) gets +around to writing a coherent manual. Getting started: @@ -80,9 +81,11 @@ Getting started: @menu * Comments:: +* Header files:: * ctime:: * inet_ntoa:: * Out of memory handling:: +* Library version handling:: @end menu @node Comments @@ -98,6 +101,78 @@ it should appear in just one place unless you can ensure that the multiple copies will always remain identical. +@node Header files +@section Header files + +@cindex double inclusion of header files +@cindex header file include protection +It is a tradition to use CPP tricks to avoid parsing the same header +file more than once, which might cause warnings. The trick is to wrap +the content of the header file (say, @file{foo.h}) in a block, as in: + +@example +#ifndef FOO_H +# define FOO_H +... +body of header file goes here +... +#endif /* FOO_H */ +@end example + +Whether to use @code{FOO_H} or @code{_FOO_H} is a matter of taste and +style. The C89 and C99 standards reserve all identifiers that begin with an +underscore and either an uppercase letter or another underscore, for +any use. Thus, in theory, an application might not safely assume that +@code{_FOO_H} has not already been defined by a library. On the other +hand, using @code{FOO_H} will likely lead the higher risk of +collisions with other symbols (e.g., @code{KEY_H}, @code{XK_H}, @code{BPF_H}, +which are CPP macro constants, or @code{COFF_LONG_H}, which is a CPP +macro function). Your preference may depend on whether you consider +the header file under discussion as part of the application (which has +its own namespace for CPP symbols) or a supporting library (that +shouldn't interfere with the application's CPP symbol namespace). + +@cindex C++ header files +@cindex Header files and C++ +Adapting C header files for use in C++ applications can use another +CPP trick, as in: + +@example +# ifdef __cplusplus +extern "C" +@{ +# endif +... +body of header file goes here +... +# ifdef __cplusplus +@} +# endif +@end example + +The idea here is that @code{__cplusplus} is defined only by C++ +implementations, which will wrap the header file in an @samp{extern "C"} +block. Again, whether to use this trick is a matter of taste and +style. While the above can be seen as harmless, it could be argued +that the header file is written in C, and any C++ application using it +should explicitly use the @samp{extern "C"} block itself. Your +preference might depend on whether you consider the API exported by +your header file as something available for C programs only, or for C +and C++ programs alike. + +@subsection Include ordering + +When writing a gnulib module, or even in general, a good way to order +the @samp{#include} directives is the following. + +@itemize +@item First comes the #include "..." specifying the module being implemented. +@item Then come all the #include <...> of system or system-replacement headers, +in arbitrary order. +@item Then come all the #include "..." of gnulib and private headers, in +arbitrary order. +@end itemize + @node ctime @section ctime @findex ctime @@ -177,6 +252,51 @@ must be taken to not allocate more memory, as that will likely also fail. +@node Library version handling +@section Library version handling + +The module ``check_version'' can be useful when your gnulib +application is a system library. You will typically wrap the call to +the @code{check_version} function through a library API, your library +header file may contain: + +@example +#define STRINGPREP_VERSION "0.5.18" +... + extern const char *stringprep_check_version (const char *req_version); +@end example + +The implementation of @code{stringprep_check_version} would simply +pass on the call to @code{check_version}. + +There are two uses of the interface. The first is a way to provide +for applications to find out the version number of the library it +uses. The application may contain diagnostic code such as: + +@example + printf ("Stringprep version: header %s library %s", + STRINGPREP_VERSION, + stringprep_check_version (NULL)); +@end example + +Separating the library and header file version can be useful when +searching for version mismatch related problems. + +The second uses is as a rudimentary test of proper library version, by +making sure the application get a library version that is the same, or +newer, than the header file used when building the application. This +doesn't catch all problems, libraries may change backwards incompatibly +in later versions, but enable applications to require a certain +minimum version before it may proceed. + +Typical uses look like: + +@example + /* Check version of libgcrypt. */ + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); +@end example + @node Invoking gnulib-tool @chapter Invoking gnulib-tool @@ -186,6 +306,244 @@ fail. Run @samp{gnulib-tool --help}, and use the source. @command{gnulib-tool} is the way to import Gnulib modules. +@menu +* Initial import:: First import of Gnulib modules. +* Importing updated files:: Subsequent imports. +* Finishing touches:: Simplifying imports. +@end menu + + +@node Initial import +@section Initial import +@cindex initial import + +Gnulib assumes your project uses Autoconf and Automake. Invoking +@samp{gnulib-tool --import} will copy source files, create a +@file{Makefile.am} to build them, and generate a @file{gnulib.m4} with +Autoconf M4 macro declarations used by @file{configure.ac}. + +Our example will be a library that uses Autoconf, Automake and +Libtool. It calls @code{strdup}, and you wish to use gnulib to make +the package portable to C89 (which doesn't have @code{strdup}). + +@example +~/src/libfoo$ gnulib-tool --import strdup +Module list with included dependencies: + strdup +File list: + lib/strdup.c + lib/strdup.h + m4/onceonly_2_57.m4 + m4/strdup.m4 +Creating ./lib/Makefile.am... +Creating ./m4/gnulib.m4... +Finished. + +You may need to add #include directives for the following .h files. + #include "strdup.h" + +Don't forget to add "lib/Makefile" +to AC_CONFIG_FILES in "./configure.ac" and to mention +"lib" in SUBDIRS in some Makefile.am. +~/src/libfoo$ +@end example + +By default, the source code is copied into @file{lib/} and the M4 +macros in @file{m4/}. You can override these paths by using +@code{--source-base=DIRECTORY} and @code{--m4-base=DIRECTORY}, or by +adding @samp{gl_SOURCE_BASE(DIRECTORY)} and +@samp{gl_M4_BASE(DIRECTORY)} to your @file{configure.ac}. +Some modules also provide other files necessary +for building. These files are copied into the directory specified +by @samp{AC_CONFIG_AUX_DIR} in @file{configure.ac} or by the +@code{--aux-dir=DIRECTORY} option. If neither is specified, the +current directory is assumed. + +@code{gnulib-tool} can make symbolic links instead +of copying the source files. Use the @code{--symbolic} +(or @code{-s} for short) option to do this. + +@code{gnulib-tool} will overwrite any pre-existing files, in +particular @file{Makefile.am}. Unfortunately, separating the +generated @file{Makefile.am} content (for building the gnulib library) +into a separate file, say @file{gnulib.mk}, that could be included +by your handwritten @file{Makefile.am} is not possible, due to how +variable assignments are handled by Automake. + +Consequently, it can be a good idea to chose directories that are not +already used by your projects, to separate gnulib imported files from +your own files. This approach can also be useful if you want to avoid +conflicts between other tools (e.g., @code{getextize} that also copy +M4 files into your package. Simon Josefsson successfully uses a source +base of @file{gl/}, and a M4 base of @file{gl/m4/}, in several +packages. + +A few manual steps are required to finish the initial import. + +First, you need to make sure Autoconf can find the macro definitions +in @file{gnulib.m4}. Use the @code{ACLOCAL_AMFLAGS} specifier in your +top-level @file{Makefile.am} file, as in: + +@example +ACLOCAL_AMFLAGS = -I m4 +@end example + +Naturally, replace @file{m4} with the value from @code{--m4-base} or +@code{gl_M4_BASE}. If the M4 base is @file{gl/m4} you would use: + +@example +ACLOCAL_AMFLAGS = -I gl/m4 +@end example + +You are now ready to call the M4 macros in @code{gnulib.m4} from +@file{configure.ac}. The macro @code{gl_EARLY} must be called as soon +as possible after verifying that the C compiler is working. +Typically, this is immediately after @code{AC_PROG_CC}, as in: + +@example +... +AC_PROG_CC +gl_EARLY +... +@end example + +The core part of the gnulib checks are done by the macro +@code{gl_INIT}. Place it further down in the file, typically where +you normally check for header files or functions. Or in a separate +section with other gnulib statements, such as @code{gl_SOURCE_BASE}. +For example: + +@example +... +# For gnulib. +gl_INIT +... +@end example + +You must also make sure that the gnulib library is built. Add the +@code{Makefile} in the gnulib source base directory to +@code{AC_CONFIG_FILES}, as in: + +@example +AC_CONFIG_FILES(... lib/Makefile ...) +@end example + +If your gnulib source base is @file{gl}, you would use: + +@example +AC_CONFIG_FILES(... gl/Makefile ...) +@end example + +You must also make sure that @code{make} work in the gnulib directory. +Add the gnulib source base directory to a @code{SUBDIRS} Makefile.am +statement, as in: + +@example +SUBDIRS = lib +@end example + +or if you, more likely, already have a few entries in @code{SUBDIRS}, +you can add something like: + +@example +SUBDIRS += lib +@end example + +If you are using a gnulib source base of @code{gl}, you would use: + +@example +SUBDIRS += gl +@end example + +Finally, you have to add compiler and linker flags in the appropriate +source directories, so that you can make use +of the gnulib library. For example: + +@example +... +AM_CPPFLAGS = -I$(top_srcdir)/lib +... +LIBADD = lib/libgnu.a +... +@end example + +Don't forget to @code{#include} the various header files. In this +example, you would need to make sure that @samp{#include } +is evaluated when compiling all source code files, that want to make +use of @code{strdup}. + + +@node Importing updated files +@section Importing updated files + +From time to time, you may want to invoke @samp{gnulib-tool --import} +to update the files in your package. Once you have set up your +package for gnulib, this step is quite simple. For example: + +@example +~/src/libfoo$ gnulib-tool --import --source-base gl --m4-base gl/m4 strdup +Module list with included dependencies: + strdup +File list: + lib/strdup.c + lib/strdup.h + m4/onceonly_2_57.m4 + m4/strdup.m4 +Creating ./lib/Makefile.am... +Creating ./m4/gnulib.m4... +Finished. + +Don't forget to add "lib/Makefile" +to AC_CONFIG_FILES in "./configure.ac" and to mention +"lib" in SUBDIRS in some Makefile.am. +~/src/libfoo$ +@end example + +If you don't recall how you invoked the tool last time, the commands +used (and the operations it resulted in) are placed in comments within +the generated @file{Makefile.am} and @file{gnulib.m4}, as in: + +@example +... +# Invoked as: gnulib-tool --import strdup +# Reproduce by: gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --libtool strdup +... +@end example + + +@node Finishing touches +@section Finishing touches + +Invoking @samp{gnulib-tool --import} with the proper parameters (e.g., +@samp{--m4-base gl/m4}) and list of modules (e.g., @samp{strdup +snprintf getline minmax}) can be tedious. To simplify this procedure, +you may put the command line parameters in your @file{configure.ac}. +For example: + +@example +... +AC_PROG_CC +gl_EARLY +... +# For gnulib. +gl_SOURCE_BASE(gl) +gl_M4_BASE(gl/m4) +gl_LIB(libgl) +gl_MODULES(getopt progname strdup dummy exit error getpass-gnu getaddrinfo) +gl_INIT +... +@end example + +This illustrate all macros defined in @file{gnulib.m4}. With the +above, importing new files are as simple as running @samp{gnulib-tool +--import} with no additional parameters. + +The macros @code{gl_EARLY}, @code{gl_INIT}, @code{gl_SOURCE_BASE}, and +@code{gl_M4_BASE} have been discussed earlier. The @code{gl_LIB} +macro can be used if you wish to change the library name (by default +@file{libgnu.a} or @file{libgnu.la} if you use libtool). The +@code{gl_MODULES} macro is used to specify which modules to import. + @node Copying This Manual @appendix Copying This Manual