aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile4
-rw-r--r--Makefile.inc16
-rw-r--r--share/mk/bsd.compiler.mk65
-rw-r--r--share/mk/bsd.dep.mk10
-rw-r--r--share/mk/bsd.lib.mk16
-rw-r--r--share/mk/bsd.opts.mk1
-rw-r--r--share/mk/bsd.prog.mk12
-rw-r--r--share/mk/local.meta.sys.mk6
-rw-r--r--share/mk/sys.mk4
-rw-r--r--sys/conf/kern.post.mk9
-rw-r--r--sys/conf/kern.pre.mk2
-rw-r--r--tools/build/options/WITH_CCACHE_BUILD42
12 files changed, 146 insertions, 31 deletions
diff --git a/Makefile b/Makefile
index 130fdbf67200..ce4c0f6963e8 100644
--- a/Makefile
+++ b/Makefile
@@ -100,6 +100,10 @@
# For more information, see the build(7) manual page.
#
+# This is included so CC is set to ccache for -V, and COMPILER_TYPE/VERSION
+# can be cached for sub-makes.
+.include <bsd.compiler.mk>
+
# Note: we use this awkward construct to be compatible with FreeBSD's
# old make used in 10.0 and 9.2 and earlier.
.if defined(MK_META_MODE) && ${MK_META_MODE} == "yes" && !make(showconfig)
diff --git a/Makefile.inc1 b/Makefile.inc1
index 3f37401b3823..c49bc4ce89ca 100644
--- a/Makefile.inc1
+++ b/Makefile.inc1
@@ -379,7 +379,7 @@ CROSSENV+= CC="${XCC} ${XCFLAGS}" CXX="${XCXX} ${XCFLAGS} ${XCXXFLAGS}" \
RANLIB=${XRANLIB} STRINGS=${XSTRINGS} \
SIZE="${XSIZE}"
-.if ${XCC:M/*}
+.if ${XCC:N${CCACHE_BIN}:M/*}
.if defined(CROSS_BINUTILS_PREFIX)
# In the case of xdev-build tools, CROSS_BINUTILS_PREFIX won't be a
# directory, but the compiler will look in the right place for it's
@@ -456,7 +456,7 @@ LIB32FLAGS= -m32 ${LIB32CPUFLAGS} -DCOMPAT_32BIT \
-isystem ${LIB32TMP}/usr/include/ \
-L${LIB32TMP}/usr/lib32 \
-B${LIB32TMP}/usr/lib32
-.if ${XCC:M/*}
+.if ${XCC:N${CCACHE_BIN}:M/*}
LIB32FLAGS+= --sysroot=${WORLDTMP}
.endif
@@ -1599,7 +1599,7 @@ _elftctools= lib/libelftc \
# If an full path to an external cross compiler is given, don't build
# a cross compiler.
-.if ${XCC:M/*} == "" && ${MK_CROSS_COMPILER} != "no"
+.if ${XCC:N${CCACHE_BIN}:M/*} == "" && ${MK_CROSS_COMPILER} != "no"
.if ${MK_CLANG_BOOTSTRAP} != "no"
_clang= usr.bin/clang
_clang_libs= lib/clang
diff --git a/share/mk/bsd.compiler.mk b/share/mk/bsd.compiler.mk
index 9ad4baee13b7..30da2aff8857 100644
--- a/share/mk/bsd.compiler.mk
+++ b/share/mk/bsd.compiler.mk
@@ -25,6 +25,71 @@
.if !target(__<bsd.compiler.mk>__)
__<bsd.compiler.mk>__:
+.include <bsd.opts.mk>
+
+# Handle ccache after CC is determined, but not if CC/CXX are already
+# overridden with a manual setup.
+.if ${MK_CCACHE_BUILD:Uno} == "yes" && \
+ (${CC:M*ccache/world/*} == "" || ${CXX:M*ccache/world/*} == "")
+# CC is always prepended with the ccache wrapper rather than modifying
+# PATH since it is more clear that ccache is used and avoids wasting time
+# for mkdep/linking/asm builds.
+LOCALBASE?= /usr/local
+CCACHE_WRAPPER_PATH?= ${LOCALBASE}/libexec/ccache
+CCACHE_BIN?= ${LOCALBASE}/bin/ccache
+.if exists(${CCACHE_BIN})
+# Export to ensure sub-makes can filter it out for mkdep/linking and
+# to chain down into kernel build which won't include this file.
+.export CCACHE_BIN
+# Expand and export some variables so they may be based on make vars.
+# This allows doing something like the following in the environment:
+# CCACHE_BASEDIR='${SRCTOP:H}' MAKEOBJDIRPREFIX='${SRCTOP:H}/obj'
+.for var in CCACHE_LOGFILE CCACHE_BASEDIR
+.if defined(${var})
+${var}:= ${${var}}
+.export ${var}
+.endif
+.endfor
+# Handle bootstrapped compiler changes properly by hashing their content
+# rather than checking mtime. For external compilers it should be safe
+# to use the more optimal mtime check.
+# XXX: CCACHE_COMPILERCHECK= string:<compiler_version, compiler_build_rev, compiler_patch_rev, compiler_default_target, compiler_default_sysroot>
+.if ${CC:N${CCACHE_BIN}:[1]:M/*} == ""
+CCACHE_COMPILERCHECK?= content
+.else
+CCACHE_COMPILERCHECK?= mtime
+.endif
+.export CCACHE_COMPILERCHECK
+# Remove ccache from the PATH to prevent double calls and wasted CPP/LD time.
+PATH:= ${PATH:C,:?${CCACHE_WRAPPER_PATH}(/world)?(:$)?,,g}
+# Ensure no bogus CCACHE_PATH leaks in which might avoid the in-tree compiler.
+CCACHE_PATH=
+.export CCACHE_PATH
+# Override various toolchain vars.
+.for var in CC CXX HOST_CC HOST_CXX
+.if defined(${var}) && ${${var}:M${CCACHE_BIN}} == ""
+${var}:= ${CCACHE_BIN} ${${var}}
+.endif
+.endfor
+# GCC does not need the CCACHE_CPP2 hack enabled by default in devel/ccache.
+# The port enables it due to ccache passing preprocessed C to clang
+# which fails with -Wparentheses-equality, -Wtautological-compare, and
+# -Wself-assign on macro-expanded lines.
+.if defined(COMPILER_TYPE) && ${COMPILER_TYPE} == "gcc"
+CCACHE_NOCPP2= 1
+.export CCACHE_NOCPP2
+.endif
+# Canonicalize CCACHE_DIR for meta mode usage.
+.if defined(CCACHE_DIR) && empty(.MAKE.META.IGNORE_PATHS:M${CCACHE_DIR})
+CCACHE_DIR:= ${CCACHE_DIR:tA}
+.MAKE.META.IGNORE_PATHS+= ${CCACHE_DIR}
+.export CCACHE_DIR
+.endif
+ccache-print-options: .PHONY
+ @${CCACHE_BIN} -p
+.endif # exists(${CCACHE_BIN})
+.endif # ${MK_CCACHE_BUILD} == "yes"
+
# Try to import COMPILER_TYPE and COMPILER_VERSION from parent make.
# The value is only used/exported for the same environment that impacts
# CC and COMPILER_* settings here.
diff --git a/share/mk/bsd.dep.mk b/share/mk/bsd.dep.mk
index 4eb4880da3be..a0e989254d32 100644
--- a/share/mk/bsd.dep.mk
+++ b/share/mk/bsd.dep.mk
@@ -48,11 +48,13 @@ CTAGSFLAGS?=
GTAGSFLAGS?= -o
HTAGSFLAGS?=
-.if ${CC} != "cc"
-MKDEPCMD?= CC='${CC} ${DEPFLAGS}' mkdep
-.else
-MKDEPCMD?= mkdep
+_MKDEPCC:= ${CC:N${CCACHE_BIN}}
+# XXX: DEPFLAGS can come out once Makefile.inc1 properly passes down
+# CXXFLAGS.
+.if !empty(DEPFLAGS)
+_MKDEPCC+= ${DEPFLAGS}
.endif
+MKDEPCMD?= CC='${_MKDEPCC}' mkdep
DEPENDFILE?= .depend
DEPENDFILES= ${DEPENDFILE}
.if ${MK_FAST_DEPEND} == "yes" && ${.MAKE.MODE:Unormal:Mmeta*} == ""
diff --git a/share/mk/bsd.lib.mk b/share/mk/bsd.lib.mk
index 579e36cd9240..7226f3f95d28 100644
--- a/share/mk/bsd.lib.mk
+++ b/share/mk/bsd.lib.mk
@@ -109,21 +109,23 @@ PO_FLAG=-pg
${CTFCONVERT_CMD}
.asm.po:
- ${CC} -x assembler-with-cpp -DPROF ${PO_CFLAGS} ${ACFLAGS} \
- -c ${.IMPSRC} -o ${.TARGET}
+ ${CC:N${CCACHE_BIN}} -x assembler-with-cpp -DPROF ${PO_CFLAGS} \
+ ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
${CTFCONVERT_CMD}
.asm.So:
- ${CC} -x assembler-with-cpp ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \
- -c ${.IMPSRC} -o ${.TARGET}
+ ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${PICFLAG} -DPIC \
+ ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
${CTFCONVERT_CMD}
.S.po:
- ${CC} -DPROF ${PO_CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CC:N${CCACHE_BIN}} -DPROF ${PO_CFLAGS} ${ACFLAGS} -c ${.IMPSRC} \
+ -o ${.TARGET}
${CTFCONVERT_CMD}
.S.So:
- ${CC} ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CC:N${CCACHE_BIN}} ${PICFLAG} -DPIC ${CFLAGS} ${ACFLAGS} \
+ -c ${.IMPSRC} -o ${.TARGET}
${CTFCONVERT_CMD}
.if !defined(_SKIP_BUILD)
@@ -249,7 +251,7 @@ ${SHLIB_NAME_FULL}: ${SOBJS}
.if defined(SHLIB_LINK) && !commands(${SHLIB_LINK:R}.ld)
@${INSTALL_SYMLINK} ${SHLIB_NAME} ${SHLIB_LINK}
.endif
- ${_LD} ${LDFLAGS} ${SSP_CFLAGS} ${SOLINKOPTS} \
+ ${_LD:N${CCACHE_BIN}} ${LDFLAGS} ${SSP_CFLAGS} ${SOLINKOPTS} \
-o ${.TARGET} -Wl,-soname,${SONAME} \
`NM='${NM}' NMFLAGS='${NMFLAGS}' lorder ${SOBJS} | tsort -q` ${LDADD}
.if ${MK_CTF} != "no"
diff --git a/share/mk/bsd.opts.mk b/share/mk/bsd.opts.mk
index a1f4ccec2aab..d242da5a59fd 100644
--- a/share/mk/bsd.opts.mk
+++ b/share/mk/bsd.opts.mk
@@ -66,6 +66,7 @@ __DEFAULT_YES_OPTIONS = \
WARNS
__DEFAULT_NO_OPTIONS = \
+ CCACHE_BUILD \
FAST_DEPEND \
CTF \
DEBUG_FILES \
diff --git a/share/mk/bsd.prog.mk b/share/mk/bsd.prog.mk
index 37ede4c94c6f..c4c783fb0084 100644
--- a/share/mk/bsd.prog.mk
+++ b/share/mk/bsd.prog.mk
@@ -82,9 +82,11 @@ ${PROG_FULL}: beforelinking
.endif
${PROG_FULL}: ${OBJS}
.if defined(PROG_CXX)
- ${CXX} ${CXXFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
+ ${CXX:N${CCACHE_BIN}} ${CXXFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} \
+ ${OBJS} ${LDADD}
.else
- ${CC} ${CFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
+ ${CC:N${CCACHE_BIN}} ${CFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} \
+ ${LDADD}
.endif
.if ${MK_CTF} != "no"
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
@@ -112,9 +114,11 @@ ${PROG_FULL}: beforelinking
.endif
${PROG_FULL}: ${OBJS}
.if defined(PROG_CXX)
- ${CXX} ${CXXFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
+ ${CXX:N${CCACHE_BIN}} ${CXXFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} \
+ ${OBJS} ${LDADD}
.else
- ${CC} ${CFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} ${LDADD}
+ ${CC:N${CCACHE_BIN}} ${CFLAGS:N-M*} ${LDFLAGS} -o ${.TARGET} ${OBJS} \
+ ${LDADD}
.endif
.if ${MK_CTF} != "no"
${CTFMERGE} ${CTFFLAGS} -o ${.TARGET} ${OBJS}
diff --git a/share/mk/local.meta.sys.mk b/share/mk/local.meta.sys.mk
index adc884bc5d16..9aac03d9d2c1 100644
--- a/share/mk/local.meta.sys.mk
+++ b/share/mk/local.meta.sys.mk
@@ -186,12 +186,6 @@ UPDATE_DEPENDFILE= NO
# define the list of places that contain files we are responsible for
.MAKE.META.BAILIWICK = ${SB} ${OBJROOT} ${STAGE_ROOT}
-.if defined(CCACHE_DIR)
-CCACHE_DIR := ${CCACHE_DIR:tA}
-.MAKE.META.IGNORE_PATHS += ${CCACHE_DIR}
-.export CCACHE_DIR
-.endif
-
CSU_DIR.${MACHINE_ARCH} ?= csu/${MACHINE_ARCH}
CSU_DIR := ${CSU_DIR.${MACHINE_ARCH}}
diff --git a/share/mk/sys.mk b/share/mk/sys.mk
index b6c75b6f96a6..ee0797e743df 100644
--- a/share/mk/sys.mk
+++ b/share/mk/sys.mk
@@ -317,11 +317,11 @@ YFLAGS ?= -d
${FC} ${RFLAGS} ${EFLAGS} ${FFLAGS} -c ${.IMPSRC} -o ${.TARGET}
.S.o:
- ${CC} ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
+ ${CC:N${CCACHE_BIN}} ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} -o ${.TARGET}
${CTFCONVERT_CMD}
.asm.o:
- ${CC} -x assembler-with-cpp ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} \
+ ${CC:N${CCACHE_BIN}} -x assembler-with-cpp ${CFLAGS} ${ACFLAGS} -c ${.IMPSRC} \
-o ${.TARGET}
${CTFCONVERT_CMD}
diff --git a/sys/conf/kern.post.mk b/sys/conf/kern.post.mk
index 851faaeaf6c0..42f67f644d7e 100644
--- a/sys/conf/kern.post.mk
+++ b/sys/conf/kern.post.mk
@@ -195,6 +195,7 @@ SFILES_CDDL= ${SFILES:M*/cddl/*}
kernel-depend: .depend
# The argument list can be very long, so use make -V and xargs to
# pass it to mkdep.
+_MKDEPCC:= ${CC:N${CCACHE_BIN}}
SRCS= assym.s vnode_if.h ${BEFORE_DEPEND} ${CFILES} \
${SYSTEM_CFILES} ${GEN_CFILES} ${SFILES} \
${MFILES:T:S/.m$/.h/}
@@ -219,14 +220,14 @@ DEPENDFILES_OBJS+= .depend.${__obj}
.if ${MK_FAST_DEPEND} == "no"
rm -f ${.TARGET}.tmp
${MAKE} -V CFILES_NOCDDL -V SYSTEM_CFILES -V GEN_CFILES | \
- CC="${CC}" xargs mkdep -a -f ${.TARGET}.tmp ${CFLAGS}
+ CC="${_MKDEPCC}" xargs mkdep -a -f ${.TARGET}.tmp ${CFLAGS}
${MAKE} -V CFILES_CDDL | \
- CC="${CC}" xargs mkdep -a -f ${.TARGET}.tmp ${ZFS_CFLAGS} \
+ CC="${_MKDEPCC}" xargs mkdep -a -f ${.TARGET}.tmp ${ZFS_CFLAGS} \
${FBT_CFLAGS} ${DTRACE_CFLAGS}
${MAKE} -V SFILES_NOCDDL | \
- CC="${CC}" xargs mkdep -a -f ${.TARGET}.tmp ${ASM_CFLAGS}
+ CC="${_MKDEPCC}" xargs mkdep -a -f ${.TARGET}.tmp ${ASM_CFLAGS}
${MAKE} -V SFILES_CDDL | \
- CC="${CC}" xargs mkdep -a -f ${.TARGET}.tmp ${ZFS_ASM_CFLAGS}
+ CC="${_MKDEPCC}" xargs mkdep -a -f ${.TARGET}.tmp ${ZFS_ASM_CFLAGS}
mv ${.TARGET}.tmp ${.TARGET}
.else
: > ${.TARGET}
diff --git a/sys/conf/kern.pre.mk b/sys/conf/kern.pre.mk
index 4328749447a5..1dbd5a9f3285 100644
--- a/sys/conf/kern.pre.mk
+++ b/sys/conf/kern.pre.mk
@@ -128,7 +128,7 @@ CFLAGS+= ${CONF_CFLAGS}
LINTFLAGS= ${LINTOBJKERNFLAGS}
NORMAL_C= ${CC} -c ${CFLAGS} ${WERROR} ${PROF} ${.IMPSRC}
-NORMAL_S= ${CC} -c ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}
+NORMAL_S= ${CC:N${CCACHE_BIN}} -c ${ASM_CFLAGS} ${WERROR} ${.IMPSRC}
PROFILE_C= ${CC} -c ${CFLAGS} ${WERROR} ${.IMPSRC}
NORMAL_C_NOWERROR= ${CC} -c ${CFLAGS} ${PROF} ${.IMPSRC}
diff --git a/tools/build/options/WITH_CCACHE_BUILD b/tools/build/options/WITH_CCACHE_BUILD
new file mode 100644
index 000000000000..4e29c9ab6d52
--- /dev/null
+++ b/tools/build/options/WITH_CCACHE_BUILD
@@ -0,0 +1,42 @@
+.\" $FreeBSD$
+Set to use
+.Xr ccache 1
+for the build.
+No configuration is required except to install the
+.Sy devel/ccache
+package.
+Using with
+.Xr distcc 1
+should set
+.Sy CCACHE_PREFIX=/usr/local/bin/distcc .
+The default cache directory of
+.Pa $HOME/.ccache
+will be used, which can be overridden by setting
+.Sy CCACHE_DIR .
+The
+.Sy CCACHE_COMPILERCHECK
+option defaults to
+.Sy content
+when using the in-tree bootstrap compiler,
+and
+.Sy mtime
+when using an external compiler.
+The
+.Sy CCACHE_CPP2
+option is used for Clang but not GCC.
+ccache works best when combined with the
+.Sy WITH_FAST_DEPEND
+option.
+.Pp
+Sharing a cache between multiple work directories requires using a layout
+similar to
+.Pa /some/prefix/src
+.Pa /some/prefix/obj
+and an environment such as:
+.Bd -literal -offset indent
+CCACHE_BASEDIR='${SRCTOP:H}' MAKEOBJDIRPREFIX='${SRCTOP:H}/obj'
+.Ed
+.Pp
+See
+.Xr ccache 1
+for more configuration options.