Google turned up nothing when I was searching for how to use ccache with NetBSD's script. My "solutions" are fairly ugly but hopefully point someone in the right direction. There may very well be better ways of doing things, but this works for me.

(note: These steps were used for a cross-compilation of NetBSD_4.0/i386 on a FreeBSD_6.2/i386 host. The basic ideas should be fairly generic and applicable to other host/target pairs, including native NetBSD builds. The basic ideas might also help in getting to use distcc)

The goal is to use ccache for c/c++ compiles done by (the "target" e.g. "release", "distribution", etc. should not matter, any target that compiles c/c++ code can potentially benefit from using ccache).

This goal can be achieved by realizing 2 subgoals:

Objective 1) - make use ccache for HOST_CC/HOST_CXX (host compiler)

Objective 2) - make use ccache for CC/CXX (target compiler)

e.g. when compiling NetBSD on a FreeBSD system, HOST_CC/HOST_CXX point to a FreeBSD compiler, which will build a NetBSD cross-compiler (CC/CXX) that runs on the host system.

For objective 1), my issue turned out to be that there are some Makefiles in the NetBSD sources that prefix some commands with /usr/bin/env -i, which clears the environment. In my case, my ccache command invocation requires CCACHE_DIR/CCACHE_PATH/PATH to be set appropriately, which /usr/bin/env -i breaks.

Fair is fair, so my workaround was simply to use the env command myself in HOST_CC/HOST_CXX:

export HOST_CC='env CCACHE_DIR=/whereever CCACHE_PATH=/whereever PATH=/whereever /usr/local/libexec/ccache/cc'

Note: you might have quoting issues if CCACHE_DIR/CCACHE_PATH/PATH contain space characters. Such issues are beyond the scope of this document.

Objective 2) is a bit hairer.

My first approach was simply to stick

CC = <ccache_stuff> ${CC}
CXX = <ccache_stuff> ${CXX}

in a $MAKECONF file, and point at that. This fails because (near as I can tell) in XXX/src/share/mk/ around line 199 (w/ NetBSD 4.0 sources) there are lines of the form:

if ${USETOOLS_GCC:Uyes} == "yes"                   #  {

Even though $MAKECONF is included at the top of, these lines will override whatever $MAKECONF sets CC and friends to.

Although I tried to avoid patching the sources at all (I build from a script, trying to automate things) I caved and added a line at line 208 in XXX/src/share/mk/

.endif  # EXTERNAL_TOOLCHAIN                        # }

# below line was added
.-include "${MAKECONF}"

to force to use my CC/CXX values from my $MAKECONF.

At the least, you will probably need to ensure that


are in the environment for CC/CXX. In contrast, $tool_dir/bin is NOT needed in these vars for HOST_CC/HOST_CXX.

NOTE: $tool_dir can be specified to via ``-T

Finally, when I had a $MAKECONF with:

CC = /usr/bin/env \
 CCACHE_DIR=<wherever> \
 CCACHE_PATH=<wherever> \
 PATH=<whatever> \
 /usr/local/bin/ccache \

(sans backslashes and newlines) and thought I had won, my compile seemed to hang forever. Not sure what caused this.

Anyhow, I ended up creating CC/CXX wrapper scripts (well, changing my build script that calls to create wrappers)

My CC/CXX scripts are just (sans backslashes and newlines):

#! /bin/sh
# fill in with yer own paths, target arch., etc.
exec /usr/bin/env \
 CCACHE_DIR=/usr/obj/ccache \
 PATH=/XXX/TOOLS/bin:<rest of $PATH> \
 /usr/local/bin/ccache \
 /XXX/TOOLS/bin/<arch>--netbsd<obj_format>-<gcc/c++> \

NOTE: "$@" is important. $* will not handle multiple args containing spaces correctly.

And the $MAKECONF I (my script) passes to is simply

CC = /xxx/path_to_cc_wrapper
CXX = /xxx/path_to_cxx_wrapper

YMMV, but this setup works for me. If anyone knows better ways to do things, feel free to update this guide with your way of doing things. In particular, a method that does not require patching NetBSD sources at all, even if it is just a single line.