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