7.3 FreeBSD Documentation Project make includes

This is best explained by inspection of the code. Here are the system include files:

7.3.1 doc.project.mk

By inspection:

DOCFORMAT?=    docbook
MAINTAINER?=    [email protected]

PREFIX?=    /usr/local
PRI_LANG?=  en_US.ISO8859-1

.if defined(DOC)
.if ${DOCFORMAT} == "docbook"
.include "doc.docbook.mk"
.endif
.endif

.include "doc.subdir.mk"
.include "doc.install.mk"

7.3.1.1 Variables

DOCFORMAT and MAINTAINER are assigned default values, if these are not set by the document make file.

PREFIX is the prefix under which the documentation building tools are installed. For normal package and port installation, this is /usr/local.

PRI_LANG should be set to whatever language and encoding is natural amongst users these documents are being built for. US English is the default.

Note: PRI_LANG in no way affects what documents can, or even will, be built. Its main use is creating links to commonly referenced documents into the FreeBSD documentation install root.

7.3.1.2 Conditionals

The .if defined(DOC) line is an example of a make conditional which, like in other programs, defines behavior if some condition is true or if it is false. defined is a function which returns whether the variable given is defined or not.

.if ${DOCFORMAT} == "docbook", next, tests whether the DOCFORMAT variable is "docbook", and in this case, includes doc.docbook.mk.

The two .endifs close the two above conditionals, marking the end of their application.

7.3.2 doc.subdir.mk

This is too long to explain by inspection, you should be able to work it out with the knowledge gained from the previous chapters, and a little help given here.

7.3.2.1 Variables

  • SUBDIR is a list of subdirectories that the build process should go further down into.

  • ROOT_SYMLINKS is the name of directories that should be linked to the document install root from their actual locations, if the current language is the primary language (specified by PRI_LANG).

  • COMPAT_SYMLINK is described in the Subdirectory Makefile section.

7.3.2.2 Targets and macros

Dependencies are described by target: dependency1 dependency2 ... tuples, where to build target, you need to build the given dependencies first.

After that descriptive tuple, instructions on how to build the target may be given, if the conversion process between the target and its dependencies are not previously defined, or if this particular conversion is not the same as the default conversion method.

A special dependency .USE defines the equivalent of a macro.

_SUBDIRUSE: .USE
.for entry in ${SUBDIR}
    @${ECHO} "===> ${DIRPRFX}${entry}"
    @(cd ${.CURDIR}/${entry} && \
    ${MAKE} ${.TARGET:S/realpackage/package/:S/realinstall/install/} DIRPRFX=${DIRPRFX}${entry}/ )
.endfor

In the above, _SUBDIRUSE is now a macro which will execute the given commands when it is listed as a dependency.

What sets this macro apart from other targets? Basically, it is executed after the instructions given in the build procedure it is listed as a dependency to, and it does not adjust .TARGET, which is the variable which contains the name of the target currently being built.

clean: _SUBDIRUSE
    rm -f ${CLEANFILES}

In the above, clean will use the _SUBDIRUSE macro after it has executed the instruction rm -f ${CLEANFILES}. In effect, this causes clean to go further and further down the directory tree, deleting built files as it goes down, not on the way back up.

7.3.2.2.1 Provided targets

  • install and package both go down the directory tree calling the real versions of themselves in the subdirectories (realinstall and realpackage respectively).

  • clean removes files created by the build process (and goes down the directory tree too). cleandir does the same, and also removes the object directory, if any.

7.3.2.3 More on conditionals

  • exists is another condition function which returns true if the given file exists.

  • empty returns true if the given variable is empty.

  • target returns true if the given target does not already exist.

7.3.2.4 Looping constructs in make (.for)

.for provides a way to repeat a set of instructions for each space-separated element in a variable. It does this by assigning a variable to contain the current element in the list being examined.

_SUBDIRUSE: .USE
.for entry in ${SUBDIR}
    @${ECHO} "===> ${DIRPRFX}${entry}"
    @(cd ${.CURDIR}/${entry} && \
    ${MAKE} ${.TARGET:S/realpackage/package/:S/realinstall/install/} DIRPRFX=${DIRPRFX}${entry}/ )
.endfor

In the above, if SUBDIR is empty, no action is taken; if it has one or more elements, the instructions between .for and .endfor would repeat for every element, with entry being replaced with the value of the current element.