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