This page describes the new order for OPTIONS in the FreeBSD Ports Tree.

Status

This has been committed. The Porter's Handbook OPTIONS section has more information.

Rationale

The options framework has some problems:

Proposal

Here is the proposal and a patch that implements it.

Porter's Handbook page modified.

We introduce 3 different types of options: simple, multi and single.

A maintainer can define these options in the port Makefile. Some common ones will be defined system-wide.

Every option can have an optional description.

A maintainer can set a port's default options (via OPTIONS_DEFAULT) and override global options that the port doesn't support yet (via OPTIONS_EXCLUDE).

A user can set global options for all ports in make.conf:

OPTIONS_SET=    OPT1 OPT3

or, similarly, unset them:

OPTIONS_UNSET=  OPT10 OPT15

Per-port options can be specified in two ways for a given port:

${UNIQUENAME}_SET=      OPT1
${UNIQUENAME}_UNSET=    OPT2

zsh_SET=        OPT1
zsh_UNSET=      OPT2

OPTIONS_SET=    OPT1
OPTIONS_UNSET=  OPT2

make WITH=extrastuff WITHOUT=DOCS

We will supply some generic options descriptions as it is currently done in the KNOBS file.

In the patch nothing is activated by default; the user has to invoke check-options manually.

The old framework has been reimplemented on top of the new one. It should also be easy to extend to add more features later.

Operation

The framework checks how the options are set using the following precedence:

  1. sets the default global options as defined by portmgr;
  2. removes any global option excluded by the port maintainer via OPTIONS_EXCLUDE;
  3. replaces all the above via OPTIONS_OVERRIDE if set;
  4. overrides any of the above using the per-port options as defined by the maintainer;
  5. overrides any of the above using the system-wide options (OPTIONS_(UN)SET) set by the user in make.conf;
  6. overrides any of the above using the per-port options set by the user in make.conf (${UNIQUENAME}_SET and ${UNIQUENAME}_UNSET);
  7. overrides any of the above using the legacy per-port OPTIONS+= in /var/db/ports/${UNIQUENAME}/options (note: usage of OPTIONS+= is deprecated);
  8. overrides any of the above using the per-port OPTIONSFILE (as set by the dialog UI).

The framework then checks for consistency of the exclusive options and the 1-n options that are set via 'make check-options'.

Short example

Here's a Makefile example that includes each type of option:

OPTIONS_DEFINE=         OPT1 OPT2 OPT3

OPTIONS_MULTI=          GRP1 GRP2
OPTIONS_MULTI_GRP1=     OPT4 OPT5
OPTIONS_MULTI_GRP2=     OPT6 OPT7

OPTIONS_SINGLE= SEL1
OPTIONS_SINGLE_SEL1=    OPT8 OTP9 OPT10

OPTIONS_DEFAULT=        OPT2 OPT3 OPT9 OPT7 OPT8 OPT4
OPTIONS_EXCLUDE=        NLS DOCS

To define a desciption for a given option:

OPT1_DESC= Description of my option

'make showconfig' will present all the options and their descriptions:

===> The following configuration options are available:
OPT1=off: Description of my option
OPT2=on
OPT3=on
====> Options available for the multi GRP1: you must choose at least one of them
OPT4=on
OPT5=off
====> Options available for the multi GRP2: you must choose at least one of them
OPT6=off
OPT7=on
====> Options available for the single SEL1: you must select only one of them
OPT8=on
OPT9=off
OPT10=off

What users need to know

Variable

Function

OPTIONS_SET

globally set some options

OPTIONS_UNSET

globally unset some options

UNIQUENAME_SET

set per-port choice of options

UNIQUENAME_UNSET

unset per-port choice of options

OPTIONS_OVERRIDE is to bypass everything and directly set the option wanted for the ports, whatever is normally set; use with caution.

See above for the precedence and a zsh example.

Tip: If UNIQUENAME is unknown, it can be found with (use apache22 as example):

