Options handling
Many packages have the ability to be built to support different
sets of features. bsd.options.mk is a framework
in pkgsrc that provides generic handling of those options that
determine different ways in which the packages can be built. It's
possible for the user to specify exactly which sets of options will be
built into a package or to allow a set of global default options
apply.
There are two broad classes of behaviors that one might want to
control via options. One is whether some particular feature is
enabled in a program that will be built anyway, often by including or
not including a dependency on some other package. The other is
whether or not an additional program will be built as part of the
package. Generally, it is better to make a split package for such
additional programs instead of using options, because it enables
binary packages to be built which can then be added separately. For
example, the foo package might have minimal dependencies (those
packages without which foo doesn't make sense), and then the foo-gfoo
package might include the GTK frontend program gfoo. This is better
than including a gtk option to foo that adds gfoo, because either that
option is default, in which case binary users can't get foo without
gfoo, or not default, in which case they can't get gfoo. With split
packages, they can install foo without having GTK, and later decide to
install gfoo (pulling in GTK at that time). This is an advantage to
source users too, avoiding the need for rebuilds.
Plugins with widely varying dependencies should usually be split
instead of options.
It is often more work to maintain split packages, especially if
the upstream package does not support this. The decision of split
vs. option should be made based on the likelihood that users will want
or object to the various pieces, the size of the dependencies that are
included, and the amount of work.
A further consideration is licensing. Non-free parts, or parts
that depend on non-free dependencies (especially plugins) should
almost always be split if feasible.
Global default options
Global default options are listed in
PKG_DEFAULT_OPTIONS, which is a list of the options
that should be built into every package if that option is supported.
This variable should be set in &mk.conf;.
Converting packages to use bsd.options.mk
The following example shows how
bsd.options.mk should be used
by the hypothetical ``wibble'' package, either in the package
Makefile, or in a file,
e.g. options.mk, that is included by the
main package Makefile.
PKG_OPTIONS_VAR= PKG_OPTIONS.wibble
PKG_SUPPORTED_OPTIONS= wibble-foo ldap
PKG_OPTIONS_OPTIONAL_GROUPS= database
PKG_OPTIONS_GROUP.database= mysql pgsql
PKG_SUGGESTED_OPTIONS= wibble-foo
PKG_OPTIONS_LEGACY_VARS+= WIBBLE_USE_OPENLDAP:ldap
PKG_OPTIONS_LEGACY_OPTS+= foo:wibble-foo
.include "../../mk/bsd.prefs.mk"
# this package was previously named wibble2
.if defined(PKG_OPTIONS.wibble2)
PKG_LEGACY_OPTIONS+= ${PKG_OPTIONS.wibble2}
PKG_OPTIONS_DEPRECATED_WARNINGS+= \
"Deprecated variable PKG_OPTIONS.wibble2 used, use ${PKG_OPTIONS_VAR} instead."
.endif
.include "../../mk/bsd.options.mk"
# Package-specific option-handling
###
### FOO support
###
.if !empty(PKG_OPTIONS:Mwibble-foo)
CONFIGURE_ARGS+= --enable-foo
.endif
###
### LDAP support
###
.if !empty(PKG_OPTIONS:Mldap)
. include "../../databases/openldap-client/buildlink3.mk"
CONFIGURE_ARGS+= --enable-ldap=${BUILDLINK_PREFIX.openldap-client}
.endif
###
### database support
###
.if !empty(PKG_OPTIONS:Mmysql)
. include "../../mk/mysql.buildlink3.mk"
.endif
.if !empty(PKG_OPTIONS:Mpgsql)
. include "../../mk/pgsql.buildlink3.mk"
.endif
The first section contains the information about which build
options are supported by the package, and any default options settings
if needed.
PKG_OPTIONS_VAR is the name of the
&man.make.1; variable that the user can set to override the default
options. It should be set to
PKG_OPTIONS.pkgbase. Do not set it to
PKG_OPTIONS.${PKGBASE}, since PKGBASE is not defined
at the point where the options are processed.
PKG_SUPPORTED_OPTIONS is a list of
build options supported by the package.
PKG_OPTIONS_OPTIONAL_GROUPS is a
list of names of groups of mutually exclusive options. The options in
each group are listed in
PKG_OPTIONS_GROUP.groupname.
The most specific setting of any option from the group takes
precedence over all other options in the group. Options from the
groups will be automatically added to
PKG_SUPPORTED_OPTIONS.
PKG_OPTIONS_REQUIRED_GROUPS is like
PKG_OPTIONS_OPTIONAL_GROUPS, but building the
packages will fail if no option from the group is
selected.
PKG_OPTIONS_NONEMPTY_SETS is a list
of names of sets of options. At least one option from each set must
be selected. The options in each set are listed in
PKG_OPTIONS_SET.setname.
Options from the sets will be automatically added to
PKG_SUPPORTED_OPTIONS. Building the package will
fail if no option from the set is selected.
PKG_SUGGESTED_OPTIONS is a list of
build options which are enabled by default.
PKG_OPTIONS_LEGACY_VARS is a list
of
USE_VARIABLE:option
pairs that map legacy &mk.conf; variables to
their option counterparts. Pairs should be added with
+=
to keep the listing of global legacy variables. A
warning will be issued if the user uses a legacy
variable.
PKG_OPTIONS_LEGACY_OPTS is a list
of
old-option:new-option
pairs that map options that have been renamed to their new
counterparts. Pairs should be added with +=
to keep
the listing of global legacy options. A warning will be issued if
the user uses a legacy option.
PKG_LEGACY_OPTIONS is a list of
options implied by deprecated variables used. This can be used for
cases that neither PKG_OPTIONS_LEGACY_VARS nor
PKG_OPTIONS_LEGACY_OPTS can handle, e. g. when
PKG_OPTIONS_VAR is renamed.
PKG_OPTIONS_DEPRECATED_WARNINGS is
a list of warnings about deprecated variables or options used, and
what to use instead.
A package should never modify
PKG_DEFAULT_OPTIONS or the variable named in
PKG_OPTIONS_VAR. These are strictly user-settable.
To suggest a default set of options, use
PKG_SUGGESTED_OPTIONS.
PKG_OPTIONS_VAR must be defined before
including bsd.options.mk. If none of
PKG_SUPPORTED_OPTIONS,
PKG_OPTIONS_OPTIONAL_GROUPS, and
PKG_OPTIONS_REQUIRED_GROUPS are defined (as can
happen with platform-specific options if none of them is supported on
the current platform), PKG_OPTIONS is set to the
empty list and the package is otherwise treated as not using the
options framework.
After the inclusion of bsd.options.mk, the
variable PKG_OPTIONS contains the list of selected
build options, properly filtered to remove unsupported and duplicate
options.
The remaining sections contain the logic that is specific to
each option. The correct way to check for an option is to check
whether it is listed in PKG_OPTIONS:
.if !empty(PKG_OPTIONS:Moption)
Option Names
Options that enable similar features in different packages (like
optional support for a library) should use a common name in all
packages that support it (like the name of the library). If another
package already has an option with the same meaning, use the same
name.
Options that enable features specific to one package, where it's
unlikely that another (unrelated) package has the same (or a similar)
optional feature, should use a name prefixed with
pkgname-.
If a group of related packages share an optional feature
specific to that group, prefix it with the name of the
main
package
(e. g. djbware-errno-hack).
For new options, add a line to
mk/defaults/options.description. Lines have two
fields, separated by tab. The first field is the option name, the
second its description. The description should be a whole sentence
(starting with an uppercase letter and ending with a period) that
describes what enabling the option does. E. g. Enable ispell
support.
The file is sorted by option names.
Determining the options of dependencies
When writing &buildlink3.mk; files, it is often necessary to list
different dependencies based on the options with which the package was
built. For querying these options, the file
pkgsrc/mk/pkg-build-options.mk should be used. A
typical example looks like this:
pkgbase := libpurple
.include "../../mk/pkg-build-options.mk"
.if !empty(PKG_BUILD_OPTIONS.libpurple:Mdbus)
...
.endif
Including pkg-build-options.mk here will set
the variable PKG_BUILD_OPTIONS.libpurple to the build
options of the libpurple package, which can then be queried like
PKG_OPTIONS in the options.mk
file. See the file pkg-build-options.mk for more
details.