xref: /freebsd/share/mk/meta.sys.mk (revision e2afbc45258f2fa4bdcf126e959ac660e76fc802)
1# $Id: meta.sys.mk,v 1.57 2025/08/09 22:42:24 sjg Exp $
2#
3#	@(#) Copyright (c) 2010-2023, Simon J. Gerraty
4#
5#	SPDX-License-Identifier: BSD-2-Clause
6#
7#	Please send copies of changes and bug-fixes to:
8#	sjg@crufty.net
9#
10
11# include this if you want to enable meta mode
12# for maximum benefit, requires filemon(4) driver.
13
14# absolute path to what we are reading.
15_PARSEDIR ?= ${.PARSEDIR:tA}
16
17.-include <local.meta.sys.env.mk>
18
19.if !defined(SYS_MK_DIR)
20SYS_MK_DIR := ${_PARSEDIR}
21.endif
22
23.if !target(.ERROR)
24
25META_MODE += meta
26.if empty(.MAKEFLAGS:M-s)
27META_MODE += verbose
28.endif
29.if ${MAKE_VERSION:U0} > 20130323 && empty(.MAKE.PATH_FILEMON)
30# we do not support filemon
31META_MODE += nofilemon
32MKDEP_MK ?= auto.dep.mk
33.endif
34
35# META_MODE_XTRAS makes it easier to add things like 'env'
36# from the command line when debugging
37# :U avoids problems from := below
38META_MODE += ${META_MODE_XTRAS:U}
39
40.MAKE.MODE ?= ${META_MODE}
41
42_filemon := ${.MAKE.PATH_FILEMON:U/dev/filemon}
43
44.if empty(UPDATE_DEPENDFILE)
45_make_mode := ${.MAKE.MODE} ${META_MODE}
46.if ${_make_mode:M*read*} != "" || ${_make_mode:M*nofilemon*} != ""
47# tell everyone we are not updating Makefile.depend*
48UPDATE_DEPENDFILE = NO
49.export UPDATE_DEPENDFILE
50.endif
51.if ${_filemon:T:Mfilemon} == "filemon"
52.if ${UPDATE_DEPENDFILE:Uyes:tl} == "no" && !exists(${_filemon})
53# we should not get upset
54META_MODE += nofilemon
55.export META_MODE
56.endif
57.endif
58.endif
59
60.if !defined(NO_SILENT)
61.if ${MAKE_VERSION} > 20110818
62# only be silent when we have a .meta file
63META_MODE += silent=yes
64.else
65.SILENT:
66.endif
67.endif
68
69.if ${MK_DIRDEPS_BUILD:Uno} == "yes"
70
71.if !defined(META2DEPS)
72.if defined(PYTHON) && exists(${PYTHON})
73# we prefer the python version of this - it is much faster
74META2DEPS ?= ${.PARSEDIR}/meta2deps.py
75.else
76META2DEPS ?= ${.PARSEDIR}/meta2deps.sh
77.endif
78META2DEPS := ${META2DEPS}
79.export META2DEPS
80.endif
81
82MAKE_PRINT_VAR_ON_ERROR += \
83	.ERROR_TARGET \
84	.ERROR_EXIT \
85	.ERROR_META_FILE \
86	.MAKE.LEVEL \
87	MAKEFILE \
88	.MAKE.MODE
89
90MK_META_ERROR_TARGET = yes
91.endif
92
93.if ${MK_META_ERROR_TARGET:Uno} == "yes"
94
95.if !defined(SB) && defined(SRCTOP)
96SB = ${SRCTOP:H}
97.endif
98ERROR_LOGDIR ?= ${SB}/error
99meta_error_log = ${ERROR_LOGDIR}/meta-${.MAKE.PID}.log
100
101.if ${.MAKE.LEVEL} == 0 && !empty(NEWLOG_SH) && exists(${ERROR_LOGDIR})
102.BEGIN:	_rotateErrorLog
103_rotateErrorLog: .NOMETA .NOTMAIN
104	@${NEWLOG_SH} -d -S -n ${ERROR_LOG_GENS:U4} ${ERROR_LOGDIR}
105.endif
106
107.ERROR: _metaError
108# We are interested here in the target(s) that caused the build to fail.
109# We want to ignore targets that were "aborted" due to failure
110# elsewhere per the message below or a sub-make may just exit 6.
111_metaError: .NOMETA .NOTMAIN
112	-@[ ${.ERROR_EXIT:U0} = 6 ] && exit 0; \
113	[ "${.ERROR_META_FILE}" ] && { \
114	grep -q 'failure has been detected in another branch' ${.ERROR_META_FILE} && exit 0; \
115	mkdir -p ${meta_error_log:H}; \
116	cp ${.ERROR_META_FILE} ${meta_error_log}; \
117	echo "ERROR: log ${meta_error_log}" >&2; }; :
118
119.endif
120.endif
121
122# Are we, after all, in meta mode?
123.if ${.MAKE.MODE:Uno:Mmeta*} != ""
124MKDEP_MK ?= meta.autodep.mk
125
126# we can afford to use cookies to prevent some targets
127# re-running needlessly
128META_COOKIE_TOUCH?= touch ${COOKIE.${.TARGET}:U${.OBJDIR}/${.TARGET:T}}
129META_NOPHONY=
130META_NOECHO= :
131
132# some targets involve old pre-built targets
133# ignore mtime of shell
134# and mtime of makefiles does not matter in meta mode
135.MAKE.META.IGNORE_PATHS += \
136	${MAKEFILE} \
137	${MAKE_SHELL} \
138	${SHELL} \
139	${SYS_MK_DIR} \
140
141
142.if ${UPDATE_DEPENDFILE:Uyes:tl} != "no"
143.if ${.MAKEFLAGS:Uno:M-k} != ""
144# make this more obvious
145.warning Setting UPDATE_DEPENDFILE=NO due to -k
146UPDATE_DEPENDFILE= NO
147.export UPDATE_DEPENDFILE
148.elif ${_filemon:T} == "filemon" && !exists(${_filemon})
149.error ${.newline}ERROR: The filemon module (${_filemon}) is not loaded.
150.endif
151.endif
152
153.else				# in meta mode?
154
155META_COOKIE_TOUCH=
156# some targets need to be .PHONY in non-meta mode
157META_NOPHONY= .PHONY
158META_NOECHO= echo
159
160.endif				# in meta mode?
161
162.-include <local.meta.sys.mk>
163