% make -C /usr/ports/*/apache22 -VUNIQUENAME

For example, the following in make.conf will enable PROXY and PROXY_HTTP in Apache:

apache22_SET= PROXY PROXY_HTTP

What maintainers need to know

For the maintainer to check if an option is set or not, we no longer need to choose between WITHOUT or WITH options. Options should be checked this way:

.include <bsd.port.options.mk>

#...

.if ${PORT_OPTIONS:MOPT1}
        @${ECHO_MSG} " the options OPT1 is set (aka on)"
.else
        @${ECHO_MSG} " the options OPT1 is not set (aka off)"
.endif

To check if an option is not set, you can use empty():

.include <bsd.port.options.mk>

#...

.if empty(PORT_OPTIONS:MOPT1)
        @${ECHO_MSG} " the options OPT1 is not set (aka off)"
.else
        @${ECHO_MSG} " the options OPT1 is set (aka on)"
.endif

Variables available to the maintainer are:

Variable

Function

OPTIONS_DEFINE

simple list of options

OPTIONS_MULTI

list of the name of option multi

OPTIONS_MULTI_NAME

list of options for a given multi

OPTIONS_SINGLE

list of the name of options single

OPTIONS_SINGLE_NAME

list of options for a given single

OPTIONS_DEFAULT

list of options to be activated by default

OPTIONS_DEFINE is the list of all options.

For simple (binary) options, if the maintainer does nothing, the option is off. However, if the maintainer adds the options to OPTIONS_DEFAULT:

OPTIONS_DEFINE= A B C D E
OPTIONS_DEFAULT= A C

then A=on, B=off, C=on, D=off, E=off.

For the other options:

Type of OPTION

Result

MULTI

at least 1 but possibly more choices must be made

SINGLE

at least 1 and no more than 1 choice must be made

NAME_DESC is a human readable description of the option.

If NAME is in OPTIONS_DEFINE then the SINGLE or MULTI concerned is conditional.

OPTIONS_EXCLUDE is used to remove an option from the list. For example, if DOCS does not mean anything for my port:

OPTIONS_EXCLUDE+= DOCS

OPTIONS_OVERRIDE can be used to for a port to be built only with the options given in OPTIONS_OVERRIDE. (However, check-config will still be used to force a valid combination of options).

If the maintainer wants to override a description, or set a description for a custom option OPT1, he just has to define:

OPT1_DESC= This is my description line

Finally, a compatibility layer allow the old OPTIONS to be valid declarations, but this usage is deprecated.

What committers need to know:

bsd.options.desc.mk is the central point to define common options and their default descriptions:

OPT_DESC?= A cool description

What portmgr needs to know

The first lines of bsd.options.mk contain ALL_OPTIONS, which are options global to the entire ports tree.

Next are PORT_OPTIONS, which are the options that portmgr claims that should be on for the whole tree by default:

PORT_OPTIONS+= <NAME> if portmgr decide an option should be on by default

This forces all ports to have the given set of options (but which can be ignored by maintainers using OPTIONS_EXCLUDE).

A maintainer has no possibility to unset it by default, but he can still ignore the option using OPTIONS_EXCLUDE.

Notice that in the code, DOCS is used instead of its NO* counterpart NOPORTDOCS. For compatibility with older code, setting DOCS to false will define NOPORTDOCS and so on for NLS.

By default for compatibility DOCS is set to on and NLS is set to on.

Implementation details

The options logic is split into 3 files:

The following new targets are added to bsd.port.mk:

All the old *config targets (e.g. showconfig) have been reimplemented on top of the new code.

The dialog now prints all the options +. The multis are printed this way:

and the single:

Other changes

An example:

Here is an example of a trivial port Makefile, and what the targets do in its case:

# cat Makefile

PORTNAME=       test
CATEGORIES=     sysutils

OPTIONS_DEFINE= DOCS NLS A B C D E
OPTIONS_MULTI=A G
OPTIONS_SINGLE=B F
OPTIONS_MULTI_A=M N O
OPTIONS_MULTI_G=P Q
OPTIONS_SINGLE_B=R Z
OPTIONS_SINGLE_F=Y W

.include <bsd.port.mk>

---> check-config

# make
===>  Vulnerability check disabled, database not found
===>  License check disabled, port has not defined LICENSE
====> You should select one and only one options from the F single
*** Error code 1

---> showconfig

# make showconfig
===> The following configuration options are available:
      DOCS=on: Build and install the port documentations
      NLS=on: Build and install the port with localisation
      A=off
      B=off
      C=off
      D=off
      E=off
====> Options available for the multi A: you must choose at least one of them
      M=off
      N=off
      O=off
====> Options available for the multi G: you must choose at least one of them
      P=off
      Q=off
====> Options available for the single B: you must select only one of them
      R=off
      Z=off
====> Options available for the single F: you must select only one of them
      Y=off
      W=off
===> Use 'make config' to modify these settings

---> pretty-print-config

# make pretty-print-config
+DOCS +NLS -A -B -C -D -E A[ -M -N -O ] G[-P -Q ] B( -R -Z ) F( -Y -W )

Another example:

A use case may help: consider

OPTIONS_DEFINE=   A
OPTIONS_SINGLE=   A
OPTIONS_SINGLE_A= B C D

This means that the A single is conditional on the A option.

If A option is "on" then we will check is the user has correctly set only one of the following: B C D

This is to have a 0 or 1 among a list option type.

ROADMAP

Things that need to be discussed are:

Ports/Options/OptionsNG (last edited 2013-10-17 01:37:40 by EitanAdler)