1# 2# The include file <bsd.dep.mk> handles Makefile dependencies. 3# 4# 5# +++ variables +++ 6# 7# CLEANDEPENDDIRS Additional directories to remove for the cleandepend 8# target. 9# 10# CLEANDEPENDFILES Additional files to remove for the cleandepend target. 11# 12# CTAGS A tags file generation program [gtags] 13# 14# CTAGSFLAGS Options for ctags(1) [not set] 15# 16# DEPENDFILE dependencies file [.depend] 17# 18# GTAGSFLAGS Options for gtags(1) [-o] 19# 20# HTAGSFLAGS Options for htags(1) [not set] 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 ${CLEANDEPENDFILES}; remove ${CLEANDEPENDDIRS} and all 31# contents. 32# 33# depend: 34# Make the dependencies for the source files, and store 35# them in the file ${DEPENDFILE}. 36# 37# tags: 38# In "ctags" mode, create a tags file for the source files. 39# In "gtags" mode, create a (GLOBAL) gtags file for the 40# source files. If HTML is defined, htags(1) is also run 41# after gtags(1). 42 43.if !target(__<bsd.init.mk>__) 44.error bsd.dep.mk cannot be included directly. 45.endif 46 47CTAGS?= gtags 48CTAGSFLAGS?= 49GTAGSFLAGS?= -o 50HTAGSFLAGS?= 51 52.if ${MK_DIRDEPS_BUILD} == "no" 53.MAKE.DEPENDFILE= ${DEPENDFILE} 54.endif 55CLEANDEPENDFILES+= ${DEPENDFILE} ${DEPENDFILE}.* 56.if ${MK_META_MODE} == "yes" 57CLEANDEPENDFILES+= *.meta 58.endif 59 60# Keep `tags' here, before SRCS are mangled below for `depend'. 61.if !target(tags) && defined(SRCS) && !defined(NO_TAGS) 62tags: ${SRCS} 63.if ${CTAGS:T} == "gtags" 64 @cd ${.CURDIR} && ${CTAGS} ${GTAGSFLAGS} ${.OBJDIR} 65.if defined(HTML) 66 @cd ${.CURDIR} && htags ${HTAGSFLAGS} -d ${.OBJDIR} ${.OBJDIR} 67.endif 68.else 69 @${CTAGS} ${CTAGSFLAGS} -f /dev/stdout \ 70 ${.ALLSRC:N*.h} | sed "s;${.CURDIR}/;;" > ${.TARGET} 71.endif 72.endif 73 74.if !empty(.MAKE.MODE:Mmeta) && empty(.MAKE.MODE:Mnofilemon) 75_meta_filemon= 1 76.endif 77# By default META_MODE is disabled in bmake if there is no OBJDIR 78# unless .MAKE.MODE contains "curdirOk=[^0nNfF]" 79.if defined(_meta_filemon) && ${.OBJDIR} == ${.CURDIR} && \ 80 (empty(.MAKE.MODE:tl:Mcurdirok=*) || \ 81 !empty(.MAKE.MODE:tl:Mcurdirok=[0NnFf]*)) 82.undef _meta_filemon 83.endif 84 85# Skip reading .depend when not needed to speed up tree-walks and simple 86# lookups. See _SKIP_BUILD logic in bsd.init.mk for more details. 87# Also skip generating or including .depend.* files if in meta+filemon mode 88# since it will track dependencies itself. OBJS_DEPEND_GUESS is still used 89# for _meta_filemon but not for _SKIP_DEPEND. 90.if !defined(NO_SKIP_DEPEND) && defined(_SKIP_BUILD) 91_SKIP_DEPEND= 1 92.endif 93.if ${MK_DIRDEPS_BUILD} == "no" 94.if defined(_SKIP_DEPEND) || defined(_meta_filemon) 95.MAKE.DEPENDFILE= /dev/null 96.endif 97.endif 98 99.if defined(SRCS) 100CLEANFILES?= 101 102.for _S in ${SRCS:N*.[dhly]} 103OBJS_DEPEND_GUESS.${_S:${OBJS_SRCS_FILTER:ts:}}.o+= ${_S} 104.endfor 105 106# Lexical analyzers 107.for _LSRC in ${SRCS:M*.l:N*/*} 108.for _LC in ${_LSRC:R}.c 109${_LC}: ${_LSRC} 110 ${LEX} ${LFLAGS} ${LFLAGS.${_LSRC}} -o${.TARGET} ${.ALLSRC} 111OBJS_DEPEND_GUESS.${_LC:R}.o+= ${_LC} 112SRCS:= ${SRCS:S/${_LSRC}/${_LC}/} 113CLEANFILES+= ${_LC} 114.endfor 115.endfor 116 117# Yacc grammars 118.for _YSRC in ${SRCS:M*.y:N*/*} 119.for _YC in ${_YSRC:R}.c 120SRCS:= ${SRCS:S/${_YSRC}/${_YC}/} 121CLEANFILES+= ${_YC} 122.if !empty(YFLAGS:M-d) && !empty(SRCS:My.tab.h) 123# Multi-output targets both expect a .meta file and will fight over it. Only 124# allow it on the .c file instead. 125y.tab.h: ${_YC} .NOMETA 126# Force rebuild the .c file if any of its other outputs are missing. 127.if !exists(y.tab.h) 128${_YC}: .PHONY .META 129.endif 130${_YC}: ${_YSRC} 131 ${YACC} ${YFLAGS} ${YFLAGS.${_YSRC}} ${.ALLSRC} 132 cp y.tab.c ${_YC} 133CLEANFILES+= y.tab.c y.tab.h 134.elif !empty(YFLAGS:M-d) 135.for _YH in ${_YC:R}.h 136# Multi-output targets both expect a .meta file and will fight over it. Only 137# allow it on the .c file instead. 138${_YH}: ${_YC} .NOMETA 139# Force rebuild the .c file if any of its other outputs are missing. 140.if !exists(${_YH}) 141${_YC}: .PHONY .META 142.endif 143${_YC}: ${_YSRC} 144 ${YACC} ${YFLAGS} ${YFLAGS.${_YSRC}} -o ${_YC} ${.ALLSRC} 145SRCS+= ${_YH} 146CLEANFILES+= ${_YH} 147.endfor 148.else 149${_YC}: ${_YSRC} 150 ${YACC} ${YFLAGS} ${YFLAGS.${_YSRC}} -o ${_YC} ${.ALLSRC} 151.endif 152OBJS_DEPEND_GUESS.${_YC:R}.o+= ${_YC} 153.endfor 154.endfor 155 156# DTrace probe definitions 157.if ${SRCS:M*.d} 158CFLAGS+= -I${.OBJDIR} 159.endif 160.for _DSRC in ${SRCS:M*.d:N*/*} 161.for _D in ${_DSRC:R} 162SRCS+= ${_D}.h 163${_D}.h: ${_DSRC} 164 ${DTRACE} ${DTRACEFLAGS} -h -s ${.ALLSRC} 165SRCS:= ${SRCS:S/^${_DSRC}$//} 166OBJS+= ${_D}.o 167CLEANFILES+= ${_D}.h ${_D}.o 168${_D}.o: ${_DSRC} ${OBJS:S/^${_D}.o$//} 169 @rm -f ${.TARGET} 170 ${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h} 171.if defined(LIB) 172CLEANFILES+= ${_D}.pico ${_D}.pieo ${_D}.po ${_D}.nossppico 173${_D}.pico: ${_DSRC} ${SOBJS:S/^${_D}.pico$//} 174 @rm -f ${.TARGET} 175 ${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h} 176${_D}.pieo: ${_DSRC} ${OBJS:S/^${_D}.pieo$//} 177 @rm -f ${.TARGET} 178 ${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h} 179${_D}.po: ${_DSRC} ${POBJS:S/^${_D}.po$//} 180 @rm -f ${.TARGET} 181 ${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h} 182${_D}.nossppico: ${_DSRC} ${SOBJS:S/^${_D}.nossppico$//} 183 @rm -f ${.TARGET} 184 ${DTRACE} ${DTRACEFLAGS} -G -o ${.TARGET} -s ${.ALLSRC:N*.h} 185.endif 186.endfor 187.endfor 188.endif # defined(SRCS) 189 190.if ${MAKE_VERSION} < 20160220 191DEPEND_MP?= -MP 192.endif 193# Handle OBJS=../somefile.o hacks. Just replace '/' rather than use :T to 194# avoid collisions. 195DEPEND_FILTER= C,/,_,g 196.if !empty(OBJS) 197.if !defined(_ALLOW_ABSOLUTE_OBJ_PATH) && ${OBJS:M/*} 198# Absolute paths to OBJS should be an error inside ${SRCTOP}, but some users 199# might be relying on this feature, so add an opt-out mechanism. 200.if defined(SRCTOP) && ${OBJS:M${SRCTOP}*} 201.error $$OBJS inside $$SRCTOP not allowed: ${OBJS:M${SRCTOP}*} 202.elif ${OBJS:N${_ABSOLUTE_PATH_OBJS}:M/*} 203.error $$OBJS absolute path not allowed: ${OBJS:N${_ABSOLUTE_PATH_OBJS}:M/*}.\ 204 If this is intended, add them to _ABSOLUTE_PATH_OBJS to silence this error\ 205 or define _ALLOW_ABSOLUTE_OBJ_PATH to disable this diagnostic. 206.endif 207.endif 208DEPENDOBJS+= ${OBJS} 209.else 210DEPENDSRCS+= ${SRCS:M*.[cSC]} ${SRCS:M*.cxx} ${SRCS:M*.cpp} ${SRCS:M*.cc} 211DEPENDSRCS+= ${DPSRCS:M*.[cSC]} ${DPSRCS:M*.cxx} ${DPSRCS:M*.cpp} ${DPSRCS:M*.cc} 212.if !empty(DEPENDSRCS) 213DEPENDOBJS+= ${DEPENDSRCS:${OBJS_SRCS_FILTER:ts:}:S,$,.o,} 214.endif 215.endif # !empty(OBJS) 216.if !empty(DEPENDOBJS) 217DEPENDFILES+= ${DEPENDOBJS:O:u:${DEPEND_FILTER}:C/^/${DEPENDFILE}./} 218.endif 219.if defined(_SKIP_DEPEND) 220# Don't bother statting any .meta files for .depend* 221${DEPENDOBJS}: .NOMETA 222${DEPENDFILE}: .NOMETA 223# Unset these to avoid looping/statting on them later. 224.undef DEPENDSRCS 225.undef DEPENDOBJS 226.undef DEPENDFILES 227.endif # defined(_SKIP_DEPEND) 228DEPEND_CFLAGS+= -MD ${DEPEND_MP} -MF${DEPENDFILE}.${.TARGET:${DEPEND_FILTER}} 229DEPEND_CFLAGS+= -MT${.TARGET} 230.if !defined(_meta_filemon) 231.if !empty(DEPEND_CFLAGS) 232# Only add in DEPEND_CFLAGS for CFLAGS on files we expect from DEPENDOBJS 233# as those are the only ones we will include. 234DEPEND_CFLAGS_CONDITION= "${DEPENDOBJS:${DEPEND_FILTER}:M${.TARGET:${DEPEND_FILTER}}}" != "" 235CFLAGS+= ${${DEPEND_CFLAGS_CONDITION}:?${DEPEND_CFLAGS}:} 236.endif 237.for __depend_obj in ${DEPENDFILES} 238.if ${MAKE_VERSION} < 20160220 239.sinclude "${.OBJDIR}/${__depend_obj}" 240.else 241.dinclude "${.OBJDIR}/${__depend_obj}" 242.endif 243.endfor 244.endif # !defined(_meta_filemon) 245 246.if ${MK_DIRDEPS_BUILD} == "yes" && ${.MAKE.DEPENDFILE} != "/dev/null" 247# Prevent meta.autodep.mk from tracking "local dependencies". 248.depend: 249.include <meta.autodep.mk> 250# If using filemon then _EXTRADEPEND is skipped since it is not needed. 251.if defined(_meta_filemon) 252# this depend: bypasses that below 253# the dependency helps when bootstrapping 254depend: beforedepend ${DPSRCS} ${SRCS} afterdepend 255beforedepend: 256afterdepend: beforedepend 257.endif 258.endif 259 260# Guess some dependencies for when no ${DEPENDFILE}.OBJ is generated yet. 261# For meta+filemon the .meta file is checked for since it is the dependency 262# file used. 263.for __obj in ${DEPENDOBJS:O:u} 264# If the obj has any '/', then replace with '_'. For meta files, this is 265# mimicing what bmake's meta_name() does and adding in the full path 266# as well to ensure that the expected meta file is read. 267.if ${__obj:M*/*} 268.if ${MAKE_VERSION} < 20171028 269_meta_obj= ${.OBJDIR:C,/,_,g}_${__obj:C,/,_,g}.meta 270.else 271_meta_obj= ${__obj:C,/,_,g}.meta 272.endif # ${MAKE_VERSION} < 20171028 273.else 274_meta_obj= ${__obj}.meta 275.endif # ${__obj:M*/*} 276_dep_obj= ${DEPENDFILE}.${__obj:${DEPEND_FILTER}} 277.if defined(_meta_filemon) 278_depfile= ${.OBJDIR}/${_meta_obj} 279.else 280_depfile= ${.OBJDIR}/${_dep_obj} 281.endif 282.if !exists(${_depfile}) || defined(_meta_filemon) 283# - Headers are normally built in beforebuild when included in DPSRCS or SRCS. 284# So we don't need it as a guessed dependency (it may lead to cyclic problems 285# if custom rules are defined). The only time this causes a problem is when 286# 'make foo.o' is ran. 287# - For meta mode we still need to know which file to depend on to avoid 288# ambiguous suffix transformation rules from .PATH. Meta mode does not 289# use .depend files when filemon is in use. 290.if !target(${__obj}) 291${__obj}: ${OBJS_DEPEND_GUESS} 292.endif 293${__obj}: ${OBJS_DEPEND_GUESS.${__obj}} 294.endif # !exists(${_depfile}) || defined(_meta_filemon) 295.endfor 296 297# Always run 'make depend' to generate dependencies early and to avoid the 298# need for manually running it. The dirdeps build should only do this in 299# sub-makes though since MAKELEVEL0 is for dirdeps calculations. 300.if ${MK_DIRDEPS_BUILD} == "no" || ${.MAKE.LEVEL} > 0 301beforebuild: depend 302.endif 303 304.if !target(depend) 305.if defined(SRCS) 306depend: beforedepend ${DEPENDFILE} afterdepend 307 308# Tell bmake not to look for generated files via .PATH 309.NOPATH: ${DEPENDFILE} ${DEPENDFILES} 310 311# A .depend file will only be generated if there are commands in 312# beforedepend/_EXTRADEPEND/afterdepend The _EXTRADEPEND target is 313# ignored if using meta+filemon since it handles all dependencies. The other 314# targets are kept as they be used for generating something. The target is 315# kept to allow 'make depend' to generate files. 316${DEPENDFILE}: ${SRCS} ${DPSRCS} 317.if !defined(_SKIP_DEPEND) 318.if exists(${.OBJDIR}/${DEPENDFILE}) || \ 319 ((commands(beforedepend) || \ 320 (!defined(_meta_filemon) && commands(_EXTRADEPEND)) || \ 321 commands(afterdepend)) && !empty(.MAKE.MODE:Mmeta)) 322 rm -f ${DEPENDFILE} 323.endif 324.endif 325.if !defined(_meta_filemon) && target(_EXTRADEPEND) 326_EXTRADEPEND: .USE 327${DEPENDFILE}: _EXTRADEPEND 328.endif 329 330.ORDER: ${DEPENDFILE} afterdepend 331.else 332depend: beforedepend afterdepend 333.endif 334.if !target(beforedepend) 335beforedepend: 336.else 337.ORDER: beforedepend ${DEPENDFILE} 338.ORDER: beforedepend afterdepend 339.endif 340.if !target(afterdepend) 341afterdepend: 342.endif 343.endif 344 345.if defined(SRCS) 346.if ${CTAGS:T} == "gtags" 347CLEANDEPENDFILES+= GPATH GRTAGS GSYMS GTAGS 348.if defined(HTML) 349CLEANDEPENDDIRS+= HTML 350.endif 351.else 352CLEANDEPENDFILES+= tags 353.endif 354.endif 355.if !target(cleandepend) 356cleandepend: 357.if !empty(CLEANDEPENDFILES) 358 rm -f ${CLEANDEPENDFILES} 359.endif 360.if !empty(CLEANDEPENDDIRS) 361 rm -rf ${CLEANDEPENDDIRS} 362.endif 363.endif 364.ORDER: cleandepend all 365.ORDER: cleandepend depend 366.if ${MK_AUTO_OBJ} == "yes" 367.ORDER: cleanobj depend 368.ORDER: cleandir depend 369.endif 370 371.if !target(checkdpadd) && (defined(DPADD) || defined(LDADD)) 372_LDADD_FROM_DPADD= ${DPADD:R:T:C;^lib(.*)$;-l\1;g} 373# Ignore -Wl,--start-group/-Wl,--end-group as it might be required in the 374# LDADD list due to unresolved symbols 375_LDADD_CANONICALIZED= ${LDADD:N:R:T:C;^lib(.*)$;-l\1;g:N-Wl,--[es]*-group} 376checkdpadd: 377.if ${_LDADD_FROM_DPADD} != ${_LDADD_CANONICALIZED} 378 @echo ${.CURDIR} 379 @echo "DPADD -> ${_LDADD_FROM_DPADD}" 380 @echo "LDADD -> ${_LDADD_CANONICALIZED}" 381.endif 382.endif 383