bsd.dep.mk revision 290629
1# $FreeBSD: head/share/mk/bsd.dep.mk 290629 2015-11-09 23:37:04Z bdrewery $
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
59DEPENDFILES=	${DEPENDFILE}
60.if ${MK_FAST_DEPEND} == "yes" && ${.MAKE.MODE:Unormal:Mmeta*} == ""
61DEPENDFILES+=	${DEPENDFILE}.*
62DEPEND_CFLAGS+=	-MD -MP -MF${DEPENDFILE}.${.TARGET}
63DEPEND_CFLAGS+=	-MT${.TARGET}
64CFLAGS+=	${DEPEND_CFLAGS}
65DEPENDOBJS+=	${OBJS} ${POBJS} ${SOBJS}
66.for __obj in ${DEPENDOBJS:O:u}
67.if ${.MAKEFLAGS:M-V} == ""
68.sinclude "${DEPENDFILE}.${__obj}"
69.endif
70DEPENDFILES_OBJS+=	${DEPENDFILE}.${__obj}
71.endfor
72.endif	# ${MK_FAST_DEPEND} == "yes"
73
74# Keep `tags' here, before SRCS are mangled below for `depend'.
75.if !target(tags) && defined(SRCS) && !defined(NO_TAGS)
76tags: ${SRCS}
77.if ${CTAGS:T} == "gtags"
78	@cd ${.CURDIR} && ${CTAGS} ${GTAGSFLAGS} ${.OBJDIR}
79.if defined(HTML)
80	@cd ${.CURDIR} && htags ${HTAGSFLAGS} -d ${.OBJDIR} ${.OBJDIR}
81.endif
82.else
83	@${CTAGS} ${CTAGSFLAGS} -f /dev/stdout \
84	    ${.ALLSRC:N*.h} | sed "s;${.CURDIR}/;;" > ${.TARGET}
85.endif
86.endif
87
88.if defined(SRCS)
89CLEANFILES?=
90
91.if ${MK_FAST_DEPEND} == "yes" || !exists(${.OBJDIR}/${DEPENDFILE})
92.for _S in ${SRCS:N*.[dhly]}
93${_S:R}.o: ${_S}
94.endfor
95.endif
96
97# Lexical analyzers
98.for _LSRC in ${SRCS:M*.l:N*/*}
99.for _LC in ${_LSRC:R}.c
100${_LC}: ${_LSRC}
101	${LEX} ${LFLAGS} -o${.TARGET} ${.ALLSRC}
102.if ${MK_FAST_DEPEND} == "yes" || !exists(${.OBJDIR}/${DEPENDFILE})
103${_LC:R}.o: ${_LC}
104.endif
105SRCS:=	${SRCS:S/${_LSRC}/${_LC}/}
106CLEANFILES+= ${_LC}
107.endfor
108.endfor
109
110# Yacc grammars
111.for _YSRC in ${SRCS:M*.y:N*/*}
112.for _YC in ${_YSRC:R}.c
113SRCS:=	${SRCS:S/${_YSRC}/${_YC}/}
114CLEANFILES+= ${_YC}
115.if !empty(YFLAGS:M-d) && !empty(SRCS:My.tab.h)
116.ORDER: ${_YC} y.tab.h
117${_YC} y.tab.h: ${_YSRC}
118	${YACC} ${YFLAGS} ${.ALLSRC}
119	cp y.tab.c ${_YC}
120CLEANFILES+= y.tab.c y.tab.h
121.elif !empty(YFLAGS:M-d)
122.for _YH in ${_YC:R}.h
123${_YH}: ${_YC}
124${_YC}: ${_YSRC}
125	${YACC} ${YFLAGS} -o ${_YC} ${.ALLSRC}
126SRCS+=	${_YH}
127CLEANFILES+= ${_YH}
128.endfor
129.else
130${_YC}: ${_YSRC}
131	${YACC} ${YFLAGS} -o ${_YC} ${.ALLSRC}
132.endif
133.if ${MK_FAST_DEPEND} == "yes" || !exists(${.OBJDIR}/${DEPENDFILE})
134${_YC:R}.o: ${_YC}
135.endif
136.endfor
137.endfor
138
139# DTrace probe definitions
140.if ${SRCS:M*.d}
141CFLAGS+=	-I${.OBJDIR}
142.endif
143.for _DSRC in ${SRCS:M*.d:N*/*}
144.for _D in ${_DSRC:R}
145DHDRS+=	${_D}.h
146${_D}.h: ${_DSRC}
147	${DTRACE} ${DTRACEFLAGS} -h -s ${.ALLSRC}
148SRCS:=	${SRCS:S/^${_DSRC}$//}
149OBJS+=	${_D}.o
150CLEANFILES+= ${_D}.h ${_D}.o
151${_D}.o: ${_DSRC} ${OBJS:S/^${_D}.o$//}
152	${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC}
153.if defined(LIB)
154CLEANFILES+= ${_D}.So ${_D}.po
155${_D}.So: ${_DSRC} ${SOBJS:S/^${_D}.So$//}
156	${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC}
157${_D}.po: ${_DSRC} ${POBJS:S/^${_D}.po$//}
158	${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC}
159.endif
160.endfor
161.endfor
162beforedepend: ${DHDRS}
163beforebuild: ${DHDRS}
164.endif
165
166.if ${MK_META_MODE} == "yes"
167.include <meta.autodep.mk>
168# this depend: bypasses that below
169# the dependency helps when bootstrapping
170depend: beforedepend ${DPSRCS} ${SRCS} afterdepend
171beforedepend:
172afterdepend: beforedepend
173.endif
174
175.if !target(depend)
176.if defined(SRCS)
177depend: beforedepend ${DEPENDFILE} afterdepend
178
179# Tell bmake not to look for generated files via .PATH
180.NOPATH: ${DEPENDFILE} ${DEPENDFILES_OBJS}
181
182# Different types of sources are compiled with slightly different flags.
183# Split up the sources, and filter out headers and non-applicable flags.
184MKDEP_CFLAGS=	${CFLAGS:M-nostdinc*} ${CFLAGS:M-[BIDU]*} ${CFLAGS:M-std=*} \
185		${CFLAGS:M-ansi}
186MKDEP_CXXFLAGS=	${CXXFLAGS:M-nostdinc*} ${CXXFLAGS:M-[BIDU]*} \
187		${CXXFLAGS:M-std=*} ${CXXFLAGS:M-ansi} ${CXXFLAGS:M-stdlib=*}
188
189DPSRCS+= ${SRCS}
190${DEPENDFILE}: ${DPSRCS}
191.if ${MK_FAST_DEPEND} == "no"
192	rm -f ${DEPENDFILE}
193.if !empty(DPSRCS:M*.[cS])
194	${MKDEPCMD} -f ${DEPENDFILE} -a ${MKDEP} \
195	    ${MKDEP_CFLAGS} ${.ALLSRC:M*.[cS]}
196.endif
197.if !empty(DPSRCS:M*.cc) || !empty(DPSRCS:M*.C) || !empty(DPSRCS:M*.cpp) || \
198    !empty(DPSRCS:M*.cxx)
199	${MKDEPCMD} -f ${DEPENDFILE} -a ${MKDEP} \
200	    ${MKDEP_CXXFLAGS} \
201	    ${.ALLSRC:M*.cc} ${.ALLSRC:M*.C} ${.ALLSRC:M*.cpp} ${.ALLSRC:M*.cxx}
202.else
203.endif
204.else
205	: > ${.TARGET}
206.endif	# ${MK_FAST_DEPEND} == "no"
207.if target(_EXTRADEPEND)
208_EXTRADEPEND: .USE
209${DEPENDFILE}: _EXTRADEPEND
210.endif
211
212.ORDER: ${DEPENDFILE} afterdepend
213.else
214depend: beforedepend afterdepend
215.endif
216.if !target(beforedepend)
217beforedepend:
218.else
219.ORDER: beforedepend ${DEPENDFILE}
220.ORDER: beforedepend afterdepend
221.endif
222.if !target(afterdepend)
223afterdepend:
224.endif
225.endif
226
227.if !target(cleandepend)
228cleandepend:
229.if defined(SRCS)
230.if ${CTAGS:T} == "gtags"
231	rm -f ${DEPENDFILES} GPATH GRTAGS GSYMS GTAGS
232.if defined(HTML)
233	rm -rf HTML
234.endif
235.else
236	rm -f ${DEPENDFILES} tags
237.endif
238.endif
239.endif
240
241.if !target(checkdpadd) && (defined(DPADD) || defined(LDADD))
242_LDADD_FROM_DPADD=	${DPADD:R:T:C;^lib(.*)$;-l\1;g}
243# Ignore -Wl,--start-group/-Wl,--end-group as it might be required in the
244# LDADD list due to unresolved symbols
245_LDADD_CANONICALIZED=	${LDADD:N:R:T:C;^lib(.*)$;-l\1;g:N-Wl,--[es]*-group}
246checkdpadd:
247.if ${_LDADD_FROM_DPADD} != ${_LDADD_CANONICALIZED}
248	@echo ${.CURDIR}
249	@echo "DPADD -> ${_LDADD_FROM_DPADD}"
250	@echo "LDADD -> ${_LDADD_CANONICALIZED}"
251.endif
252.endif
253