FreeBSD Documentation Project Primer for New Contributors
Prev | Chapter 7 The Documentation Build Process | Next

# 7.3 FreeBSD Documentation Project make includes

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

- `doc.project.mk` is the main project include file, which includes all the following include files, as necessary.

- `doc.subdir.mk` handles traversing of the document tree during the build and install processes.

- `doc.install.mk` provides variables that affect ownership and installation of documents.

- `doc.docbook.mk` is included if `DOCFORMAT` is `docbook` and `DOC` is set.

## 7.3.1 doc.project.mk

By inspection:

    DOCFORMAT?=	docbook
    MAINTAINER?=	doc@FreeBSD.org

    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 `.endif`s 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.

Prev | Home | Next
Understanding Makefiles in the Documentation tree | Up | The Website