xref: /freebsd/share/mk/bsd.dep.mk (revision 49b49cda41feabe3439f7318e8bf40e3896c7bf4)
1# $FreeBSD$
2#
3# The include file <bsd.dep.mk> handles Makefile dependencies.
4#
5#
6# +++ variables +++
7#
8# CTAGS		A tags file generation program [gtags]
9#
10# CTAGSFLAGS	Options for ctags(1) [not set]
11#
12# DEPENDFILE	dependencies file [.depend]
13#
14# GTAGSFLAGS	Options for gtags(1) [-o]
15#
16# HTAGSFLAGS	Options for htags(1) [not set]
17#
18# MKDEP		Options for ${MKDEPCMD} [not set]
19#
20# MKDEPCMD	Makefile dependency list program [mkdep]
21#
22# SRCS          List of source files (c, c++, assembler)
23#
24# DPSRCS	List of source files which are needed for generating
25#		dependencies, ${SRCS} are always part of it.
26#
27# +++ targets +++
28#
29#	cleandepend:
30#		Remove depend and tags file
31#
32#	depend:
33#		Make the dependencies for the source files, and store
34#		them in the file ${DEPENDFILE}.
35#
36#	tags:
37#		In "ctags" mode, create a tags file for the source files.
38#		In "gtags" mode, create a (GLOBAL) gtags file for the
39#		source files.  If HTML is defined, htags(1) is also run
40#		after gtags(1).
41
42.if !target(__<bsd.init.mk>__)
43.error bsd.dep.mk cannot be included directly.
44.endif
45
46CTAGS?=		gtags
47CTAGSFLAGS?=
48GTAGSFLAGS?=	-o
49HTAGSFLAGS?=
50
51_MKDEPCC:=	${CC:N${CCACHE_BIN}}
52# XXX: DEPFLAGS can come out once Makefile.inc1 properly passes down
53# CXXFLAGS.
54.if !empty(DEPFLAGS)
55_MKDEPCC+=	${DEPFLAGS}
56.endif
57MKDEPCMD?=	CC='${_MKDEPCC}' mkdep
58DEPENDFILE?=	.depend
59.MAKE.DEPENDFILE= ${DEPENDFILE}
60DEPENDFILES=	${DEPENDFILE}
61
62# Keep `tags' here, before SRCS are mangled below for `depend'.
63.if !target(tags) && defined(SRCS) && !defined(NO_TAGS)
64tags: ${SRCS}
65.if ${CTAGS:T} == "gtags"
66	@cd ${.CURDIR} && ${CTAGS} ${GTAGSFLAGS} ${.OBJDIR}
67.if defined(HTML)
68	@cd ${.CURDIR} && htags ${HTAGSFLAGS} -d ${.OBJDIR} ${.OBJDIR}
69.endif
70.else
71	@${CTAGS} ${CTAGSFLAGS} -f /dev/stdout \
72	    ${.ALLSRC:N*.h} | sed "s;${.CURDIR}/;;" > ${.TARGET}
73.endif
74.endif
75
76.if defined(SRCS)
77CLEANFILES?=
78
79.if ${MK_FAST_DEPEND} == "yes" || !exists(${.OBJDIR}/${DEPENDFILE})
80.for _S in ${SRCS:N*.[dhly]}
81${_S:R}.o: ${_S}
82.endfor
83.endif
84
85# Lexical analyzers
86.for _LSRC in ${SRCS:M*.l:N*/*}
87.for _LC in ${_LSRC:R}.c
88${_LC}: ${_LSRC}
89	${LEX} ${LFLAGS} -o${.TARGET} ${.ALLSRC}
90.if ${MK_FAST_DEPEND} == "yes" || !exists(${.OBJDIR}/${DEPENDFILE})
91${_LC:R}.o: ${_LC}
92.endif
93SRCS:=	${SRCS:S/${_LSRC}/${_LC}/}
94CLEANFILES+= ${_LC}
95.endfor
96.endfor
97
98# Yacc grammars
99.for _YSRC in ${SRCS:M*.y:N*/*}
100.for _YC in ${_YSRC:R}.c
101SRCS:=	${SRCS:S/${_YSRC}/${_YC}/}
102CLEANFILES+= ${_YC}
103.if !empty(YFLAGS:M-d) && !empty(SRCS:My.tab.h)
104.ORDER: ${_YC} y.tab.h
105${_YC} y.tab.h: ${_YSRC}
106	${YACC} ${YFLAGS} ${.ALLSRC}
107	cp y.tab.c ${_YC}
108CLEANFILES+= y.tab.c y.tab.h
109.elif !empty(YFLAGS:M-d)
110.for _YH in ${_YC:R}.h
111${_YH}: ${_YC}
112${_YC}: ${_YSRC}
113	${YACC} ${YFLAGS} -o ${_YC} ${.ALLSRC}
114SRCS+=	${_YH}
115CLEANFILES+= ${_YH}
116.endfor
117.else
118${_YC}: ${_YSRC}
119	${YACC} ${YFLAGS} -o ${_YC} ${.ALLSRC}
120.endif
121.if ${MK_FAST_DEPEND} == "yes" || !exists(${.OBJDIR}/${DEPENDFILE})
122${_YC:R}.o: ${_YC}
123.endif
124.endfor
125.endfor
126
127# DTrace probe definitions
128.if ${SRCS:M*.d}
129CFLAGS+=	-I${.OBJDIR}
130.endif
131.for _DSRC in ${SRCS:M*.d:N*/*}
132.for _D in ${_DSRC:R}
133SRCS+=	${_D}.h
134${_D}.h: ${_DSRC}
135	${DTRACE} ${DTRACEFLAGS} -h -s ${.ALLSRC}
136SRCS:=	${SRCS:S/^${_DSRC}$//}
137OBJS+=	${_D}.o
138CLEANFILES+= ${_D}.h ${_D}.o
139${_D}.o: ${_DSRC} ${OBJS:S/^${_D}.o$//}
140	@rm -f ${.TARGET}
141	${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h}
142.if defined(LIB)
143CLEANFILES+= ${_D}.So ${_D}.po
144${_D}.So: ${_DSRC} ${SOBJS:S/^${_D}.So$//}
145	@rm -f ${.TARGET}
146	${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h}
147${_D}.po: ${_DSRC} ${POBJS:S/^${_D}.po$//}
148	@rm -f ${.TARGET}
149	${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h}
150.endif
151.endfor
152.endfor
153
154
155.if ${MK_FAST_DEPEND} == "yes" && \
156    (${.MAKE.MODE:Mmeta} == "" || ${.MAKE.MODE:Mnofilemon} != "")
157DEPENDFILES+=	${DEPENDFILE}.*
158DEPEND_MP?=	-MP
159# Handle OBJS=../somefile.o hacks.  Just replace '/' rather than use :T to
160# avoid collisions.
161DEPEND_FILTER=	C,/,_,g
162DEPEND_CFLAGS+=	-MD ${DEPEND_MP} -MF${DEPENDFILE}.${.TARGET:${DEPEND_FILTER}}
163DEPEND_CFLAGS+=	-MT${.TARGET}
164.if defined(.PARSEDIR)
165# Only add in DEPEND_CFLAGS for CFLAGS on files we expect from DEPENDOBJS
166# as those are the only ones we will include.
167DEPEND_CFLAGS_CONDITION= !empty(DEPENDOBJS:M${.TARGET:${DEPEND_FILTER}})
168CFLAGS+=	${${DEPEND_CFLAGS_CONDITION}:?${DEPEND_CFLAGS}:}
169.else
170CFLAGS+=	${DEPEND_CFLAGS}
171.endif
172DEPENDSRCS=	${SRCS:M*.[cSC]} ${SRCS:M*.cxx} ${SRCS:M*.cpp} ${SRCS:M*.cc}
173.if !empty(DEPENDSRCS)
174DEPENDOBJS+=	${DEPENDSRCS:R:S,$,.o,}
175.endif
176DEPENDFILES_OBJS=	${DEPENDOBJS:O:u:${DEPEND_FILTER}:C/^/${DEPENDFILE}./}
177.if ${.MAKEFLAGS:M-V} == ""
178.for __depend_obj in ${DEPENDFILES_OBJS}
179.sinclude "${__depend_obj}"
180.endfor
181.endif
182.endif	# ${MK_FAST_DEPEND} == "yes"
183.endif	# defined(SRCS)
184
185.if ${MK_DIRDEPS_BUILD} == "yes"
186.include <meta.autodep.mk>
187# this depend: bypasses that below
188# the dependency helps when bootstrapping
189depend: beforedepend ${DPSRCS} ${SRCS} afterdepend
190beforedepend:
191afterdepend: beforedepend
192.endif
193
194.if !target(depend)
195.if defined(SRCS)
196depend: beforedepend ${DEPENDFILE} afterdepend
197
198# Tell bmake not to look for generated files via .PATH
199.NOPATH: ${DEPENDFILE} ${DEPENDFILES_OBJS}
200
201.if ${MK_FAST_DEPEND} == "no"
202# Capture -include from CFLAGS.
203# This could be simpler with bmake :tW but needs to support fmake for MFC.
204_CFLAGS_INCLUDES= ${CFLAGS:Q:S/\\ /,/g:C/-include,/-include%/g:C/,/ /g:M-include*:C/%/ /g}
205_CXXFLAGS_INCLUDES= ${CXXFLAGS:Q:S/\\ /,/g:C/-include,/-include%/g:C/,/ /g:M-include*:C/%/ /g}
206# XXX: Temporary hack to workaround .depend files not tracking -include
207.if !empty(_CFLAGS_INCLUDES)
208${OBJS} ${POBJS} ${SOBJS}: ${_CFLAGS_INCLUDES:M*.h}
209.endif
210.if !empty(_CXXFLAGS_INCLUDES)
211${OBJS} ${POBJS} ${SOBJS}: ${_CXXFLAGS_INCLUDES:M*.h}
212.endif
213
214# Different types of sources are compiled with slightly different flags.
215# Split up the sources, and filter out headers and non-applicable flags.
216MKDEP_CFLAGS=	${CFLAGS:M-nostdinc*} ${CFLAGS:M-[BIDU]*} ${CFLAGS:M-std=*} \
217		${CFLAGS:M-ansi} ${_CFLAGS_INCLUDES}
218MKDEP_CXXFLAGS=	${CXXFLAGS:M-nostdinc*} ${CXXFLAGS:M-[BIDU]*} \
219		${CXXFLAGS:M-std=*} ${CXXFLAGS:M-ansi} ${CXXFLAGS:M-stdlib=*} \
220		${_CXXFLAGS_INCLUDES}
221.endif	# ${MK_FAST_DEPEND} == "no"
222
223DPSRCS+= ${SRCS}
224${DEPENDFILE}: ${DPSRCS}
225.if ${MK_FAST_DEPEND} == "no"
226	rm -f ${DEPENDFILE}
227.if !empty(DPSRCS:M*.[cS])
228	${MKDEPCMD} -f ${DEPENDFILE} -a ${MKDEP} \
229	    ${MKDEP_CFLAGS} ${.ALLSRC:M*.[cS]}
230.endif
231.if !empty(DPSRCS:M*.cc) || !empty(DPSRCS:M*.C) || !empty(DPSRCS:M*.cpp) || \
232    !empty(DPSRCS:M*.cxx)
233	${MKDEPCMD} -f ${DEPENDFILE} -a ${MKDEP} \
234	    ${MKDEP_CXXFLAGS} \
235	    ${.ALLSRC:M*.cc} ${.ALLSRC:M*.C} ${.ALLSRC:M*.cpp} ${.ALLSRC:M*.cxx}
236.else
237.endif
238.else
239	: > ${.TARGET}
240.endif	# ${MK_FAST_DEPEND} == "no"
241.if target(_EXTRADEPEND)
242_EXTRADEPEND: .USE
243${DEPENDFILE}: _EXTRADEPEND
244.endif
245
246.ORDER: ${DEPENDFILE} afterdepend
247.else
248depend: beforedepend afterdepend
249.endif
250.if !target(beforedepend)
251beforedepend:
252.else
253.ORDER: beforedepend ${DEPENDFILE}
254.ORDER: beforedepend afterdepend
255.endif
256.if !target(afterdepend)
257afterdepend:
258.endif
259.endif
260
261.if !target(cleandepend)
262cleandepend:
263.if defined(SRCS)
264.if ${CTAGS:T} == "gtags"
265	rm -f ${DEPENDFILES} GPATH GRTAGS GSYMS GTAGS
266.if defined(HTML)
267	rm -rf HTML
268.endif
269.else
270	rm -f ${DEPENDFILES} tags
271.endif
272.endif
273.endif
274
275.if !target(checkdpadd) && (defined(DPADD) || defined(LDADD))
276_LDADD_FROM_DPADD=	${DPADD:R:T:C;^lib(.*)$;-l\1;g}
277# Ignore -Wl,--start-group/-Wl,--end-group as it might be required in the
278# LDADD list due to unresolved symbols
279_LDADD_CANONICALIZED=	${LDADD:N:R:T:C;^lib(.*)$;-l\1;g:N-Wl,--[es]*-group}
280checkdpadd:
281.if ${_LDADD_FROM_DPADD} != ${_LDADD_CANONICALIZED}
282	@echo ${.CURDIR}
283	@echo "DPADD -> ${_LDADD_FROM_DPADD}"
284	@echo "LDADD -> ${_LDADD_CANONICALIZED}"
285.endif
286.endif
287