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