xref: /freebsd/contrib/bmake/mk/autodep.mk (revision ec0ea6efa1ad229d75c394c1a9b9cac33af2b1d3)
1#
2# RCSid:
3#	$Id: autodep.mk,v 1.40 2021/12/08 05:56:50 sjg Exp $
4#
5#	@(#) Copyright (c) 1999-2010, Simon J. Gerraty
6#
7#	This file is provided in the hope that it will
8#	be of use.  There is absolutely NO WARRANTY.
9#	Permission to copy, redistribute or otherwise
10#	use this file is hereby granted provided that
11#	the above copyright notice and this notice are
12#	left intact.
13#
14#	Please send copies of changes and bug-fixes to:
15#	sjg@crufty.net
16
17# This module provides automagic dependency generation along the
18# lines suggested in the GNU make.info
19# The depend target is mainly for backwards compatibility,
20# dependencies are normally updated as part of compilation.
21
22.if !target(__${.PARSEFILE}__)
23__${.PARSEFILE}__: .NOTMAIN
24
25DEPENDFILE?= .depend
26.for d in ${DEPENDFILE:N.depend}
27# bmake only groks .depend
28.if ${MAKE_VERSION} < 20160218
29.-include <$d>
30.else
31.dinclude <$d>
32.endif
33.endfor
34
35# it does nothing if SRCS is not defined or is empty
36.if defined(SRCS) && !empty(SRCS)
37DEPSRCS?=${SRCS}
38__depsrcs=${DEPSRCS:M*.c}
39__depsrcs+=${DEPSRCS:M*.y}
40__depsrcs+=${DEPSRCS:M*.l}
41__depsrcs+=${DEPSRCS:M*.s}
42__depsrcs+=${DEPSRCS:M*.S}
43__depsrcs+=${DEPSRCS:M*.cc}
44__depsrcs+=${DEPSRCS:M*.cpp}
45__depsrcs+=${DEPSRCS:M*.C}
46__depsrcs+=${DEPSRCS:M*.cxx}
47__depsrcs+=${DEPSRCS:M*.pc}
48
49.for s in ${__depsrcs}
50${s:T:R}.d:	$s
51.endfor
52
53__depsrcs:=${__depsrcs:T:R:S/$/.d/g}
54# we also need to handle makefiles where the .d's from __depsrcs
55# don't  match those from OBJS
56# we avoid using := here, since the modifier applied to OBJS
57# can cause trouble if there are any undefined vars in OBJS.
58__dependsrcsx?= ${__depsrcs} ${OBJS:S/.o/.d/}
59__dependsrcs= ${__dependsrcsx:O:u}
60
61# clean up any .c files we may have generated
62#__gensrcs:= ${DEPSRCS:M*.y} ${DEPSRCS:M*.l}
63#CLEANFILES+= ${__gensrcs:T:R:S/$/.c/g}
64
65# set this to -MMD to ignore /usr/include
66# actually it ignores <> so may not be a great idea
67CFLAGS_MD?=-MD
68# -MF etc not available on all gcc versions.
69# we "fix" the .o later
70.if ${COMPILER_TYPE:Ugcc} == "gcc" && ${COMPILER_VERSION:U0} < 30000
71CFLAGS_MF=
72.endif
73CFLAGS_MF?=-MF ${.TARGET:T:R}.d -MT ${.TARGET:T:R}.o
74CFLAGS+= ${CFLAGS_MD} ${CFLAGS_MF}
75RM?= rm
76MAKE_SHELL?= sh
77
78# watch out for people who don't use CPPFLAGS
79CPPFLAGS_MD=${CFLAGS:M-[IUD]*} ${CPPFLAGS}
80CXXFLAGS_MD=${CXXFLAGS:M-[IUD]*} ${CPPFLAGS}
81
82# just in case these need to be different
83CC_MD?=${CC}
84CXX_MD?=${CXX}
85
86# should have been set by sys.mk
87CXX_SUFFIXES?= .cc .cpp .cxx .C
88
89# so we can do an explicit make depend, but not otherwise
90.if make(depend)
91.SUFFIXES:	.d
92
93.if empty(CFLAGS_MD)
94.y.d:
95	@echo updating dependencies for $<
96	@${YACC} ${YFLAGS} $<
97	@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} y.tab.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f y.tab.c $@; false; }
98	@${RM} -f y.tab.c
99
100.l.d:
101	@echo updating dependencies for $<
102	${LEX} ${LFLAGS} $<
103	@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} lex.yy.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f lex.yy.c $@; false; }
104	@${RM} -f lex.yy.c
105
106.c.d:
107	@echo updating dependencies for $<
108	@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
109
110.s.d .S.d:
111	@echo updating dependencies for $<
112	@${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} ${AINC} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
113
114${CXX_SUFFIXES:%=%.d}:
115	@echo updating dependencies for $<
116	@${MAKE_SHELL} -ec "${CXX_MD} -M ${CXXFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; }
117.else
118.y.d:
119	${YACC} ${YFLAGS} $<
120	${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} y.tab.c > $@ || { ${RM} -f y.tab.c $@; false; }
121	${RM} -f y.tab.c
122
123.l.d:
124	${LEX} ${LFLAGS} $<
125	${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} lex.yy.c > $@ || { ${RM} -f lex.yy.c $@; false; }
126	${RM} -f lex.yy.c
127
128.c.d:
129	${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} $< > $@ || { ${RM} -f $@; false; }
130
131.s.d .S.d:
132	${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} ${AINC} $< > $@ || { ${RM} -f $@; false; }
133
134${CXX_SUFFIXES:%=%.d}:
135	${CXX_MD} ${CFLAGS_MD:S/D//} ${CXXFLAGS_MD} $< > $@ || { ${RM} -f $@; false; }
136.endif
137
138.if !target(depend)
139depend: beforedepend ${DEPENDFILE} afterdepend _SUBDIRUSE
140
141${DEPENDFILE}:	${DEPSRCS} ${__dependsrcs}
142.NOPATH:	${__dependsrcs}
143.OPTIONAL:	${__dependsrcs}
144.endif
145.endif				# make(depend)
146
147.if empty(CFLAGS_MD)
148# make sure the .d's are generated/updated
149${PROG} ${_LIBS}:	${DEPENDFILE}
150.endif
151
152.ORDER:	beforedepend ${DEPENDFILE} afterdepend
153
154.if ${.OBJDIR} != ${.CURDIR}
155__depfiles= *.d
156.else
157__depfiles= ${__dependsrcs}
158.endif
159
160DEPCLEANFILES= ${DEPENDFILE} ${__depfiles} y.tab.d *.tmp.d
161
162cleandir: cleanautodepend
163cleanautodepend:
164	${RM} -f ${DEPCLEANFILES}
165
166CLEANFILES+= ${DEPCLEANFILES}
167
168.if defined(__dependsrcs) && !empty(__dependsrcs)
169.if make(depend) || !(make(clean*) || make(destroy*) || make(obj) || make(*install) || make(install-*))
170# this ensures we do the right thing if only building a shared or
171# profiled lib
172OBJ_EXTENSIONS?=.o .po .so .So
173MDLIB_SED= -e '/:/s,^\([^\.:]*\)\.[psS]*o,${OBJ_EXTENSIONS:S,^,\1,},'
174.ifdef NOMD_SED
175.ifdef LIB
176MD_SED=sed ${MDLIB_SED}
177.else
178MD_SED=cat
179.endif
180.else
181# arrange to put some variable names into ${DEPENDFILE}
182.ifdef LIB
183MD_SED=sed ${MDLIB_SED}
184.else
185MD_SED=sed
186.endif
187SUBST_DEPVARS+= SB TOP BACKING SRC SRCDIR BASE BASEDIR
188.for v in ${SUBST_DEPVARS}
189.if defined(${v}) && !empty(${v})
190MD_SED+= -e 's,${$v},$${$v},'
191.endif
192.endfor
193.endif
194.if (${MD_SED} == "sed")
195MD_SED=cat
196.endif
197
198# this will be done whenever make finishes successfully
199.if ${MAKE_VERSION:U0:[1]:C/.*-//} < 20050530
200.END:
201.else
202.END:	${DEPENDFILE}
203# we do not want to trigger building .d's just use them if they exist
204${DEPENDFILE}:	${__dependsrcs:@d@${exists($d):?$d:}@}
205.endif
206	-@${MD_SED} ${__depfiles} > ${DEPENDFILE}.new 2> /dev/null && \
207	test -s ${DEPENDFILE}.new && mv ${DEPENDFILE}.new ${DEPENDFILE}; \
208	${RM} -f ${DEPENDFILE}.new
209.endif
210.endif
211.else
212depend: beforedepend afterdepend _SUBDIRUSE
213.endif
214
215.if !target(beforedepend)
216beforedepend:
217.endif
218.if !target(afterdepend)
219afterdepend:
220.endif
221
222.endif
223