Table of Contents
The pkgsrc infrastructure consists of many small Makefile fragments. Each such fragment needs a properly specified interface. This chapter explains how such an interface looks like.
Whenever a variable is defined in the pkgsrc infrastructure, the location and the way of definition provide much information about the intended use of that variable. Additionally, more documentation may be found in a header comment or in this pkgsrc guide.
A special file is
	mk/defaults/mk.conf, which lists all
	variables that are intended to be user-defined. They are either
	defined using the ?= operator or they are
	left undefined because defining them to anything would
	effectively mean “yes”. All these variables may be
	overridden by the pkgsrc user in the MAKECONF
	file.
Outside this file, the following conventions apply:
	Variables that are defined using the ?=
	operator may be overridden by a package.
Variables that are defined using the =
	operator may be used read-only at run-time.
Variables whose name starts with an underscore must not be accessed outside the pkgsrc infrastructure at all. They may change without further notice.
These conventions are currently not applied consistently to the complete pkgsrc infrastructure.
All variables that contain lists of things should default
	to being empty. Two examples that do not follow this rule are
	USE_LANGUAGES and
	DISTFILES. These variables cannot simply be
	modified using the += operator in package
	Makefiles (or other files included by
	them), since there is no guarantee whether the variable is
	already set or not, and what its value is. In the case of
	DISTFILES, the packages “know”
	the default value and just define it as in the following
	example.
DISTFILES=      ${DISTNAME}${EXTRACT_SUFX} additional-files.tar.gz
Because of the selection of this default value, the same
	value appears in many package Makefiles. Similarly for
	USE_LANGUAGES, but in this case the default
	value (“c”) is so short that it
	doesn't stand out. Nevertheless it is mentioned in many
	files.
Variable evaluation takes place either at load time or at runtime, depending on the context in which they occur. The contexts where variables are evaluated at load time are:
The right hand side of the :=
	and != operators,
Make directives like .if or
	.for,
Dependency lines.
A special exception are references to the iteration
	variables of .for loops, which are expanded
	inline, no matter in which context they appear.
As the values of variables may change during load time,
	care must be taken not to evaluate them by accident. Typical
	examples for variables that should not be evaluated at load time
	are DEPENDS and
	CONFIGURE_ARGS. To make the effect more
	clear, here is an example:
CONFIGURE_ARGS=         # none
CFLAGS=                 -O
CONFIGURE_ARGS+=        CFLAGS=${CFLAGS:Q}
CONFIGURE_ARGS:=        ${CONFIGURE_ARGS}
CFLAGS+=                -Wall
This code shows how the use of the :=
	operator can quickly lead to unexpected results. The first
	paragraph is fairly common code. The second paragraph evaluates
	the CONFIGURE_ARGS variable, which results in
	CFLAGS=-O. In the third paragraph, the
	-Wall is appended to the
	CFLAGS, but this addition will not appear in
	CONFIGURE_ARGS. In actual code, the three
	paragraphs from above typically occur in completely unrelated
	files.
There are many ways in which the definition and use of a
	variable can be restricted in order to detect bugs and violations
	of the (mostly unwritten) policies. A package can be checked with
	pkglint -Wall to see whether it meets these
	rules.
Most of the .mk files fall into one
	of the following classes. Cases where a file falls into more
	than one class should be avoided as it often leads to subtle
	bugs.
In a traditional imperative programming language some of
	the .mk files could be described as
	procedures. They take some input parameters and—after
	inclusion—provide a result in output parameters. Since all
	variables in Makefiles have global scope
	care must be taken not to use parameter names that have already
	another meaning. For example, PKGNAME is a
	bad choice for a parameter name.
Procedures are completely evaluated at preprocessing time.
	That is, when calling a procedure all input parameters must be
	completely resolvable. For example,
	CONFIGURE_ARGS should never be an input
	parameter since it is very likely that further text will be
	added after calling the procedure, which would effectively apply
	the procedure to only a part of the variable. Also, references
	to other variables will be modified after calling the
	procedure.
A procedure can declare its output parameters either as suitable for use in preprocessing directives or as only available at runtime. The latter alternative is for variables that contain references to other runtime variables.
Procedures shall be written such that it is possible to call the procedure more than once. That is, the file must not contain multiple-inclusion guards.
Examples for procedures are
	mk/bsd.options.mk and
	mk/buildlink3/bsd.builtin.mk. To express
	that the parameters are evaluated at load time, they should be
	assigned using the := operator, which should
	be used only for this purpose.
Action files take some input parameters and may define runtime variables. They shall not define loadtime variables. There are action files that are included implicitly by the pkgsrc infrastructure, while other must be included explicitly.
An example for action files is
	mk/subst.mk.
Package Makefiles usually consist of
	a set of variable definitions, and include the file
	../../mk/bsd.pkg.mk in the very last line.
	Before that, they may also include various other
	*.mk files if they need to query the
	availability of certain features like the type of compiler or
	the X11 implementation. Due to the heavy use of preprocessor
	directives like .if and
	.for, the order in which the files are loaded
	matters.
This section describes at which point the various files are loaded and gives reasons for that order.
The very first action in bsd.prefs.mk
	is to define some essential variables like
	OPSYS, OS_VERSION and
	MACHINE_ARCH.
Then, the user settings are loaded from the file specified
	in MAKECONF, which is usually mk.conf.
	After that, those variables
	that have not been overridden by the user are loaded from
	mk/defaults/mk.conf.
After the user settings, the system settings and platform settings are loaded, which may override the user settings.
Then, the tool definitions are loaded. The tool wrappers are not yet in effect. This only happens when building a package, so the proper variables must be used instead of the direct tool names.
As the last steps, some essential variables from the wrapper and the package system flavor are loaded, as well as the variables that have been cached in earlier phases of a package build.
First, bsd.prefs.mk is loaded.
Then, the various *-vars.mk files are
	loaded, which fill default values for those variables that have
	not been defined by the package. These variables may later
	be used even in unrelated files.
Then, the file bsd.pkg.error.mk
	provides the target error-check that is added
	as a special dependency to all other targets that use
	DELAYED_ERROR_MSG or
	DELAYED_WARNING_MSG.
Then, the package-specific hacks from
	hacks.mk are included.
Then, various other files follow. Most of them don't have any dependencies on what they need to have included before or after them, though some do.
The code to check PKG_FAIL_REASON and
	PKG_SKIP_REASON is then executed, which
	restricts the use of these variables to all the files that have
	been included before. Appearances in later files will be
	silently ignored.
Then, the files for the main targets are included, in the order of later execution, though the actual order should not matter.
At last, some more files are included that don't set any interesting variables but rather just define make targets to be executed.