Generally the following compilation parameters should be used:
CC = gcc CFLAGS = -O2 -g -Wall # sane warning options vary between programs LDFLAGS = # none install -s # (or use strip on the files in debian/tmp)
Note that all installed binaries should be stripped,
either by using the -s flag to
install
, or by calling strip
on
the binaries after they have been copied into
debian/tmp but before the tree is made into a
package.
The -g flag is useful on compilation so that you have available a full set of debugging symbols in your built source tree, in case anyone should file a bug report involving (for example) a core dump.
The -N flag should not be used. On a.out systems it may have been useful for some very small binaries, but for ELF it has no good effect.
It is up to the package maintainer to decide what compilation options are best for the package. Certain binaries (such as computationally-intensive programs) may function better with certain flags (-O3, for example); feel free to use them. Please use good judgment here. Don't use flags for the sake of it; only use them if there is good reason to do so. Feel free to override the upstream author's ideas about which compilation options are best--they are often inappropriate for our environment.
You have to specify the gcc option -D_REENTRANT when building a library (either static or shared) to make the library compatible with LinuxThreads.
Note that all installed shared libraries should be stripped with
strip --strip-unneeded <your-lib>(The option `--strip-unneeded' makes strip remove only the symbols which aren't needed for relocation processing.) Shared libraries can function perfectly well when stripped, since the symbols for dynamic linking are in a separate part of the ELF object file.
Note that under some circumstances it may be useful to install a shared library unstripped, for example when building a separate package to support debugging.
Please make sure that you use only released versions of shared libraries to build your packages; otherwise other users will not be able to run your binaries properly. Producing source packages that depend on unreleased compilers is also usually a bad idea.
For a straightforward library which has a development
environment and a runtime kit including just shared
libraries you need to create two packages:
librarynamesoname
(soname is the shared object name of the shared
library--it's the thing that has to match exactly between
building an executable and running it for the dynamic
linker to be able run the program; usually the
soname is the major number of the library) and
libraryname
soname
-dev
.
If you prefer only to support one development version at a
time you may name the development package
libraryname-dev
; otherwise you may
wish to use dpkg
's conflicts mechanism to
ensure that the user only installs one development version
at a time (after all, different development versions are
likely to have the same header files in them, causing a
filename clash if both are installed). Typically the
development version will also need an exact version
dependency on the runtime library, to make sure that
compilation and linking happens correctly.
Packages which use the shared library should have a
dependency on the name of the shared library package,
librarynamesoname
. When
the soname changes you can have both versions
of the library installed while moving from the old library
to the new.
If your package has some run-time support programs which
use the shared library you must not put them in
the shared library package. If you do that then you won't
be able to install several versions of the shared library
without getting filename clashes. Instead, either create
a third package for the runtime binaries (this package
might typically be named
libraryname-runtime
--note the absence
of the soname in the package name) or if the
development package is small include them in there.
If you have several shared libraries built from the same source tree you can lump them all together into a single shared library package, provided that you change all their sonames at once (so that you don't get filename clashes if you try to install different versions of the combined shared libraries package).
Follow the directions in the Debian Packaging Manual for putting the shared library in its package, and make sure you include a shlibs control area file with details of the dependencies for packages which use the library.
Shared libraries should not be installed
executable, since ld.so
does not require this
and trying to execute a shared library results in a core
dump.
dpkg
,
should have a #! line naming the shell to be used
to interpret them.In the case of Perl scripts this should be #!/usr/bin/perl.
Shell scripts (sh
and bash
)
should almost certainly start with set -e so that
errors are detected. Every script must use
set -e or check the exit status of every
command.
The standard shell interpreter `/bin/sh' may be a
symbolic link to any POSIX compatible shell. Thus, shell
scripts specifying `/bin/sh' as interpreter may
only use POSIX features. If a script requires non-POSIX
features from the shell interpreter, the appropriate shell
has to be specified in the first line of the script (e.g.,
`#!/bin/bash') and the package has to depend on
the package providing the shell (unless the shell package
is marked `Essential', e.g., in the case of
bash
).
Restrict your script to POSIX features when possible so
that it may use /bin/sh as its interpreter. If
your script works with ash
, it's probably
POSIX compliant, but if you are in doubt, use
/bin/bash.
Perl scripts should check for errors when making any system calls, including open, print, close, rename and system.
csh
and tcsh
should be avoided
as scripting languages. See Csh Programming
Considered Harmful, one of the comp.unix.*
FAQs. It can be found on rtfm.mit.edu
in
/pub/usenet-by-group/comp.unix.programmer/Csh_Programming_Considered_Harmful
.
If an upstream package comes with csh
scripts
then you must make sure that they start with
#!/bin/csh and make your package depend on the
c-shell
virtual package.
Any scripts which create files in world-writable directories (e.g., in /tmp) have to use a mechanism which will fail if a file with the same name already exists.
The Debian base distribution provides the
tempfile
and mktemp
utilities
for use by scripts for this purpose.
In addition, symbolic links should be specified as short as possible, i.e., link targets like `foo/../bar' are deprecated.
Note that when creating a relative link using
ln
it is not necessary for the target of the
link to exist relative to the working directory you're
running ln
from; nor is it necessary to
change directory to the directory where the link is to be
made. Simply include the string that should appear as the
target of the link (this will be a pathname relative to
the directory in which the link resides) as the first
argument to ln
.
For example, in your Makefile
or
debian/rules, do things like:
ln -fs gcc $(prefix)/bin/cc ln -fs gcc debian/tmp/usr/bin/cc ln -fs ../sbin/sendmail $(prefix)/bin/runq ln -fs ../sbin/sendmail debian/tmp/usr/bin/runq
A symbolic link pointing to a compressed file should always have the same file extension as the referenced file. (For example, if a file `foo.gz' is referenced by a symbolic link, the filename of the link has to end with `.gz' too, as in `bar.gz.')
If a package needs any special device files that are not
included in the base system, it has to call
makedev
in the postinst script,
after asking the user for permission to do so.
No package should remove any device files in the postrm or any other script. This is left to the system administrator.
Debian uses the serial devices /dev/tty*. Programs using the old /dev/cu* devices should be changed to use /dev/tty*.
It is almost certain that any file in /etc that
is in your package's filesystem archive should be listed
in dpkg
's conffiles control area
file. (See the Debian Packaging
Manual).
Only packages that are tagged conflicting with each other may specify the same file as conffile. A package may not modify a configuration file of another package.
If two or more packages use the same configuration file, one of these packages has to be defined as owner of the configuration file, i.e., it has to list the file as conffile and has to provide a program that modifies the configuration file.
The other packages have to depend on the owner package and use that program to update the configuration file.
Sometimes it's appropriate to build a new package, which
just provides the basic infrastructure for the
other packages and which manages the shared configuration
files. (Check out the sgml-base
package as an
example.)
Files in /etc/skel will automatically be copied
into new user accounts by adduser
. They
should not be referenced there by any program.
Therefore, if a program needs a dotfile to exist in advance in $HOME to work sensibly that dotfile should be installed in /etc/skel (and listed in conffiles, if it is not generated and modified dynamically by the package's installation scripts).
However, programs that require dotfiles in order to operate sensibly (dotfiles that they do not create themselves automatically, that is) are a bad thing, and programs should be configured by the Debian default installation as close to normal as possible.
Therefore, if a program in a Debian package needs to be configured in some way in order to operate sensibly that configuration should be done in a site-wide global configuration file elsewhere in /etc. Only if the program doesn't support a site-wide default configuration and the package maintainer doesn't have time to add it should a default per-user file be placed in /etc/skel.
/etc/skel should be as empty as we can make it. This is particularly true because there is no easy mechanism for ensuring that the appropriate dotfiles are copied into the accounts of existing users when a package is installed.
Ideally the sysadmin should not have to do any configuration other than that done (semi-)automatically by the postinst script.
.log
. If you have many
log files, or need a separate directory for permissions
reasons (/var/log is writable only by
root), you should usually create a directory named
/var/log/package
.
Make sure that any log files are rotated occasionally so
that they don't grow indefinitely; the best way to do this
is to use savelog
program in an
/etc/cron.daily, /etc/cron.weekly or
/etc/cron.monthly script. Here is a good example:
[ -d /var/log/apache/. ] || exit 0 umask 022 cd /var/log/apache if [ -fs access.log ] then savelog -c 7 access.log > /dev/null fi
Make sure that any log files are removed when the package is purged (but not when it is only removed), by checking the argument to the postrm script (see the Debian Packaging Manual for details).
debian-devel
first.Files should be owned by root.root, and made writable only by the owner and universally readable (and executable, if appropriate).
Directories should be mode 755 or (for group-writability) mode 2775. The ownership of the directory should be consistent with its mode--if a directory is mode 2775, it should be owned by the group that needs write access to it.
Setuid and setgid executables should be mode 4755 or 2755 respectively, and owned by the appropriate user or group. They should not be made unreadable (modes like 4711 or 2711 or even 4111); doing so achieves no extra security, because anyone can find the binary in the freely available Debian package--it is merely inconvenient. For the same reason you should not restrict read or execute permissions on non-set-id executables.
Some setuid programs need to be restricted to particular sets of users, using file permissions. In this case they should be owned by the uid to which they are set-id, and by the group which should be allowed to execute them. They should have mode 4754; there is no point in making them unreadable to those users who must not be allowed to execute them.
Do not arrange that the system administrator can only
reconfigure the package to correspond to their local
security policy by changing the permissions on a binary.
Ordinary files installed by dpkg
(as opposed
to conffiles and other similar objects) have their
permissions reset to the distributed permissions when the
package is reinstalled. Instead you should consider (for
example) creating a group for people allowed to use the
program(s) and making any setuid executables executable
only by that group.
If you need to create a new user or group for your package there are two possibilities. Firstly, you may need to make some files in the binary package be owned by this user or group, or you may need to compile the user or group id (rather than just the name) into the binary (though this latter should be avoided if possible). In this case you need a statically allocated id.
You must ask for a user or group id from the base system maintainer, and must not release the package until you have been allocated one. Once you have been allocated one you must make the package depend on a version of the base system with the id present in /etc/passwd or /etc/group, or alternatively arrange for your package to create the user or group itself with the correct id (using adduser) in its pre- or post-installation script (the latter is to be preferred if it is possible).
On the other hand, the program may able to determine the
uid or gid from the group name at runtime, so that a
dynamic id can be used. In this case you must choose an
appropriate user or group name, discussing this on
debian-devel
and checking with the base
system maintainer that it is unique and that they do not
wish you to use a statically allocated id instead. When
this has been checked you must arrange for your package to
create the user or group if necessary using
adduser
in the pre- or post-installation
script (again, the latter is to be preferred if it is
possible).
Note that changing the numeric value of an id associated with a name is very difficult, and involves searching the filesystem for all appropriate files. You need to think carefully whether a static or dynamic id is required, since changing your mind later will cause problems.