Packaging - 3. Packaging Policy
3.1 Package Licenses
The packages included in Fink come with a wide variety of licenses. Most of them place restrictions on redistributing the full source and especially on distributing binaries. Some packages can not be included in the binary distribution of Fink because of these license restrictions. Thus it is very important that package maintainers check the license of their package carefully.
Every package that is to be distributed as a binary package must
contain a copy of the license.
It must be installed in the doc directory,
i.e. in %p/share/doc/%n
.
(In the InstallScript, %i must be used instead of %p, of course.
The DocFiles field takes care of the details automatically.)
If there is no explicit license in the original source, include a
small text file with a note about the status of the package.
Most licenses require that the license accompanies any distribution.
Fink's policy is to always do this, even if it is not explicitly
required.
To make an automated maintenance of the binary distribution possible,
any package that is to be distributed must have a License
field.
This field denotes the nature of the license and is used to decide
which packages make it into the binary distribution and which must be
held back.
The field may only be present if the actual license terms are included
in the binary package, as explained above.
To make the License
field useful, only one of the
following pre-defined values may be used.
If you're packaging something that doesn't fit into these categories,
ask for help on the developer mailing list.
GPL
- the GNU General Public License. This license requires that the source is available from the same place as the binary.LGPL
- the GNU Lesser General Public License. This license requires that the source is available from the same place as the binary.GPL/LGPL
- this if a special case for packages where one part is licensed under the GPL (e.g. the executables) and another part is licensed under the LGPL (e.g. the libraries).BSD
- for BSD-style licenses. This includes the so-called "original" BSD license, the "modified" BSD license and the MIT license. The Apache license also counts as BSD. With these licenses the distribution of source code is optional.Artistic
- for the Artistic license and derivatives.Artistic/GPL
- dual-licensed under the Artistic and GPL licenses.GNU Free Documentation License
andLinux Documentation Project
- if the documentation included in a package is explicitly included under one of the licenses, then this is indicated by appending/GFDL
or/LDP
, giving one of the allowed combinations: "GFDL", "GPL/GFDL", "LGPL/GFDL", "GPL/LGPL/GFDL", "LDP", or "GPL/LGPL/LDP".DFSG-Approved
- for software that meets the guidelines of the Debian Social Contract.OSI-Approved
- for other Open Source licenses approved by the Open Source Initiative. One of OSI's requirements is that free distribution of binaries and sources is allowed. This value can also be used as an umbrella for dual-licensed packages.Restrictive
- for restrictive licenses. Use this for packages that are available from the author in source form for free use, but don't allow free redistribution.Restrictive/Distributable
- for restrictive licenses which permit distribution of source and binaries. Use this for packages that are available from the author in source form, permit distribution of source and binaries, but have restrictions which make them non-open source licenses.Commercial
- for restrictive, commercial licenses. Use this for commercial packages (e.g. Freeware, Shareware) that do not allow free redistribution of source or binaries.Public Domain
- for packages that are in the Public Domain, i.e. the author has given up his copyright on the code. These packages don't have licenses at all and anyone can do anything with them.
3.2 The GPL and OpenSSL
(Policy change effective April, 2005.)
Due to the apparent incompatibility of the OpenSSL license with the GPL and LGPL licenses, fink packages which link to openssl but are licensed under the GPL or LGPL are marked as "Restrictive." As a consequence, the Fink project will not distribute binaries of such packages, although users are free to compile them from source at their discretion.
Package maintainers are encouraged to record the original package license in
the DescPackaging
field.
3.3 Base System Interference
Fink is an add-on distribution that is installed in a directory separate from the base system. It is crucial that a package does not install files outside of Fink's directory.
Exceptions can be made when there is no other possibility, e.g. with XFree86. In this case the package must check for existing files before installation and refuse to install if it would overwrite existing files. The package must make sure that all files it installed outside of the Fink directory are deleted when the package is removed, or that they cause no harm if they are left there (i.e. they need to check binaries for existence before calling them and the like).
3.4 Shared Libraries
Fink's policy about shared libraries became effective in February 2002. This section of the documentation discusses version 4 of the policy (which coincides with the release of Fink's 0.5.0 distribution), as modified in December, 2006 to handle 64-bit libraries and from January, 2008 to handle private shared libraries. (In addition, the discussion was updated in June, 2008 to eliminate obsolete references to a transitional period for implementing the shared libraries policy.) We begin with a quick summary, and then discuss things in more detail.
Any package which builds shared libraries should treat its shared libraries according to Fink's policy. This means:
- verify, using
otool -L
(orotool64 -L
for 64-bit libraries on 10.4), that the install_name of each library and its compatibility and current version numbers are correct - put the public shared libraries in a separate package (except for the
links from libfoo.dylib to the install_name), and include
the
Shlibs
field in that package - put the headers and the final links from libfoo.dylib into a package
which is classified as
BuildDependsOnly: True
, and plan to have no other package depend on this one.
Note that a package may also install private shared libraries, which
are not intended to be linked from any other package. In this case, the
libraries need not go into a separate package, but a Shlibs
field must still be part of the package containing shared libraries. Also,
maintainers should try to avoid storing a final link from libfoo.dylib
in the main library directory %i/lib
(or its 64-bit equivalent), to prevent
other programs from accidentally linking to this library.
A maintainer who has reasons to deviate from this policy and not split the package should explain the reasons in the DescPackaging field.
For some packages, everything can be accomplished with a main package and a
-shlibs package; in other cases you also need a third package. The new
SplitOff
field actually makes this quite easy.
When three packages are needed, there are two different ways they could be named, depending on whether the libraries (option 1) or the binaries (option 2) are the most important feature of the package. For option 1, use the layout:
Package | Contents |
---|---|
foo-shlibs | Shared libraries |
foo | Headers |
foo-bin | Binaries, etc. |
while for option 2, use the layout:
Package | Contents |
---|---|
foo-shlibs | Shared libraries |
foo-dev | Headers |
foo | Binaries, etc. |
The policy in detail
We now discuss things in more detail; for examples of the policy in action, see the libpng, libjpeg and libtiff packages.
Software which has been ported to Darwin should build shared libraries
whenever possible. (Package maintainers
are also free to build static libraries as well, if appropriate
for their packages; or they may submit packages containing only static
libraries if they wish.)
Whenever shared libraries are being built that are expected to be used by other packages,
two closely related fink packages should be made, named foo
and foo-shlibs. The shared libraries go in foo-shlibs, and the header
files go in foo. These two packages
can be made with a single .info file, using
the SplitOff
field, as described below.
(In fact, it is often necessary
to make more than two packages from the source, and this can be done
using SplitOff2
, SplitOff3
, etc.)
Each software package for which public shared libraries are built must have
a major version number N, which is included in the shared
library's filename (for example, libbar.N.dylib
).
The major version number is only supposed
to change when a backwards-incompatible change in the library's API has been
made. Fink uses the following naming convention: if the upstream name
of the package is bar, then the fink packages are called barN and
barN-shlibs. (This is only strictly applied to new packages, or when the
major version number changes.) For example, the major version number for
the pre-existing libpng package was 2, but recent versions of the
library have major version number 3. So there are now four fink packages
to handle this: libpng, libpng-shlibs, libpng3, libpng3-shlibs.
Only one of libpng and libpng3 can be installed at any given time,
but libpng-shlibs and libpng3-shlibs can be installed at the same time.
(Note that only two .info files are required to build these four packages.)
The shared library itself and certain related files will be put into
the package barN-shlibs; the "include" files and certain other files will
be put into the package barN. There can be no overlapping files
between these two packages, and everything stored in barN-shlibs must have
a pathname which somehow includes the major version number N. In many
instances, your package will need some files at runtime which are
typically installed into %i/lib/bar/
or
%i/share/bar/
; you should adjust the installation
paths to %i/lib/bar/N/
or
%i/share/bar/N/
.
All other packages which depend on bar, major version N, will be asked to use the dependencies
Depends: barN-shlibs BuildDepends: barN
It is not be permitted for another package to depend on barN itself. (Although there may still be a few such dependencies involving packages which were in place prior to February, 2002.) This is signaled to other developers by a boolean field
BuildDependsOnly: True
within the package description for barN.
If your package includes both shared libraries and binary files, and if the binary files need to be present at runtime (not just at build time), then the binaries must be split off into a third package, which could be called barN-bin. Other packages are allowed to depend on barN-bin as well as barN-shlibs.
When building shared libraries under major version N, it is important that
the "install_name" of the library be %p/lib/libbar.N.dylib
.
(You can
find the install_name by running otool -L
on your library,
or otool64 -L
for 64-bit libraries on 10.4.) The
actual library file may be installed at another location, such as
%i/lib/libbar.N.x.y.dylib
and your packages should create symbolic links
%i/lib/libbar.N.dylib -> %p/lib/libbar.N.x.y.dylib %i/lib/libbar.dylib -> %p/lib/libbar.N.x.y.dylib
from the install_name path and from the linking path to the actual library. (The first will not be needed if the library is in fact installed at the install_name path, which is becoming more common.)
If the static library is also built, then it will be installed at
%i/lib/libbar.a
If the package uses libtool, these things are usually handled automatically,
but in any event you should
check that they have been done correctly in your case. You should also
check that current_version and compatibility_version were defined
appropriately for your shared libraries. (These are also shown with the
otool -L
query, or otool64 -L
for 64-bit libraries.)
Files are then divided between the two packages as follows
- in package barN-shlibs:
%i/lib/libbar.N.x.y.dylib %i/lib/libbar.N.dylib -> %p/lib/libbar.N.x.y.dylib %i/lib/bar/N/* %i/share/bar/N/* %i/share/doc/barN-shlibs/*
- in package barN:
%i/include/* %i/lib/libbar.dylib -> %p/lib/libbar.N.x.y.dylib %i/lib/libbar.a %i/share/doc/barN/* other files, if needed
Notice that both packages are required to have some documentation about the license, but that the directories containing the DocFiles will be different.
Doing this is quite easy in practice, using the
SplitOff
field. Here is
how the example above would be implemented (in part):
Package: barN Version: N.x.y Revision: 1 License: GPL Depends: barN-shlibs (= %v-%r) BuildDependsOnly: True DocFiles: COPYING SplitOff: << Package: barN-shlibs Files: lib/libbar.N.x.y.dylib lib/libbar.N.dylib lib/bar/N DocFiles: COPYING <<
During the execution of the SplitOff
field, the specified files and directories are moved from the
install directory %I of the main package to the install directory %i of the
splitoff package. (There is a similar convention for names: %N is the
name of the main package, and %n is the name of the current package.)
The DocFiles
command then puts a copy of the documentation into
%i/share/doc/barN-shlibs
.
Notice that we have included the exact current version of barN-shlibs as a dependency of the main package barN (which can be abbreviated %N-shlibs (= %v-%r) ). This ensures that the versions match, and also guarantees that barN automatically "inherits" all the dependencies of barN-shlibs.
The BuildDependsOnly field
When libraries are being upgraded over time, it is often necessary to have two versions of the header files available during a transition period, with one version used for compiling some things and the other version used for compiling others. For this reason, the packages containing header files must be constructed with some care. If both foo-dev and bar-dev contain overlapping headers, then foo-dev should declare
Conflicts: bar-dev Replaces: bar-dev
and similarly bar-dev declares Conflicts/Replaces on foo-dev.
In addition, both packages should declare
BuildDependsOnly: True
This inhibits others from writing packages which depend on foo-dev or bar-dev, since any such dependency will prevent the smooth operation of the Conflicts/Replaces method.
There are some packages containing header files for which it's not appropriate to declare BuildDependsOnly to be true. In that case, the package should declare
BuildDependsOnly: False
and the reason must be given in the DescPackaging field.
The BuildDependsOnly field should only be mentioned in the package's .info
file if the package contains header files, installed into
%i/include
(or subdirectories thereof).
As of fink 0.20.5, "fink validate" will issue a warning for any .deb which contains header files and at least one dylib, and does not declare BuildDependsOnly to be either true or false. (It is possible that in future versions of fink, this warning will be expanded to cover the case of a .deb with header files and a static library as well.)
The goal of the Shared Library Policy is to allow assure
compatibility between libraries supplied by one package and
libraries or programs that use them in a different package. Some
packages may have shared libraries that are not designed to be used
by other packages. Common situations include a suite of programs
that come with a back-end library of utility functions or a program
that comes with plugins to handle various features. Because these
libraries are "private" to the package that has them, they do not
require being packaged with separate -shlibs
or BuildDependsOnly
SplitOffs.
The Shlibs field
In addition to putting the shared libraries in the correct package, as of
version 4 of this policy, you must also declare all of the shared libraries
using the Shlibs
field. This field has one line for each
shared library, which contains the -install_name
of the
library. If the library is public, its Shlibs
entry also
lists the -compatibility_version
, versioned
dependency information specifying the Fink package which provides
this library at this compatibility version, and the library
architecture. (The library architecture may either be "32", "64", or
"32-64", and may be absent. If the library architecture is not
explicitly listed, it defaults to the standard value for the current
architecture of Fink; these standard values are "32" for the powerpc
and i386 architectures, and "64"
for the x86_64 architecture.)
The dependency should
be stated in the form foo (>= version-revision)
where
version-revision
refers to
the first version of a Fink package which made
this library (with this compatibility version) available. For example,
a declaration
Shlibs: << %p/lib/libbar.1.dylib 2.1.0 bar1 (>= 1.1-2) 32 <<
indicates that a (32-bit)
library with -install_name
%p/lib/libbar.1.dylib
and -compatibility_version
2.1.0 has been installed since
version 1.1-2 of the bar1 package. In addition, this declaration
amounts to a promise
from the maintainer that a 32-bit
library with this name and a compatibility-version
of at least 2.1.0 will always be found in later versions of the bar1
package.
Note the use of %p in the name of the library, which allows the correct
-install_name
to be found by all users of Fink, no matter
what prefix they have chosen.
When a package is updated, usually the Shlibs
field can simply
be copied to the next version/revision of the package. The exception to
this is if the -compatibility_version
increases: in that
case, the version number in the dependency information should be changed
to the current version/revision (which is the first version/revision to
provide the library with the new compatibility version number).
The Shlibs
entry for a private library uses a different syntax:
Shlibs: << !%p/lib/%N/libbar.1.dylib <<
The leading exclamation point indicates that this is a private library, and since the other information is not relevant in this case, it is not included.
Note that in this example, the private shared library has been placed
in its own subdirectory %N
of the
%i/lib
directory (which was named after the
package). This is a recommended procedure for private libraries,
as an additional safety measure, to prevent other packages from accidentally
linking to this library.
What to do when the major version number changes:
If the major version number changes from N to M, you will create two new packages barM and barM-shlibs. The package barM-shlibs can have no overlap with the package barN-shlibs, since many users will have both of these installed simultaneously. In package barM, you should use dependencies
Conflicts: barN Replaces: barN
and similarly, you should revise barN to include dependencies
Conflicts: barM Replaces: barM
Users will then see barN and barM shuffling in and out as various other packages are built which depend on one version or another of the shared library, while barN-shlibs and barM-shlibs remain permanently installed.
Packages containing both binary files and libraries:
When an upstream package contains both binary files and public libraries, some
care must be exercised in constructing fink packages. In some cases,
the only binary files will be things like foo-config
which
are presumably only used at build time and never at run time. In these
cases, the binaries can go with the header files in the foo
package.
In other cases, the binary files will be needed by other packages at
runtime, and they must be split off into a separate fink package with
a name something like foo-bin
. The foo-bin
package should depend on the foo-shlibs
package, and
maintainers of other packages should be encouraged to use
Depends: foo-bin BuildDepends: foo
which will take care of foo-shlibs implicitly.
Upgrading presents a problem in this situation, however, since users won't
be prompted to install foo-bin
. To work around this, until
all other package maintainers have revised their packages as above,
your foo
package can say
Depends: foo-shlibs (= exact.version), foo-bin
This will force the installation of foo-bin on most users' systems, until
such time as the other package maintainers have upgraded their packages
which depend on foo
.
As of fink-0.28.0 (released in January 2008), the format of
the Shlibs
entry for a "private" shared library has
changed (see earlier discussion of the difference between a public
and a private shared library). Note that the Shared Library Policy
has always required all shared libraries to be listed; the change
here is only in the syntax of the Shlibs
field. Because
this type of shared library is not designed to be used by external
packages, there is no need to document its compatilibity or other
versioning. Instead, an exclamation-mark is used. For example,
if libquux.3.dylib
is
the install_name
of a private shared library, it would
be listed as follows:
Shlibs: << !%p/lib/libquux.3.dylib <<
3.5 Perl Modules
Fink's policy about perl modules, originally implemented in May 2003, has been revised as of April 2004.
Traditionally, the Fink packages for perl modules had the suffix
-pm
, and were built using the Type: perl
directive, which stores the perl module's files in /opt/sw/lib/perl5
and/or
/opt/sw/lib/perl5/darwin
. Under the policy
now in place, this storage location is only
permitted for perl modules which are independent of the version of perl
being used to compile them (and which do not depend on other perl modules
that lack this independence-of-version).
The perl modules which are version-dependent are the so-called XS modules,
which frequently contain compiled C code as well as pure perl routines.
There are a number of ways of recognizing these, including the presence
of a file with a suffix .bundle
.
A version-dependent perl module must be built using a versioned binary
of perl, such as perl5.12.3
, and must store its files in
versioned subdirectories of the standard perl directories, such as
/opt/sw/lib/perl5/5.12.3
and /opt/sw/lib/perl5/5.12.3/darwin
. By convention, package names
use the suffix -pm5123
for
a perl module of version 5.12.3. Similar storage and naming conventions
are in force for other versions of perl, which include
perl 5.10.0 (in the 10.6 tree only), perl 5.12.4 (in the 10.7 tree only), and
perl 5.16.2 (in the 10.7 tree only).
The directive Type: perl 5.12.3
automatically uses the
versioned perl binary and stores the files in the correct subdirectories.
(This directive is available starting with version 0.13.0 of fink.)
Under the May 2003 policy, it was permitted to create a
-pm
package which is essentially
a "bundle" package that loads the -pm560
variant or any
others which may be exist. Under the April 2004 policy this is discouraged,
and after a transitional period was outlawed entirely.
As of fink 0.20.2, the system-perl virtual package automatically
"Provides" certain perl modules depending on the system-perl version. The
code generating the list of provided perl modules is found in the
VirtPackage.pm
file that is part of the fink
package.
As different system perls provide different modules, package maintainers are encouraged to check to be sure that they are assuming the correct list when using provided perl modules.
Effective with version 0.13.0 of fink, the fink validate
command when applied to a .deb
file will check to see if
the fink package is an XS module which has been installed in a non-versioned
directory, and will issue a warning if so.
Users may have more than one version of perl installed at a time, so
any perl-versioned module packages must be written to allow more than
one version of themselves to be installed concurrently. One must use
care when installing manpages and binary or other script executables
in these packages in order to prevent installation conflicts due to
filename collisions.
You are not allowed to have any files in a package whose name ends
with -pmXYZ that would have an identical pathname across
different XYZ. Using Replaces
to allow the
same-named files to overwrite each other in different perl-versions of
these perl-module packages is no longer acceptable.
As a simple solution for manpages, starting in
March 2005, Fink has defined alternate locations in MANPATH:
%p/lib/perl5/X.Y.Z/man
for each perl-X.Y.Z. You
no longer need to create mutually-exclusive -man or -doc SplitOff
packages. For
example, to avoid conflicts between uri-pm5124 and uri-pm5162, the
same-named URI.3pm
manpage is installed
as %p/lib/perl5/5.12.4/man/man3/URI.3pm
and
%p/lib/perl5/5.16.2/man/man3/URI.3pm
,
respectively. Note that the default scripts provided by Type:
perl X.Y.Z
have not changed, so you will have to locate the
manpages here manually in your InstallScript
. If you
don't have a highly customized script, you can still use the default
one, and then simply move the files manually:
%{default_script} mv %i/share/man %i/lib/perl5/5.12.4
That will move all manpages. If you wish to move only one section of manpages (for example, only section 3, the module manpages, not script manpages in section 1), a similar approach works:
%{default_script} mkdir -p %i/lib/perl5/5.12.4/man mv %i/share/man/man3 %i/lib/perl5/5.12.4/man
If you have executables, for example, demo or utility scripts
in %p/bin
, you have several options. One example
is to put these files (and their associated manpages and/or other
related files) in a %N-bin splitoff package. Use of
Conflicts
and Replaces
fields ensures that
installation of different perl-version forms of these packages, which
contain files of the same name, is mutually exclusive. The user can
install many different perl-versions of the runtime modules, and then
choose whichever one perl-version of the scripts he wants at a given
time. For example, Tk.pm comes with an
executable ptksh
, so the set of tk-pm* packages
could be constructed as follows:
Info2: << Package: tk-pm%type_pkg[perl] Type: perl (5.12.3 5.12.4 5.16.2) InstallScript: << %{default_script} mkdir -p %i/lib/perl5/%type_raw[perl]/man mv %i/share/man/man3 %i/lib/perl5/%type_raw[perl]/man << SplitOff: << Package: %N-bin Depends: %N Conflicts: %{Ni}5.12.3, %{Ni}5.12.4, %{Ni}5.16.2 Replaces: %{Ni}5.12.3, %{Ni}5.12.4, %{Ni}5.16.2 Files: bin share/man/man1 << <<
An alternative arrangement is to rename the scripts and their manpages to include perl-version information. This method means there is no naming conflict at all, so one does not need the mutually-exclusive %N-bin splitoffs:
Info2: << Package: tk-pm%type_pkg[perl] Type: perl (5.12.3 5.12.4 5.16.2) InstallScript: << %{default_script} mkdir -p %i/lib/perl5/%type_raw[perl]/man mv %i/share/man/man3 %i/lib/perl5/%type_raw[perl]/man mv %i/bin/ptksh %i/bin/ptksh%type_raw[perl] mv %i/share/man/man1/ptksh.1 %i/share/man/man1/ptksh%type_raw[perl].1 << <<
The user accesses ptksh for whichever perl she wants. For convenience,
one could use update-alternatives
to allow users to be
able to access these by their generic (no perl-version) names as well.
Also as of March 2005, the location of manpages and modules installed
by fink packages for perl itself (packages perlXYZ and perlXYZ-core
other than the perl-version provided by Apple) has changed. As a
result of this relocation, other fink packages that supply updated
versions of core perl modules should not list any perlXYZ or
perlXYZ-core packages in the Replaces
field.
3.6 Emacs Policy
The Fink project has chosen to follow the Debian project's policy
regarding emacs, with a few small differences.
(The Debian policy document can be found at
http://www.debian.org/doc/packaging-manuals/debian-emacs-policy.)
There are two differences in the Fink policy. First,
this policy only applies to the emacs21
, emacs22
, and
emacs23
packages in fink at the moment, not to the xemacs package. (This
may change some day in the future.) And second, unlike the Debian policy,
Fink packages are allowed to install things directly into
/opt/sw/share/emacs/site-lisp.
3.7 Source Policy
Sources should normally be downloaded from the location(s) that the upstream
developer(s) use, and any modifications for Fink should be done through the use
of a PatchFile and/or a PatchScript. Do not make changes manually and use a changed
source archive as a Source
in your Fink packaging.
If a VCS checkout (e.g. from git or svn) is to be used, e.g. because a project doesn't do formal releases, or a fix for a particular issue has been added between releases of a package, an acceptable source can be generated via the following method:
- Check out the package, preferably at a definite revision of the VCS.
- Make an archive from the VCS checkout (e.g. zip, tar, tar.gz,
or tar.bz2).
Give the tarball a unique version. For example, you can include the VCS revision in the archive name, e.g.
foo-0svn1234.tar.gz
for a package that doesn't make releases, orbar-1.2.3+svn4567.tar.bz2
for a Fink package which is between upstream releases. - Use the same
Version
in your.info
file. - It is also useful to put the commands that you ran to generate the source tarball in the
DescPackaging
field. - Upload the tarball to a public download site where users can use
fink
to download it. If you don't have ready access to one, ask on the Fink developers mailing list or the #fink IRC channel, and someone should be able to help.
3.8 File Download Policy
Packages are not to download any files during the unpack, patch, compile, install, or build phases of the build process. Any large patches (i.e. larger than can be accommodated conveniently in a PatchFile) that need to be applied should set up as additional Sources in accordance with the Source Policy.
Packages may download data in a PostInstScript after they have been installed on the system, under some limited circumstances:
- No updates to the package itself are allowed.
- The nature of the data is such that it couldn't easily be packaged for Fink. E.g.
virus definitions for
clamav
can be downloaded during this phase, because they change continually.
If you are unsure, contact the Fink Core Team.
Next: 4. Filesystem Layout