1# SPDX-License-Identifier: BSD-2-Clause 2# 3# RCSid: 4# $Id: autodep.mk,v 1.43 2024/02/17 17:26:57 sjg Exp $ 5# 6# @(#) Copyright (c) 1999-2024, Simon J. Gerraty 7# 8# This file is provided in the hope that it will 9# be of use. There is absolutely NO WARRANTY. 10# Permission to copy, redistribute or otherwise 11# use this file is hereby granted provided that 12# the above copyright notice and this notice are 13# left intact. 14# 15# Please send copies of changes and bug-fixes to: 16# sjg@crufty.net 17 18# This module provides automagic dependency generation along the 19# lines suggested in the GNU make.info 20# The depend target is mainly for backwards compatibility, 21# dependencies are normally updated as part of compilation. 22 23.if !target(__${.PARSEFILE}__) 24__${.PARSEFILE}__: .NOTMAIN 25 26DEPENDFILE?= .depend 27.for d in ${DEPENDFILE:N.depend} 28# bmake only groks .depend 29.if ${MAKE_VERSION} < 20160218 30.-include <$d> 31.else 32.dinclude <$d> 33.endif 34.endfor 35 36# should have been set by sys.mk 37CXX_SUFFIXES ?= .cc .ccm .cpp .cxx .C 38 39# it does nothing if SRCS is not defined or is empty 40.if defined(SRCS) && !empty(SRCS) 41DEPSRCS ?= ${SRCS} 42__depsrcs = ${DEPSRCS:M*.c} 43__depsrcs += ${DEPSRCS:M*.y} 44__depsrcs += ${DEPSRCS:M*.l} 45__depsrcs += ${DEPSRCS:M*.s} 46__depsrcs += ${DEPSRCS:M*.S} 47__depsrcs += ${DEPSRCS:M*.pc} 48.for s in ${CXX_SUFFIXES} 49__depsrcs += ${DEPSRCS:M*$s} 50.endfor 51 52.for s in ${__depsrcs} 53${s:T:R}.d: $s 54.endfor 55 56__depsrcs := ${__depsrcs:T:R:S/$/.d/g} 57# we also need to handle makefiles where the .d's from __depsrcs 58# don't match those from OBJS 59# we avoid using := here, since the modifier applied to OBJS 60# can cause trouble if there are any undefined vars in OBJS. 61__dependsrcsx ?= ${__depsrcs} ${OBJS:S/.o/.d/} 62__dependsrcs = ${__dependsrcsx:O:u} 63 64# clean up any .c files we may have generated 65#__gensrcs := ${DEPSRCS:M*.y} ${DEPSRCS:M*.l} 66#CLEANFILES += ${__gensrcs:T:R:S/$/.c/g} 67 68# set this to -MMD to ignore /usr/include 69# actually it ignores <> so may not be a great idea 70CFLAGS_MD ?= -MD 71# -MF etc not available on all gcc versions. 72# we "fix" the .o later 73.if ${COMPILER_TYPE:Ugcc} == "gcc" && ${COMPILER_VERSION:U0} < 30000 74CFLAGS_MF = 75.endif 76CFLAGS_MF ?= -MF ${.TARGET:T:R}.d -MT ${.TARGET:T:R}.o 77CFLAGS += ${CFLAGS_MD} ${CFLAGS_MF} 78RM?= rm 79MAKE_SHELL ?= sh 80 81# watch out for people who don't use CPPFLAGS 82CPPFLAGS_MD = ${CFLAGS:M-[IUD]*} ${CPPFLAGS} 83CXXFLAGS_MD = ${CXXFLAGS:M-[IUD]*} ${CPPFLAGS} 84 85# just in case these need to be different 86CC_MD ?= ${CC} 87CXX_MD ?= ${CXX} 88 89# so we can do an explicit make depend, but not otherwise 90.if make(depend) 91.SUFFIXES: .d 92 93.if empty(CFLAGS_MD) 94.y.d: 95 @echo updating dependencies for $< 96 @${YACC} ${YFLAGS} $< 97 @${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} y.tab.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f y.tab.c $@; false; } 98 @${RM} -f y.tab.c 99 100.l.d: 101 @echo updating dependencies for $< 102 ${LEX} ${LFLAGS} $< 103 @${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} lex.yy.c | sed '/:/s/^/$@ /' > $@" || { ${RM} -f lex.yy.c $@; false; } 104 @${RM} -f lex.yy.c 105 106.c.d: 107 @echo updating dependencies for $< 108 @${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; } 109 110.s.d .S.d: 111 @echo updating dependencies for $< 112 @${MAKE_SHELL} -ec "${CC_MD} -M ${CPPFLAGS_MD} ${AINC} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; } 113 114${CXX_SUFFIXES:%=%.d}: 115 @echo updating dependencies for $< 116 @${MAKE_SHELL} -ec "${CXX_MD} -M ${CXXFLAGS_MD} $< | sed '/:/s/^/$@ /' > $@" || { ${RM} -f $@; false; } 117 118.else 119 120.y.d: 121 ${YACC} ${YFLAGS} $< 122 ${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} y.tab.c > $@ || { ${RM} -f y.tab.c $@; false; } 123 ${RM} -f y.tab.c 124 125.l.d: 126 ${LEX} ${LFLAGS} $< 127 ${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} lex.yy.c > $@ || { ${RM} -f lex.yy.c $@; false; } 128 ${RM} -f lex.yy.c 129 130.c.d: 131 ${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} $< > $@ || { ${RM} -f $@; false; } 132 133.s.d .S.d: 134 ${CC_MD} ${CFLAGS_MD:S/D//} ${CPPFLAGS_MD} ${AINC} $< > $@ || { ${RM} -f $@; false; } 135 136${CXX_SUFFIXES:%=%.d}: 137 ${CXX_MD} ${CFLAGS_MD:S/D//} ${CXXFLAGS_MD} $< > $@ || { ${RM} -f $@; false; } 138 139.endif 140 141.if !target(depend) 142depend: beforedepend ${DEPENDFILE} afterdepend _SUBDIRUSE 143 144${DEPENDFILE}: ${DEPSRCS} ${__dependsrcs} 145.NOPATH: ${__dependsrcs} 146.OPTIONAL: ${__dependsrcs} 147.endif 148.endif # make(depend) 149 150.if empty(CFLAGS_MD) 151# make sure the .d's are generated/updated 152${PROG} ${_LIBS}: ${DEPENDFILE} 153.endif 154 155.ORDER: beforedepend ${DEPENDFILE} afterdepend 156 157.if ${.OBJDIR} != ${.CURDIR} 158__depfiles = *.d 159.else 160__depfiles = ${__dependsrcs} 161.endif 162 163DEPCLEANFILES = ${DEPENDFILE} ${__depfiles} y.tab.d *.tmp.d 164 165cleandir: cleanautodepend 166cleanautodepend: 167 ${RM} -f ${DEPCLEANFILES} 168 169CLEANFILES += ${DEPCLEANFILES} 170 171.if defined(__dependsrcs) && !empty(__dependsrcs) 172.if make(depend) || !(make(clean*) || make(destroy*) || make(obj) || make(*install) || make(install-*)) 173# this ensures we do the right thing if only building a shared or 174# profiled lib 175OBJ_SUFFIXES ?= .o .po .so .So 176MDLIB_SED = -e '/:/s,^\([^\.:]*\)\.[psS]*o,${OBJ_SUFFIXES:S,^,\1,},' 177.ifdef NOMD_SED 178.ifdef LIB 179MD_SED = sed ${MDLIB_SED} 180.else 181MD_SED = cat 182.endif 183.else 184# arrange to put some variable names into ${DEPENDFILE} 185.ifdef LIB 186MD_SED = sed ${MDLIB_SED} 187.else 188MD_SED = sed 189.endif 190SUBST_DEPVARS += SB TOP BACKING SRC SRCDIR BASE BASEDIR 191.for v in ${SUBST_DEPVARS} 192.if defined(${v}) && !empty(${v}) 193MD_SED += -e 's,${$v},$${$v},' 194.endif 195.endfor 196.endif 197.if (${MD_SED} == "sed") 198MD_SED = cat 199.endif 200 201# this will be done whenever make finishes successfully 202.if ${MAKE_VERSION:U0:[1]:C/.*-//} < 20050530 203.END: 204.else 205.END: ${DEPENDFILE} 206# we do not want to trigger building .d's just use them if they exist 207${DEPENDFILE}: ${__dependsrcs:@d@${exists($d):?$d:}@} 208.endif 209 -@${MD_SED} ${__depfiles} > ${DEPENDFILE}.new 2> /dev/null && \ 210 test -s ${DEPENDFILE}.new && mv ${DEPENDFILE}.new ${DEPENDFILE}; \ 211 ${RM} -f ${DEPENDFILE}.new 212.endif 213.endif 214.else 215depend: beforedepend afterdepend _SUBDIRUSE 216.endif 217 218.if !target(beforedepend) 219beforedepend: 220.endif 221.if !target(afterdepend) 222afterdepend: 223.endif 224 225.-include <ccm.dep.mk> 226 227.endif 228