1217 lines
49 KiB
Plaintext
1217 lines
49 KiB
Plaintext
|
This is Info file standards.info, produced by Makeinfo-1.64 from the
|
|||
|
input file ./standards.texi.
|
|||
|
|
|||
|
START-INFO-DIR-ENTRY
|
|||
|
* Standards: (standards). GNU coding standards.
|
|||
|
END-INFO-DIR-ENTRY
|
|||
|
|
|||
|
GNU Coding Standards Copyright (C) 1992, 1993, 1994, 1995, 1996 Free
|
|||
|
Software Foundation, Inc.
|
|||
|
|
|||
|
Permission is granted to make and distribute verbatim copies of this
|
|||
|
manual provided the copyright notice and this permission notice are
|
|||
|
preserved on all copies.
|
|||
|
|
|||
|
Permission is granted to copy and distribute modified versions of
|
|||
|
this manual under the conditions for verbatim copying, provided that
|
|||
|
the entire resulting derived work is distributed under the terms of a
|
|||
|
permission notice identical to this one.
|
|||
|
|
|||
|
Permission is granted to copy and distribute translations of this
|
|||
|
manual into another language, under the above conditions for modified
|
|||
|
versions, except that this permission notice may be stated in a
|
|||
|
translation approved by the Free Software Foundation.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Syntactic Conventions, Next: Names, Prev: Comments, Up: Writing C
|
|||
|
|
|||
|
Clean Use of C Constructs
|
|||
|
=========================
|
|||
|
|
|||
|
Please explicitly declare all arguments to functions. Don't omit
|
|||
|
them just because they are `int's.
|
|||
|
|
|||
|
Declarations of external functions and functions to appear later in
|
|||
|
the source file should all go in one place near the beginning of the
|
|||
|
file (somewhere before the first function definition in the file), or
|
|||
|
else should go in a header file. Don't put `extern' declarations inside
|
|||
|
functions.
|
|||
|
|
|||
|
It used to be common practice to use the same local variables (with
|
|||
|
names like `tem') over and over for different values within one
|
|||
|
function. Instead of doing this, it is better declare a separate local
|
|||
|
variable for each distinct purpose, and give it a name which is
|
|||
|
meaningful. This not only makes programs easier to understand, it also
|
|||
|
facilitates optimization by good compilers. You can also move the
|
|||
|
declaration of each local variable into the smallest scope that includes
|
|||
|
all its uses. This makes the program even cleaner.
|
|||
|
|
|||
|
Don't use local variables or parameters that shadow global
|
|||
|
identifiers.
|
|||
|
|
|||
|
Don't declare multiple variables in one declaration that spans lines.
|
|||
|
Start a new declaration on each line, instead. For example, instead of
|
|||
|
this:
|
|||
|
|
|||
|
int foo,
|
|||
|
bar;
|
|||
|
|
|||
|
write either this:
|
|||
|
|
|||
|
int foo, bar;
|
|||
|
|
|||
|
or this:
|
|||
|
|
|||
|
int foo;
|
|||
|
int bar;
|
|||
|
|
|||
|
(If they are global variables, each should have a comment preceding it
|
|||
|
anyway.)
|
|||
|
|
|||
|
When you have an `if'-`else' statement nested in another `if'
|
|||
|
statement, always put braces around the `if'-`else'. Thus, never write
|
|||
|
like this:
|
|||
|
|
|||
|
if (foo)
|
|||
|
if (bar)
|
|||
|
win ();
|
|||
|
else
|
|||
|
lose ();
|
|||
|
|
|||
|
always like this:
|
|||
|
|
|||
|
if (foo)
|
|||
|
{
|
|||
|
if (bar)
|
|||
|
win ();
|
|||
|
else
|
|||
|
lose ();
|
|||
|
}
|
|||
|
|
|||
|
If you have an `if' statement nested inside of an `else' statement,
|
|||
|
either write `else if' on one line, like this,
|
|||
|
|
|||
|
if (foo)
|
|||
|
...
|
|||
|
else if (bar)
|
|||
|
...
|
|||
|
|
|||
|
with its `then'-part indented like the preceding `then'-part, or write
|
|||
|
the nested `if' within braces like this:
|
|||
|
|
|||
|
if (foo)
|
|||
|
...
|
|||
|
else
|
|||
|
{
|
|||
|
if (bar)
|
|||
|
...
|
|||
|
}
|
|||
|
|
|||
|
Don't declare both a structure tag and variables or typedefs in the
|
|||
|
same declaration. Instead, declare the structure tag separately and
|
|||
|
then use it to declare the variables or typedefs.
|
|||
|
|
|||
|
Try to avoid assignments inside `if'-conditions. For example, don't
|
|||
|
write this:
|
|||
|
|
|||
|
if ((foo = (char *) malloc (sizeof *foo)) == 0)
|
|||
|
fatal ("virtual memory exhausted");
|
|||
|
|
|||
|
instead, write this:
|
|||
|
|
|||
|
foo = (char *) malloc (sizeof *foo);
|
|||
|
if (foo == 0)
|
|||
|
fatal ("virtual memory exhausted");
|
|||
|
|
|||
|
Don't make the program ugly to placate `lint'. Please don't insert
|
|||
|
any casts to `void'. Zero without a cast is perfectly fine as a null
|
|||
|
pointer constant, except when calling a varargs function.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Names, Next: System Portability, Prev: Syntactic Conventions, Up: Writing C
|
|||
|
|
|||
|
Naming Variables and Functions
|
|||
|
==============================
|
|||
|
|
|||
|
The names of global variables and functions in a program serve as
|
|||
|
comments of a sort. So don't choose terse names--instead, look for
|
|||
|
names that give useful information about the meaning of the variable or
|
|||
|
function. In a GNU program, names should be English, like other
|
|||
|
comments.
|
|||
|
|
|||
|
Local variable names can be shorter, because they are used only
|
|||
|
within one context, where (presumably) comments explain their purpose.
|
|||
|
|
|||
|
Please use underscores to separate words in a name, so that the Emacs
|
|||
|
word commands can be useful within them. Stick to lower case; reserve
|
|||
|
upper case for macros and `enum' constants, and for name-prefixes that
|
|||
|
follow a uniform convention.
|
|||
|
|
|||
|
For example, you should use names like `ignore_space_change_flag';
|
|||
|
don't use names like `iCantReadThis'.
|
|||
|
|
|||
|
Variables that indicate whether command-line options have been
|
|||
|
specified should be named after the meaning of the option, not after
|
|||
|
the option-letter. A comment should state both the exact meaning of
|
|||
|
the option and its letter. For example,
|
|||
|
|
|||
|
/* Ignore changes in horizontal whitespace (-b). */
|
|||
|
int ignore_space_change_flag;
|
|||
|
|
|||
|
When you want to define names with constant integer values, use
|
|||
|
`enum' rather than `#define'. GDB knows about enumeration constants.
|
|||
|
|
|||
|
Use file names of 14 characters or less, to avoid creating gratuitous
|
|||
|
problems on older System V systems. You can use the program `doschk'
|
|||
|
to test for this. `doschk' also tests for potential name conflicts if
|
|||
|
the files were loaded onto an MS-DOS file system--something you may or
|
|||
|
may not care about.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: System Portability, Next: CPU Portability, Prev: Names, Up: Writing C
|
|||
|
|
|||
|
Portability between System Types
|
|||
|
================================
|
|||
|
|
|||
|
In the Unix world, "portability" refers to porting to different Unix
|
|||
|
versions. For a GNU program, this kind of portability is desirable, but
|
|||
|
not paramount.
|
|||
|
|
|||
|
The primary purpose of GNU software is to run on top of the GNU
|
|||
|
kernel, compiled with the GNU C compiler, on various types of CPU. The
|
|||
|
amount and kinds of variation among GNU systems on different CPUs will
|
|||
|
be comparable to the variation among Linux-based GNU systems or among
|
|||
|
BSD systems today. So the kinds of portability that are absolutely
|
|||
|
necessary are quite limited.
|
|||
|
|
|||
|
But many users do run GNU software on non-GNU Unix or Unix-like
|
|||
|
systems. So supporting a variety of Unix-like systems is desirable,
|
|||
|
although not paramount.
|
|||
|
|
|||
|
The easiest way to achieve portability to most Unix-like systems is
|
|||
|
to use Autoconf. It's unlikely that your program needs to know more
|
|||
|
information about the host platform than Autoconf can provide, simply
|
|||
|
because most of the programs that need such knowledge have already been
|
|||
|
written.
|
|||
|
|
|||
|
Avoid using the format of semi-internal data bases (e.g.,
|
|||
|
directories) when there is a higher-level alternative (`readdir').
|
|||
|
|
|||
|
As for systems that are not like Unix, such as MSDOS, Windows, the
|
|||
|
Macintosh, VMS, and MVS, supporting them is usually so much work that it
|
|||
|
is better if you don't.
|
|||
|
|
|||
|
The planned GNU kernel is not finished yet, but you can tell which
|
|||
|
facilities it will provide by looking at the GNU C Library Manual. The
|
|||
|
GNU kernel is based on Mach, so the features of Mach will also be
|
|||
|
available. However, if you use Mach features, you'll probably have
|
|||
|
trouble debugging your program today.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: CPU Portability, Next: System Functions, Prev: System Portability, Up: Writing C
|
|||
|
|
|||
|
Portability between CPUs
|
|||
|
========================
|
|||
|
|
|||
|
Even GNU systems will differ because of differences among CPU
|
|||
|
types--for example, difference in byte ordering and alignment
|
|||
|
requirements. It is absolutely essential to handle these differences.
|
|||
|
However, don't make any effort to cater to the possibility that an
|
|||
|
`int' will be less than 32 bits. We don't support 16-bit machines in
|
|||
|
GNU.
|
|||
|
|
|||
|
Don't assume that the address of an `int' object is also the address
|
|||
|
of its least-significant byte. This is false on big-endian machines.
|
|||
|
Thus, don't make the following mistake:
|
|||
|
|
|||
|
int c;
|
|||
|
...
|
|||
|
while ((c = getchar()) != EOF)
|
|||
|
write(file_descriptor, &c, 1);
|
|||
|
|
|||
|
When calling functions, you need not worry about the difference
|
|||
|
between pointers of various types, or between pointers and integers.
|
|||
|
On most machines, there's no difference anyway. As for the few
|
|||
|
machines where there is a difference, all of them support ANSI C, so
|
|||
|
you can use prototypes (conditionalized to be active only in ANSI C) to
|
|||
|
make the code work on those systems.
|
|||
|
|
|||
|
In certain cases, it is ok to pass integer and pointer arguments
|
|||
|
indiscriminately to the same function, and use no prototype on any
|
|||
|
system. For example, many GNU programs have error-reporting functions
|
|||
|
that pass their arguments along to `printf' and friends:
|
|||
|
|
|||
|
error (s, a1, a2, a3)
|
|||
|
char *s;
|
|||
|
int a1, a2, a3;
|
|||
|
{
|
|||
|
fprintf (stderr, "error: ");
|
|||
|
fprintf (stderr, s, a1, a2, a3);
|
|||
|
}
|
|||
|
|
|||
|
In practice, this works on all machines, and it is much simpler than any
|
|||
|
"correct" alternative. Be sure *not* to use a prototype for such
|
|||
|
functions.
|
|||
|
|
|||
|
However, avoid casting pointers to integers unless you really need
|
|||
|
to. These assumptions really reduce portability, and in most programs
|
|||
|
they are easy to avoid. In the cases where casting pointers to
|
|||
|
integers is essential--such as, a Lisp interpreter which stores type
|
|||
|
information as well as an address in one word--it is ok to do so, but
|
|||
|
you'll have to make explicit provisions to handle different word sizes.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: System Functions, Next: Internationalization, Prev: CPU Portability, Up: Writing C
|
|||
|
|
|||
|
Calling System Functions
|
|||
|
========================
|
|||
|
|
|||
|
C implementations differ substantially. ANSI C reduces but does not
|
|||
|
eliminate the incompatibilities; meanwhile, many users wish to compile
|
|||
|
GNU software with pre-ANSI compilers. This chapter gives
|
|||
|
recommendations for how to use the more or less standard C library
|
|||
|
functions to avoid unnecessary loss of portability.
|
|||
|
|
|||
|
* Don't use the value of `sprintf'. It returns the number of
|
|||
|
characters written on some systems, but not on all systems.
|
|||
|
|
|||
|
* `main' should be declared to return type `int'. It should
|
|||
|
terminate either by calling `exit' or by returning the integer
|
|||
|
status code; make sure it cannot ever return an undefined value.
|
|||
|
|
|||
|
* Don't declare system functions explicitly.
|
|||
|
|
|||
|
Almost any declaration for a system function is wrong on some
|
|||
|
system. To minimize conflicts, leave it to the system header
|
|||
|
files to declare system functions. If the headers don't declare a
|
|||
|
function, let it remain undeclared.
|
|||
|
|
|||
|
While it may seem unclean to use a function without declaring it,
|
|||
|
in practice this works fine for most system library functions on
|
|||
|
the systems where this really happens; thus, the disadvantage is
|
|||
|
only theoretical. By contrast, actual declarations have
|
|||
|
frequently caused actual conflicts.
|
|||
|
|
|||
|
* If you must declare a system function, don't specify the argument
|
|||
|
types. Use an old-style declaration, not an ANSI prototype. The
|
|||
|
more you specify about the function, the more likely a conflict.
|
|||
|
|
|||
|
* In particular, don't unconditionally declare `malloc' or `realloc'.
|
|||
|
|
|||
|
Most GNU programs use those functions just once, in functions
|
|||
|
conventionally named `xmalloc' and `xrealloc'. These functions
|
|||
|
call `malloc' and `realloc', respectively, and check the results.
|
|||
|
|
|||
|
Because `xmalloc' and `xrealloc' are defined in your program, you
|
|||
|
can declare them in other files without any risk of type conflict.
|
|||
|
|
|||
|
On most systems, `int' is the same length as a pointer; thus, the
|
|||
|
calls to `malloc' and `realloc' work fine. For the few
|
|||
|
exceptional systems (mostly 64-bit machines), you can use
|
|||
|
*conditionalized* declarations of `malloc' and `realloc'--or put
|
|||
|
these declarations in configuration files specific to those
|
|||
|
systems.
|
|||
|
|
|||
|
* The string functions require special treatment. Some Unix systems
|
|||
|
have a header file `string.h'; others have `strings.h'. Neither
|
|||
|
file name is portable. There are two things you can do: use
|
|||
|
Autoconf to figure out which file to include, or don't include
|
|||
|
either file.
|
|||
|
|
|||
|
* If you don't include either strings file, you can't get
|
|||
|
declarations for the string functions from the header file in the
|
|||
|
usual way.
|
|||
|
|
|||
|
That causes less of a problem than you might think. The newer ANSI
|
|||
|
string functions should be avoided anyway because many systems
|
|||
|
still don't support them. The string functions you can use are
|
|||
|
these:
|
|||
|
|
|||
|
strcpy strncpy strcat strncat
|
|||
|
strlen strcmp strncmp
|
|||
|
strchr strrchr
|
|||
|
|
|||
|
The copy and concatenate functions work fine without a declaration
|
|||
|
as long as you don't use their values. Using their values without
|
|||
|
a declaration fails on systems where the width of a pointer
|
|||
|
differs from the width of `int', and perhaps in other cases. It
|
|||
|
is trivial to avoid using their values, so do that.
|
|||
|
|
|||
|
The compare functions and `strlen' work fine without a declaration
|
|||
|
on most systems, possibly all the ones that GNU software runs on.
|
|||
|
You may find it necessary to declare them *conditionally* on a few
|
|||
|
systems.
|
|||
|
|
|||
|
The search functions must be declared to return `char *'. Luckily,
|
|||
|
there is no variation in the data type they return. But there is
|
|||
|
variation in their names. Some systems give these functions the
|
|||
|
names `index' and `rindex'; other systems use the names `strchr'
|
|||
|
and `strrchr'. Some systems support both pairs of names, but
|
|||
|
neither pair works on all systems.
|
|||
|
|
|||
|
You should pick a single pair of names and use it throughout your
|
|||
|
program. (Nowadays, it is better to choose `strchr' and `strrchr'
|
|||
|
for new programs, since those are the standard ANSI names.)
|
|||
|
Declare both of those names as functions returning `char *'. On
|
|||
|
systems which don't support those names, define them as macros in
|
|||
|
terms of the other pair. For example, here is what to put at the
|
|||
|
beginning of your file (or in a header) if you want to use the
|
|||
|
names `strchr' and `strrchr' throughout:
|
|||
|
|
|||
|
#ifndef HAVE_STRCHR
|
|||
|
#define strchr index
|
|||
|
#endif
|
|||
|
#ifndef HAVE_STRRCHR
|
|||
|
#define strrchr rindex
|
|||
|
#endif
|
|||
|
|
|||
|
char *strchr ();
|
|||
|
char *strrchr ();
|
|||
|
|
|||
|
Here we assume that `HAVE_STRCHR' and `HAVE_STRRCHR' are macros
|
|||
|
defined in systems where the corresponding functions exist. One way to
|
|||
|
get them properly defined is to use Autoconf.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Internationalization, Next: Mmap, Prev: System Functions, Up: Writing C
|
|||
|
|
|||
|
Internationalization
|
|||
|
====================
|
|||
|
|
|||
|
GNU has a library called GNU gettext that makes it easy to translate
|
|||
|
the messages in a program into various languages. You should use this
|
|||
|
library in every program. Use English for the messages as they appear
|
|||
|
in the program, and let gettext provide the way to translate them into
|
|||
|
other languages.
|
|||
|
|
|||
|
Using GNU gettext involves putting a call to the `gettext' macro
|
|||
|
around each string that might need translation--like this:
|
|||
|
|
|||
|
printf (gettext ("Processing file `%s'..."));
|
|||
|
|
|||
|
This permits GNU gettext to replace the string `"Processing file
|
|||
|
`%s'..."' with a translated version.
|
|||
|
|
|||
|
Once a program uses gettext, please make a point of writing calls to
|
|||
|
`gettext' when you add new strings that call for translation.
|
|||
|
|
|||
|
Using GNU gettext in a package involves specifying a "text domain
|
|||
|
name" for the package. The text domain name is used to separate the
|
|||
|
translations for this package from the translations for other packages.
|
|||
|
Normally, the text domain name should be the same as the name of the
|
|||
|
package--for example, `fileutils' for the GNU file utilities.
|
|||
|
|
|||
|
To enable gettext to work well, avoid writing code that makes
|
|||
|
assumptions about the structure of words or sentences. When you want
|
|||
|
the precise text of a sentence to vary depending on the data, use two or
|
|||
|
more alternative string constants each containing a complete sentences,
|
|||
|
rather than inserting conditionalized words or phrases into a single
|
|||
|
sentence framework.
|
|||
|
|
|||
|
Here is an example of what not to do:
|
|||
|
|
|||
|
printf ("%d file%s processed", nfiles,
|
|||
|
nfiles != 1 ? "s" : "");
|
|||
|
|
|||
|
The problem with that example is that it assumes that plurals are made
|
|||
|
by adding `s'. If you apply gettext to the format string, like this,
|
|||
|
|
|||
|
printf (gettext ("%d file%s processed"), nfiles,
|
|||
|
nfiles != 1 ? "s" : "");
|
|||
|
|
|||
|
the message can use different words, but it will still be forced to use
|
|||
|
`s' for the plural. Here is a better way:
|
|||
|
|
|||
|
printf ((nfiles != 1 ? "%d files processed"
|
|||
|
: "%d file processed"),
|
|||
|
nfiles);
|
|||
|
|
|||
|
This way, you can apply gettext to each of the two strings
|
|||
|
independently:
|
|||
|
|
|||
|
printf ((nfiles != 1 ? gettext ("%d files processed")
|
|||
|
: gettext ("%d file processed")),
|
|||
|
nfiles);
|
|||
|
|
|||
|
This can any method of forming the plural of the word for "file", and
|
|||
|
also handles languages that require agreement in the word for
|
|||
|
"processed".
|
|||
|
|
|||
|
A similar problem appears at the level of sentence structure with
|
|||
|
this code:
|
|||
|
|
|||
|
printf ("# Implicit rule search has%s been done.\n",
|
|||
|
f->tried_implicit ? "" : " not");
|
|||
|
|
|||
|
Adding `gettext' calls to this code cannot give correct results for all
|
|||
|
languages, because negation in some languages requires adding words at
|
|||
|
more than one place in the sentence. By contrast, adding `gettext'
|
|||
|
calls does the job straightfowardly if the code starts out like this:
|
|||
|
|
|||
|
printf (f->tried_implicit
|
|||
|
? "# Implicit rule search has been done.\n",
|
|||
|
: "# Implicit rule search has not been done.\n");
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Mmap, Prev: Internationalization, Up: Writing C
|
|||
|
|
|||
|
Mmap
|
|||
|
====
|
|||
|
|
|||
|
Don't assume that `mmap' either works on all files or fails for all
|
|||
|
files. It may work on some files and fail on others.
|
|||
|
|
|||
|
The proper way to use `mmap' is to try it on the specific file for
|
|||
|
which you want to use it--and if `mmap' doesn't work, fall back on
|
|||
|
doing the job in another way using `read' and `write'.
|
|||
|
|
|||
|
The reason this precaution is needed is that the GNU kernel (the
|
|||
|
HURD) provides a user-extensible file system, in which there can be many
|
|||
|
different kinds of "ordinary files." Many of them support `mmap', but
|
|||
|
some do not. It is important to make programs handle all these kinds
|
|||
|
of files.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Documentation, Next: Managing Releases, Prev: Writing C, Up: Top
|
|||
|
|
|||
|
Documenting Programs
|
|||
|
********************
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* GNU Manuals:: Writing proper manuals.
|
|||
|
* Manual Structure Details:: Specific structure conventions.
|
|||
|
* NEWS File:: NEWS files supplement manuals.
|
|||
|
* Change Logs:: Recording Changes
|
|||
|
* Man Pages:: Man pages are secondary.
|
|||
|
* Reading other Manuals:: How far you can go in learning
|
|||
|
from other manuals.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: GNU Manuals, Next: Manual Structure Details, Up: Documentation
|
|||
|
|
|||
|
GNU Manuals
|
|||
|
===========
|
|||
|
|
|||
|
The preferred way to document part of the GNU system is to write a
|
|||
|
manual in the Texinfo formatting language. See the Texinfo manual,
|
|||
|
either the hardcopy, or the on-line version available through `info' or
|
|||
|
the Emacs Info subsystem (`C-h i').
|
|||
|
|
|||
|
Programmers often find it most natural to structure the documentation
|
|||
|
following the structure of the implementation, which they know. But
|
|||
|
this structure is not necessarily good for explaining how to use the
|
|||
|
program; it may be irrelevant and confusing for a user.
|
|||
|
|
|||
|
At every level, from the sentences in a paragraph to the grouping of
|
|||
|
topics into separate manuals, the right way to structure documentation
|
|||
|
is according to the concepts and questions that a user will have in mind
|
|||
|
when reading it. Sometimes this structure of ideas matches the
|
|||
|
structure of the implementation of the software being documented--but
|
|||
|
often they are different. Often the most important part of learning to
|
|||
|
write good documentation is learning to notice when you are structuring
|
|||
|
the documentation like the implementation, and think about better
|
|||
|
alternatives.
|
|||
|
|
|||
|
For example, each program in the GNU system probably ought to be
|
|||
|
documented in one manual; but this does not mean each program should
|
|||
|
have its own manual. That would be following the structure of the
|
|||
|
implementation, rather than the structure that helps the user
|
|||
|
understand.
|
|||
|
|
|||
|
Instead, each manual should cover a coherent *topic*. For example,
|
|||
|
instead of a manual for `diff' and a manual for `diff3', we have one
|
|||
|
manual for "comparison of files" which covers both of those programs,
|
|||
|
as well as `cmp'. By documenting these programs together, we can make
|
|||
|
the whole subject clearer.
|
|||
|
|
|||
|
The manual which discusses a program should document all of the
|
|||
|
program's command-line options and all of its commands. It should give
|
|||
|
examples of their use. But don't organize the manual as a list of
|
|||
|
features. Instead, organize it logically, by subtopics. Address the
|
|||
|
questions that a user will ask when thinking about the job that the
|
|||
|
program does.
|
|||
|
|
|||
|
In general, a GNU manual should serve both as tutorial and reference.
|
|||
|
It should be set up for convenient access to each topic through Info,
|
|||
|
and for reading straight through (appendixes aside). A GNU manual
|
|||
|
should give a good introduction to a beginner reading through from the
|
|||
|
start, and should also provide all the details that hackers want.
|
|||
|
|
|||
|
That is not as hard as it first sounds. Arrange each chapter as a
|
|||
|
logical breakdown of its topic, but order the sections, and write their
|
|||
|
text, so that reading the chapter straight through makes sense. Do
|
|||
|
likewise when structuring the book into chapters, and when structuring a
|
|||
|
section into paragraphs. The watchword is, *at each point, address the
|
|||
|
most fundamental and important issue raised by the preceding text.*
|
|||
|
|
|||
|
If necessary, add extra chapters at the beginning of the manual which
|
|||
|
are purely tutorial and cover the basics of the subject. These provide
|
|||
|
the framework for a beginner to understand the rest of the manual. The
|
|||
|
Bison manual provides a good example of how to do this.
|
|||
|
|
|||
|
Don't use Unix man pages as a model for how to write GNU
|
|||
|
documentation; most of them are terse, badly structured, and give
|
|||
|
inadequate explanation of the underlying concepts. (There are, of
|
|||
|
course exceptions.) Also Unix man pages use a particular format which
|
|||
|
is different from what we use in GNU manuals.
|
|||
|
|
|||
|
Please do not use the term "pathname" that is used in Unix
|
|||
|
documentation; use "file name" (two words) instead. We use the term
|
|||
|
"path" only for search paths, which are lists of file names.
|
|||
|
|
|||
|
Please do not use the term "illegal" to refer to erroneous input to a
|
|||
|
computer program. Please use "invalid" for this, and reserve the term
|
|||
|
"illegal" for violations of law.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Manual Structure Details, Next: NEWS File, Prev: GNU Manuals, Up: Documentation
|
|||
|
|
|||
|
Manual Structure Details
|
|||
|
========================
|
|||
|
|
|||
|
The title page of the manual should state the version of the
|
|||
|
programs or packages documented in the manual. The Top node of the
|
|||
|
manual should also contain this information. If the manual is changing
|
|||
|
more frequently than or independent of the program, also state a version
|
|||
|
number for the manual in both of these places.
|
|||
|
|
|||
|
Each program documented in the manual should should have a node named
|
|||
|
`PROGRAM Invocation' or `Invoking PROGRAM'. This node (together with
|
|||
|
its subnodes, if any) should describe the program's command line
|
|||
|
arguments and how to run it (the sort of information people would look
|
|||
|
in a man page for). Start with an `@example' containing a template for
|
|||
|
all the options and arguments that the program uses.
|
|||
|
|
|||
|
Alternatively, put a menu item in some menu whose item name fits one
|
|||
|
of the above patterns. This identifies the node which that item points
|
|||
|
to as the node for this purpose, regardless of the node's actual name.
|
|||
|
|
|||
|
There will be automatic features for specifying a program name and
|
|||
|
quickly reading just this part of its manual.
|
|||
|
|
|||
|
If one manual describes several programs, it should have such a node
|
|||
|
for each program described.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: NEWS File, Next: Change Logs, Prev: Manual Structure Details, Up: Documentation
|
|||
|
|
|||
|
The NEWS File
|
|||
|
=============
|
|||
|
|
|||
|
In addition to its manual, the package should have a file named
|
|||
|
`NEWS' which contains a list of user-visible changes worth mentioning.
|
|||
|
In each new release, add items to the front of the file and identify
|
|||
|
the version they pertain to. Don't discard old items; leave them in
|
|||
|
the file after the newer items. This way, a user upgrading from any
|
|||
|
previous version can see what is new.
|
|||
|
|
|||
|
If the `NEWS' file gets very long, move some of the older items into
|
|||
|
a file named `ONEWS' and put a note at the end referring the user to
|
|||
|
that file.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Change Logs, Next: Man Pages, Prev: NEWS File, Up: Documentation
|
|||
|
|
|||
|
Change Logs
|
|||
|
===========
|
|||
|
|
|||
|
Keep a change log to describe all the changes made to program source
|
|||
|
files. The purpose of this is so that people investigating bugs in the
|
|||
|
future will know about the changes that might have introduced the bug.
|
|||
|
Often a new bug can be found by looking at what was recently changed.
|
|||
|
More importantly, change logs can help you eliminate conceptual
|
|||
|
inconsistencies between different parts of a program, by giving you a
|
|||
|
history of how the conflicting concepts arose and who they came from.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Change Log Concepts::
|
|||
|
* Style of Change Logs::
|
|||
|
* Simple Changes::
|
|||
|
* Conditional Changes::
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Change Log Concepts, Next: Style of Change Logs, Up: Change Logs
|
|||
|
|
|||
|
Change Log Concepts
|
|||
|
-------------------
|
|||
|
|
|||
|
You can think of the change log as a conceptual "undo list" which
|
|||
|
explains how earlier versions were different from the current version.
|
|||
|
People can see the current version; they don't need the change log to
|
|||
|
tell them what is in it. What they want from a change log is a clear
|
|||
|
explanation of how the earlier version differed.
|
|||
|
|
|||
|
The change log file is normally called `ChangeLog' and covers an
|
|||
|
entire directory. Each directory can have its own change log, or a
|
|||
|
directory can use the change log of its parent directory-it's up to you.
|
|||
|
|
|||
|
Another alternative is to record change log information with a
|
|||
|
version control system such as RCS or CVS. This can be converted
|
|||
|
automatically to a `ChangeLog' file.
|
|||
|
|
|||
|
There's no need to describe the full purpose of the changes or how
|
|||
|
they work together. If you think that a change calls for explanation,
|
|||
|
you're probably right. Please do explain it--but please put the
|
|||
|
explanation in comments in the code, where people will see it whenever
|
|||
|
they see the code. For example, "New function" is enough for the
|
|||
|
change log when you add a function, because there should be a comment
|
|||
|
before the function definition to explain what it does.
|
|||
|
|
|||
|
However, sometimes it is useful to write one line to describe the
|
|||
|
overall purpose of a batch of changes.
|
|||
|
|
|||
|
The easiest way to add an entry to `ChangeLog' is with the Emacs
|
|||
|
command `M-x add-change-log-entry'. An entry should have an asterisk,
|
|||
|
the name of the changed file, and then in parentheses the name of the
|
|||
|
changed functions, variables or whatever, followed by a colon. Then
|
|||
|
describe the changes you made to that function or variable.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Style of Change Logs, Next: Simple Changes, Prev: Change Log Concepts, Up: Change Logs
|
|||
|
|
|||
|
Style of Change Logs
|
|||
|
--------------------
|
|||
|
|
|||
|
Here are some examples of change log entries:
|
|||
|
|
|||
|
* register.el (insert-register): Return nil.
|
|||
|
(jump-to-register): Likewise.
|
|||
|
|
|||
|
* sort.el (sort-subr): Return nil.
|
|||
|
|
|||
|
* tex-mode.el (tex-bibtex-file, tex-file, tex-region):
|
|||
|
Restart the tex shell if process is gone or stopped.
|
|||
|
(tex-shell-running): New function.
|
|||
|
|
|||
|
* expr.c (store_one_arg): Round size up for move_block_to_reg.
|
|||
|
(expand_call): Round up when emitting USE insns.
|
|||
|
* stmt.c (assign_parms): Round size up for move_block_from_reg.
|
|||
|
|
|||
|
It's important to name the changed function or variable in full.
|
|||
|
Don't abbreviate function or variable names, and don't combine them.
|
|||
|
Subsequent maintainers will often search for a function name to find all
|
|||
|
the change log entries that pertain to it; if you abbreviate the name,
|
|||
|
they won't find it when they search.
|
|||
|
|
|||
|
For example, some people are tempted to abbreviate groups of function
|
|||
|
names by writing `* register.el ({insert,jump-to}-register)'; this is
|
|||
|
not a good idea, since searching for `jump-to-register' or
|
|||
|
`insert-register' would not find that entry.
|
|||
|
|
|||
|
Separate unrelated change log entries with blank lines. When two
|
|||
|
entries represent parts of the same change, so that they work together,
|
|||
|
then don't put blank lines between them. Then you can omit the file
|
|||
|
name and the asterisk when successive entries are in the same file.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Simple Changes, Next: Conditional Changes, Prev: Style of Change Logs, Up: Change Logs
|
|||
|
|
|||
|
Simple Changes
|
|||
|
--------------
|
|||
|
|
|||
|
Certain simple kinds of changes don't need much detail in the change
|
|||
|
log.
|
|||
|
|
|||
|
When you change the calling sequence of a function in a simple
|
|||
|
fashion, and you change all the callers of the function, there is no
|
|||
|
need to make individual entries for all the callers that you changed.
|
|||
|
Just write in the entry for the function being called, "All callers
|
|||
|
changed."
|
|||
|
|
|||
|
* keyboard.c (Fcommand_execute): New arg SPECIAL.
|
|||
|
All callers changed.
|
|||
|
|
|||
|
When you change just comments or doc strings, it is enough to write
|
|||
|
an entry for the file, without mentioning the functions. Just "Doc
|
|||
|
fixes" is enough for the change log.
|
|||
|
|
|||
|
There's no need to make change log entries for documentation files.
|
|||
|
This is because documentation is not susceptible to bugs that are hard
|
|||
|
to fix. Documentation does not consist of parts that must interact in a
|
|||
|
precisely engineered fashion. To correct an error, you need not know
|
|||
|
the history of the erroneous passage; it is enough to compare what the
|
|||
|
documentation says with the way the program actually works.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Conditional Changes, Prev: Simple Changes, Up: Change Logs
|
|||
|
|
|||
|
Conditional Changes
|
|||
|
-------------------
|
|||
|
|
|||
|
C programs often contain compile-time `#if' conditionals. Many
|
|||
|
changes are conditional; sometimes you add a new definition which is
|
|||
|
entirely contained in a conditional. It is very useful to indicate in
|
|||
|
the change log the conditions for which the change applies.
|
|||
|
|
|||
|
Our convention for indicating conditional changes is to use square
|
|||
|
brackets around the name of the condition.
|
|||
|
|
|||
|
Here is a simple example, describing a change which is conditional
|
|||
|
but does not have a function or entity name associated with it:
|
|||
|
|
|||
|
* xterm.c [SOLARIS2]: Include string.h.
|
|||
|
|
|||
|
Here is an entry describing a new definition which is entirely
|
|||
|
conditional. This new definition for the macro `FRAME_WINDOW_P' is
|
|||
|
used only when `HAVE_X_WINDOWS' is defined:
|
|||
|
|
|||
|
* frame.h [HAVE_X_WINDOWS] (FRAME_WINDOW_P): Macro defined.
|
|||
|
|
|||
|
Here is an entry for a change within the function `init_display',
|
|||
|
whose definition as a whole is unconditional, but the changes themselves
|
|||
|
are contained in a `#ifdef HAVE_LIBNCURSES' conditional:
|
|||
|
|
|||
|
* dispnew.c (init_display) [HAVE_LIBNCURSES]: If X, call tgetent.
|
|||
|
|
|||
|
Here is an entry for a change that takes affect only when a certain
|
|||
|
macro is *not* defined:
|
|||
|
|
|||
|
(gethostname) [!HAVE_SOCKETS]: Replace with winsock version.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Man Pages, Next: Reading other Manuals, Prev: Change Logs, Up: Documentation
|
|||
|
|
|||
|
Man Pages
|
|||
|
=========
|
|||
|
|
|||
|
In the GNU project, man pages are secondary. It is not necessary or
|
|||
|
expected for every GNU program to have a man page, but some of them do.
|
|||
|
It's your choice whether to include a man page in your program.
|
|||
|
|
|||
|
When you make this decision, consider that supporting a man page
|
|||
|
requires continual effort each time the program is changed. The time
|
|||
|
you spend on the man page is time taken away from more useful work.
|
|||
|
|
|||
|
For a simple program which changes little, updating the man page may
|
|||
|
be a small job. Then there is little reason not to include a man page,
|
|||
|
if you have one.
|
|||
|
|
|||
|
For a large program that changes a great deal, updating a man page
|
|||
|
may be a substantial burden. If a user offers to donate a man page,
|
|||
|
you may find this gift costly to accept. It may be better to refuse
|
|||
|
the man page unless the same person agrees to take full responsibility
|
|||
|
for maintaining it--so that you can wash your hands of it entirely. If
|
|||
|
this volunteer later ceases to do the job, then don't feel obliged to
|
|||
|
pick it up yourself; it may be better to withdraw the man page from the
|
|||
|
distribution until someone else agrees to update it.
|
|||
|
|
|||
|
When a program changes only a little, you may feel that the
|
|||
|
discrepancies are small enough that the man page remains useful without
|
|||
|
updating. If so, put a prominent note near the beginning of the man
|
|||
|
page explaining that you don't maintain it and that the Texinfo manual
|
|||
|
is more authoritative. The note should say how to access the Texinfo
|
|||
|
documentation.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Reading other Manuals, Prev: Man Pages, Up: Documentation
|
|||
|
|
|||
|
Reading other Manuals
|
|||
|
=====================
|
|||
|
|
|||
|
There may be non-free books or documentation files that describe the
|
|||
|
program you are documenting.
|
|||
|
|
|||
|
It is ok to use these documents for reference, just as the author of
|
|||
|
a new algebra textbook can read other books on algebra. A large portion
|
|||
|
of any non-fiction book consists of facts, in this case facts about how
|
|||
|
a certain program works, and these facts are necessarily the same for
|
|||
|
everyone who writes about the subject. But be careful not to copy your
|
|||
|
outline structure, wording, tables or examples from preexisting non-free
|
|||
|
documentation. Copying from free documentation may be ok; please check
|
|||
|
with the FSF about the individual case.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Managing Releases, Prev: Documentation, Up: Top
|
|||
|
|
|||
|
The Release Process
|
|||
|
*******************
|
|||
|
|
|||
|
Making a release is more than just bundling up your source files in a
|
|||
|
tar file and putting it up for FTP. You should set up your software so
|
|||
|
that it can be configured to run on a variety of systems. Your Makefile
|
|||
|
should conform to the GNU standards described below, and your directory
|
|||
|
layout should also conform to the standards discussed below. Doing so
|
|||
|
makes it easy to include your package into the larger framework of all
|
|||
|
GNU software.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Configuration:: How Configuration Should Work
|
|||
|
* Makefile Conventions:: Makefile Conventions
|
|||
|
* Releases:: Making Releases
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Configuration, Next: Makefile Conventions, Up: Managing Releases
|
|||
|
|
|||
|
How Configuration Should Work
|
|||
|
=============================
|
|||
|
|
|||
|
Each GNU distribution should come with a shell script named
|
|||
|
`configure'. This script is given arguments which describe the kind of
|
|||
|
machine and system you want to compile the program for.
|
|||
|
|
|||
|
The `configure' script must record the configuration options so that
|
|||
|
they affect compilation.
|
|||
|
|
|||
|
One way to do this is to make a link from a standard name such as
|
|||
|
`config.h' to the proper configuration file for the chosen system. If
|
|||
|
you use this technique, the distribution should *not* contain a file
|
|||
|
named `config.h'. This is so that people won't be able to build the
|
|||
|
program without configuring it first.
|
|||
|
|
|||
|
Another thing that `configure' can do is to edit the Makefile. If
|
|||
|
you do this, the distribution should *not* contain a file named
|
|||
|
`Makefile'. Instead, it should include a file `Makefile.in' which
|
|||
|
contains the input used for editing. Once again, this is so that people
|
|||
|
won't be able to build the program without configuring it first.
|
|||
|
|
|||
|
If `configure' does write the `Makefile', then `Makefile' should
|
|||
|
have a target named `Makefile' which causes `configure' to be rerun,
|
|||
|
setting up the same configuration that was set up last time. The files
|
|||
|
that `configure' reads should be listed as dependencies of `Makefile'.
|
|||
|
|
|||
|
All the files which are output from the `configure' script should
|
|||
|
have comments at the beginning explaining that they were generated
|
|||
|
automatically using `configure'. This is so that users won't think of
|
|||
|
trying to edit them by hand.
|
|||
|
|
|||
|
The `configure' script should write a file named `config.status'
|
|||
|
which describes which configuration options were specified when the
|
|||
|
program was last configured. This file should be a shell script which,
|
|||
|
if run, will recreate the same configuration.
|
|||
|
|
|||
|
The `configure' script should accept an option of the form
|
|||
|
`--srcdir=DIRNAME' to specify the directory where sources are found (if
|
|||
|
it is not the current directory). This makes it possible to build the
|
|||
|
program in a separate directory, so that the actual source directory is
|
|||
|
not modified.
|
|||
|
|
|||
|
If the user does not specify `--srcdir', then `configure' should
|
|||
|
check both `.' and `..' to see if it can find the sources. If it finds
|
|||
|
the sources in one of these places, it should use them from there.
|
|||
|
Otherwise, it should report that it cannot find the sources, and should
|
|||
|
exit with nonzero status.
|
|||
|
|
|||
|
Usually the easy way to support `--srcdir' is by editing a
|
|||
|
definition of `VPATH' into the Makefile. Some rules may need to refer
|
|||
|
explicitly to the specified source directory. To make this possible,
|
|||
|
`configure' can add to the Makefile a variable named `srcdir' whose
|
|||
|
value is precisely the specified directory.
|
|||
|
|
|||
|
The `configure' script should also take an argument which specifies
|
|||
|
the type of system to build the program for. This argument should look
|
|||
|
like this:
|
|||
|
|
|||
|
CPU-COMPANY-SYSTEM
|
|||
|
|
|||
|
For example, a Sun 3 might be `m68k-sun-sunos4.1'.
|
|||
|
|
|||
|
The `configure' script needs to be able to decode all plausible
|
|||
|
alternatives for how to describe a machine. Thus, `sun3-sunos4.1'
|
|||
|
would be a valid alias. For many programs, `vax-dec-ultrix' would be
|
|||
|
an alias for `vax-dec-bsd', simply because the differences between
|
|||
|
Ultrix and BSD are rarely noticeable, but a few programs might need to
|
|||
|
distinguish them.
|
|||
|
|
|||
|
There is a shell script called `config.sub' that you can use as a
|
|||
|
subroutine to validate system types and canonicalize aliases.
|
|||
|
|
|||
|
Other options are permitted to specify in more detail the software
|
|||
|
or hardware present on the machine, and include or exclude optional
|
|||
|
parts of the package:
|
|||
|
|
|||
|
`--enable-FEATURE[=PARAMETER]'
|
|||
|
Configure the package to build and install an optional user-level
|
|||
|
facility called FEATURE. This allows users to choose which
|
|||
|
optional features to include. Giving an optional PARAMETER of
|
|||
|
`no' should omit FEATURE, if it is built by default.
|
|||
|
|
|||
|
No `--enable' option should *ever* cause one feature to replace
|
|||
|
another. No `--enable' option should ever substitute one useful
|
|||
|
behavior for another useful behavior. The only proper use for
|
|||
|
`--enable' is for questions of whether to build part of the program
|
|||
|
or exclude it.
|
|||
|
|
|||
|
`--with-PACKAGE'
|
|||
|
The package PACKAGE will be installed, so configure this package
|
|||
|
to work with PACKAGE.
|
|||
|
|
|||
|
Possible values of PACKAGE include `x', `x-toolkit', `gnu-as' (or
|
|||
|
`gas'), `gnu-ld', `gnu-libc', and `gdb'.
|
|||
|
|
|||
|
Do not use a `--with' option to specify the file name to use to
|
|||
|
find certain files. That is outside the scope of what `--with'
|
|||
|
options are for.
|
|||
|
|
|||
|
`--nfp'
|
|||
|
The target machine has no floating point processor.
|
|||
|
|
|||
|
`--gas'
|
|||
|
The target machine assembler is GAS, the GNU assembler. This is
|
|||
|
obsolete; users should use `--with-gnu-as' instead.
|
|||
|
|
|||
|
`--x'
|
|||
|
The target machine has the X Window System installed. This is
|
|||
|
obsolete; users should use `--with-x' instead.
|
|||
|
|
|||
|
All `configure' scripts should accept all of these "detail" options,
|
|||
|
whether or not they make any difference to the particular package at
|
|||
|
hand. In particular, they should accept any option that starts with
|
|||
|
`--with-' or `--enable-'. This is so users will be able to configure
|
|||
|
an entire GNU source tree at once with a single set of options.
|
|||
|
|
|||
|
You will note that the categories `--with-' and `--enable-' are
|
|||
|
narrow: they *do not* provide a place for any sort of option you might
|
|||
|
think of. That is deliberate. We want to limit the possible
|
|||
|
configuration options in GNU software. We do not want GNU programs to
|
|||
|
have idiosyncratic configuration options.
|
|||
|
|
|||
|
Packages that perform part of the compilation process may support
|
|||
|
cross-compilation. In such a case, the host and target machines for
|
|||
|
the program may be different. The `configure' script should normally
|
|||
|
treat the specified type of system as both the host and the target,
|
|||
|
thus producing a program which works for the same type of machine that
|
|||
|
it runs on.
|
|||
|
|
|||
|
The way to build a cross-compiler, cross-assembler, or what have
|
|||
|
you, is to specify the option `--host=HOSTTYPE' when running
|
|||
|
`configure'. This specifies the host system without changing the type
|
|||
|
of target system. The syntax for HOSTTYPE is the same as described
|
|||
|
above.
|
|||
|
|
|||
|
Bootstrapping a cross-compiler requires compiling it on a machine
|
|||
|
other than the host it will run on. Compilation packages accept a
|
|||
|
configuration option `--build=HOSTTYPE' for specifying the
|
|||
|
configuration on which you will compile them, in case that is different
|
|||
|
from the host.
|
|||
|
|
|||
|
Programs for which cross-operation is not meaningful need not accept
|
|||
|
the `--host' option, because configuring an entire operating system for
|
|||
|
cross-operation is not a meaningful thing.
|
|||
|
|
|||
|
Some programs have ways of configuring themselves automatically. If
|
|||
|
your program is set up to do this, your `configure' script can simply
|
|||
|
ignore most of its arguments.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Makefile Conventions, Next: Releases, Prev: Configuration, Up: Managing Releases
|
|||
|
|
|||
|
Makefile Conventions
|
|||
|
====================
|
|||
|
|
|||
|
This node describes conventions for writing the Makefiles for GNU
|
|||
|
programs.
|
|||
|
|
|||
|
* Menu:
|
|||
|
|
|||
|
* Makefile Basics:: General Conventions for Makefiles
|
|||
|
* Utilities in Makefiles:: Utilities in Makefiles
|
|||
|
* Command Variables:: Variables for Specifying Commands
|
|||
|
* Directory Variables:: Variables for Installation Directories
|
|||
|
* Standard Targets:: Standard Targets for Users
|
|||
|
* Install Command Categories:: Three categories of commands in the `install'
|
|||
|
rule: normal, pre-install and post-install.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Makefile Basics, Next: Utilities in Makefiles, Up: Makefile Conventions
|
|||
|
|
|||
|
General Conventions for Makefiles
|
|||
|
---------------------------------
|
|||
|
|
|||
|
Every Makefile should contain this line:
|
|||
|
|
|||
|
SHELL = /bin/sh
|
|||
|
|
|||
|
to avoid trouble on systems where the `SHELL' variable might be
|
|||
|
inherited from the environment. (This is never a problem with GNU
|
|||
|
`make'.)
|
|||
|
|
|||
|
Different `make' programs have incompatible suffix lists and
|
|||
|
implicit rules, and this sometimes creates confusion or misbehavior. So
|
|||
|
it is a good idea to set the suffix list explicitly using only the
|
|||
|
suffixes you need in the particular Makefile, like this:
|
|||
|
|
|||
|
.SUFFIXES:
|
|||
|
.SUFFIXES: .c .o
|
|||
|
|
|||
|
The first line clears out the suffix list, the second introduces all
|
|||
|
suffixes which may be subject to implicit rules in this Makefile.
|
|||
|
|
|||
|
Don't assume that `.' is in the path for command execution. When
|
|||
|
you need to run programs that are a part of your package during the
|
|||
|
make, please make sure that it uses `./' if the program is built as
|
|||
|
part of the make or `$(srcdir)/' if the file is an unchanging part of
|
|||
|
the source code. Without one of these prefixes, the current search
|
|||
|
path is used.
|
|||
|
|
|||
|
The distinction between `./' (the "build directory") and
|
|||
|
`$(srcdir)/' (the "source directory") is important because users can
|
|||
|
build in a separate directory using the `--srcdir' option to
|
|||
|
`configure'. A rule of the form:
|
|||
|
|
|||
|
foo.1 : foo.man sedscript
|
|||
|
sed -e sedscript foo.man > foo.1
|
|||
|
|
|||
|
will fail when the build directory is not the source directory, because
|
|||
|
`foo.man' and `sedscript' are in the the source directory.
|
|||
|
|
|||
|
When using GNU `make', relying on `VPATH' to find the source file
|
|||
|
will work in the case where there is a single dependency file, since
|
|||
|
the `make' automatic variable `$<' will represent the source file
|
|||
|
wherever it is. (Many versions of `make' set `$<' only in implicit
|
|||
|
rules.) A Makefile target like
|
|||
|
|
|||
|
foo.o : bar.c
|
|||
|
$(CC) -I. -I$(srcdir) $(CFLAGS) -c bar.c -o foo.o
|
|||
|
|
|||
|
should instead be written as
|
|||
|
|
|||
|
foo.o : bar.c
|
|||
|
$(CC) -I. -I$(srcdir) $(CFLAGS) -c $< -o $@
|
|||
|
|
|||
|
in order to allow `VPATH' to work correctly. When the target has
|
|||
|
multiple dependencies, using an explicit `$(srcdir)' is the easiest way
|
|||
|
to make the rule work well. For example, the target above for `foo.1'
|
|||
|
is best written as:
|
|||
|
|
|||
|
foo.1 : foo.man sedscript
|
|||
|
sed -e $(srcdir)/sedscript $(srcdir)/foo.man > $@
|
|||
|
|
|||
|
GNU distributions usually contain some files which are not source
|
|||
|
files--for example, Info files, and the output from Autoconf, Automake,
|
|||
|
Bison or Flex. Since these files normally appear in the source
|
|||
|
directory, they should always appear in the source directory, not in the
|
|||
|
build directory. So Makefile rules to update them should put the
|
|||
|
updated files in the source directory.
|
|||
|
|
|||
|
However, if a file does not appear in the distribution, then the
|
|||
|
Makefile should not put it in the source directory, because building a
|
|||
|
program in ordinary circumstances should not modify the source directory
|
|||
|
in any way.
|
|||
|
|
|||
|
Try to make the build and installation targets, at least (and all
|
|||
|
their subtargets) work correctly with a parallel `make'.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Utilities in Makefiles, Next: Command Variables, Prev: Makefile Basics, Up: Makefile Conventions
|
|||
|
|
|||
|
Utilities in Makefiles
|
|||
|
----------------------
|
|||
|
|
|||
|
Write the Makefile commands (and any shell scripts, such as
|
|||
|
`configure') to run in `sh', not in `csh'. Don't use any special
|
|||
|
features of `ksh' or `bash'.
|
|||
|
|
|||
|
The `configure' script and the Makefile rules for building and
|
|||
|
installation should not use any utilities directly except these:
|
|||
|
|
|||
|
cat cmp cp diff echo egrep expr false grep install-info
|
|||
|
ln ls mkdir mv pwd rm rmdir sed sleep sort tar test touch true
|
|||
|
|
|||
|
The compression program `gzip' can be used in the `dist' rule.
|
|||
|
|
|||
|
Stick to the generally supported options for these programs. For
|
|||
|
example, don't use `mkdir -p', convenient as it may be, because most
|
|||
|
systems don't support it.
|
|||
|
|
|||
|
It is a good idea to avoid creating symbolic links in makefiles,
|
|||
|
since a few systems don't support them.
|
|||
|
|
|||
|
The Makefile rules for building and installation can also use
|
|||
|
compilers and related programs, but should do so via `make' variables
|
|||
|
so that the user can substitute alternatives. Here are some of the
|
|||
|
programs we mean:
|
|||
|
|
|||
|
ar bison cc flex install ld ldconfig lex
|
|||
|
make makeinfo ranlib texi2dvi yacc
|
|||
|
|
|||
|
Use the following `make' variables to run those programs:
|
|||
|
|
|||
|
$(AR) $(BISON) $(CC) $(FLEX) $(INSTALL) $(LD) $(LDCONFIG) $(LEX)
|
|||
|
$(MAKE) $(MAKEINFO) $(RANLIB) $(TEXI2DVI) $(YACC)
|
|||
|
|
|||
|
When you use `ranlib' or `ldconfig', you should make sure nothing
|
|||
|
bad happens if the system does not have the program in question.
|
|||
|
Arrange to ignore an error from that command, and print a message before
|
|||
|
the command to tell the user that failure of this command does not mean
|
|||
|
a problem. (The Autoconf `AC_PROG_RANLIB' macro can help with this.)
|
|||
|
|
|||
|
If you use symbolic links, you should implement a fallback for
|
|||
|
systems that don't have symbolic links.
|
|||
|
|
|||
|
Additional utilities that can be used via Make variables are:
|
|||
|
|
|||
|
chgrp chmod chown mknod
|
|||
|
|
|||
|
It is ok to use other utilities in Makefile portions (or scripts)
|
|||
|
intended only for particular systems where you know those utilities
|
|||
|
exist.
|
|||
|
|
|||
|
|
|||
|
File: standards.info, Node: Command Variables, Next: Directory Variables, Prev: Utilities in Makefiles, Up: Makefile Conventions
|
|||
|
|
|||
|
Variables for Specifying Commands
|
|||
|
---------------------------------
|
|||
|
|
|||
|
Makefiles should provide variables for overriding certain commands,
|
|||
|
options, and so on.
|
|||
|
|
|||
|
In particular, you should run most utility programs via variables.
|
|||
|
Thus, if you use Bison, have a variable named `BISON' whose default
|
|||
|
value is set with `BISON = bison', and refer to it with `$(BISON)'
|
|||
|
whenever you need to use Bison.
|
|||
|
|
|||
|
File management utilities such as `ln', `rm', `mv', and so on, need
|
|||
|
not be referred to through variables in this way, since users don't
|
|||
|
need to replace them with other programs.
|
|||
|
|
|||
|
Each program-name variable should come with an options variable that
|
|||
|
is used to supply options to the program. Append `FLAGS' to the
|
|||
|
program-name variable name to get the options variable name--for
|
|||
|
example, `BISONFLAGS'. (The name `CFLAGS' is an exception to this
|
|||
|
rule, but we keep it because it is standard.) Use `CPPFLAGS' in any
|
|||
|
compilation command that runs the preprocessor, and use `LDFLAGS' in
|
|||
|
any compilation command that does linking as well as in any direct use
|
|||
|
of `ld'.
|
|||
|
|
|||
|
If there are C compiler options that *must* be used for proper
|
|||
|
compilation of certain files, do not include them in `CFLAGS'. Users
|
|||
|
expect to be able to specify `CFLAGS' freely themselves. Instead,
|
|||
|
arrange to pass the necessary options to the C compiler independently
|
|||
|
of `CFLAGS', by writing them explicitly in the compilation commands or
|
|||
|
by defining an implicit rule, like this:
|
|||
|
|
|||
|
CFLAGS = -g
|
|||
|
ALL_CFLAGS = -I. $(CFLAGS)
|
|||
|
.c.o:
|
|||
|
$(CC) -c $(CPPFLAGS) $(ALL_CFLAGS) $<
|
|||
|
|
|||
|
Do include the `-g' option in `CFLAGS', because that is not
|
|||
|
*required* for proper compilation. You can consider it a default that
|
|||
|
is only recommended. If the package is set up so that it is compiled
|
|||
|
with GCC by default, then you might as well include `-O' in the default
|
|||
|
value of `CFLAGS' as well.
|
|||
|
|
|||
|
Put `CFLAGS' last in the compilation command, after other variables
|
|||
|
containing compiler options, so the user can use `CFLAGS' to override
|
|||
|
the others.
|
|||
|
|
|||
|
Every Makefile should define the variable `INSTALL', which is the
|
|||
|
basic command for installing a file into the system.
|
|||
|
|
|||
|
Every Makefile should also define the variables `INSTALL_PROGRAM'
|
|||
|
and `INSTALL_DATA'. (The default for each of these should be
|
|||
|
`$(INSTALL)'.) Then it should use those variables as the commands for
|
|||
|
actual installation, for executables and nonexecutables respectively.
|
|||
|
Use these variables as follows:
|
|||
|
|
|||
|
$(INSTALL_PROGRAM) foo $(bindir)/foo
|
|||
|
$(INSTALL_DATA) libfoo.a $(libdir)/libfoo.a
|
|||
|
|
|||
|
Always use a file name, not a directory name, as the second argument of
|
|||
|
the installation commands. Use a separate command for each file to be
|
|||
|
installed.
|
|||
|
|