1# $FreeBSD$ 2# 3# The include file <bsd.obj.mk> handles creating the 'obj' directory 4# and cleaning up object files, etc. 5# 6# +++ variables +++ 7# 8# CLEANDIRS Additional directories to remove for the clean target. 9# 10# CLEANFILES Additional files to remove for the clean target. 11# 12# MAKEOBJDIR A pathname for the directory where the targets 13# are built. Note: MAKEOBJDIR is an *environment* variable 14# and works properly only if set as an environment variable, 15# not as a global or command line variable! 16# 17# E.g. use `env MAKEOBJDIR=temp-obj make' 18# 19# MAKEOBJDIRPREFIX Specifies somewhere other than /usr/obj to root the object 20# tree. Note: MAKEOBJDIRPREFIX is an *environment* variable 21# and works properly only if set as an environment variable, 22# not as a global or command line variable! 23# 24# E.g. use `env MAKEOBJDIRPREFIX=/somewhere/obj make' 25# 26# NO_OBJ Do not create object directories. This should not be set 27# if anything is built. 28# 29# +++ targets +++ 30# 31# clean: 32# remove ${CLEANFILES}; remove ${CLEANDIRS} and all contents. 33# 34# cleandir: 35# remove the build directory (and all its contents) created by obj 36# 37# obj: 38# create build directory. 39# 40 41.if !target(__<bsd.obj.mk>__) 42__<bsd.obj.mk>__: 43.include <bsd.own.mk> 44 45.if ${MK_AUTO_OBJ} == "yes" 46# it is done by now 47objwarn: .PHONY 48obj: .PHONY 49CANONICALOBJDIR= ${.OBJDIR} 50# This is also done in bsd.init.mk 51.if defined(NO_OBJ) && ${.OBJDIR} != ${.CURDIR} 52# but this makefile does not want it! 53.OBJDIR: ${.CURDIR} 54.endif 55# Handle special case where SRCS is full-pathed and requires 56# nested objdirs. This duplicates some auto.obj.mk logic. 57.if (!empty(SRCS:M*/*) || !empty(DPSRCS:M*/*)) && \ 58 (${.TARGETS} == "" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} != "") && \ 59 !make(print-dir) && empty(.MAKEFLAGS:M-[nN]) 60_wantdirs= ${SRCS:M*/*:H} ${DPSRCS:M*/*:H} 61.if !empty(_wantdirs) 62_wantdirs:= ${_wantdirs:O:u} 63_needdirs= 64.for _dir in ${_wantdirs} 65.if !exists(${.OBJDIR}/${_dir}/) 66_needdirs+= ${_dir} 67.endif 68.endfor 69.endif 70.if !empty(_needdirs) 71#_mkneededdirs!= umask ${OBJDIR_UMASK:U002}; ${Mkdirs} ${_needdirs} 72__objdir_made != umask ${OBJDIR_UMASK:U002}; ${Mkdirs}; \ 73 for dir in ${_needdirs}; do \ 74 dir=${.OBJDIR}/$${dir}; \ 75 ${ECHO_TRACE} "[Creating nested objdir $${dir}...]" >&2; \ 76 Mkdirs $${dir}; \ 77 done 78.endif 79.endif # !empty(SRCS:M*/*) || !empty(DPSRCS:M*/*) 80.elif !empty(MAKEOBJDIRPREFIX) 81CANONICALOBJDIR:=${MAKEOBJDIRPREFIX}${.CURDIR} 82.elif defined(MAKEOBJDIR) && ${MAKEOBJDIR:M/*} != "" 83CANONICALOBJDIR:=${MAKEOBJDIR} 84OBJTOP?= ${MAKEOBJDIR} 85.else 86CANONICALOBJDIR:=/usr/obj${.CURDIR} 87.endif 88 89.if defined(SRCTOP) && defined(RELDIR) && \ 90 (${CANONICALOBJDIR} == /${RELDIR} || ${.OBJDIR} == /${RELDIR}) 91.error .OBJDIR incorrectly set to /${RELDIR} 92.endif 93 94OBJTOP?= ${.OBJDIR:S,${.CURDIR},,}${SRCTOP} 95 96# 97# Warn of unorthodox object directory. 98# 99# The following directories are tried in order for ${.OBJDIR}: 100# 101# 1. ${MAKEOBJDIRPREFIX}/`pwd` 102# 2. ${MAKEOBJDIR} 103# 3. obj.${MACHINE} 104# 4. obj 105# 5. /usr/obj/`pwd` 106# 6. ${.CURDIR} 107# 108# If ${.OBJDIR} is constructed using canonical cases 1 or 5, or 109# case 2 (using MAKEOBJDIR), don't issue a warning. Otherwise, 110# issue a warning differentiating between cases 6 and (3 or 4). 111# 112objwarn: .PHONY 113.if !defined(NO_OBJ) && ${.OBJDIR} != ${CANONICALOBJDIR} && \ 114 !(defined(MAKEOBJDIRPREFIX) && exists(${CANONICALOBJDIR}/)) && \ 115 !(defined(MAKEOBJDIR) && exists(${MAKEOBJDIR}/)) 116.if ${.OBJDIR} == ${.CURDIR} 117 @${ECHO} "Warning: Object directory not changed from original ${.CURDIR}" 118.elif exists(${.CURDIR}/obj.${MACHINE}/) || exists(${.CURDIR}/obj/) 119 @${ECHO} "Warning: Using ${.OBJDIR} as object directory instead of\ 120 canonical ${CANONICALOBJDIR}" 121.endif 122.endif 123beforebuild: objwarn 124 125.if !defined(NO_OBJ) 126.if !target(obj) 127obj: .PHONY 128 @if ! test -d ${CANONICALOBJDIR}/; then \ 129 mkdir -p ${CANONICALOBJDIR}; \ 130 if ! test -d ${CANONICALOBJDIR}/; then \ 131 ${ECHO} "Unable to create ${CANONICALOBJDIR}."; \ 132 exit 1; \ 133 fi; \ 134 ${ECHO} "${CANONICALOBJDIR} created for ${.CURDIR}"; \ 135 fi 136.for dir in ${SRCS:H:O:u} ${DPSRCS:H:O:u} 137 @if ! test -d ${CANONICALOBJDIR}/${dir}/; then \ 138 mkdir -p ${CANONICALOBJDIR}/${dir}; \ 139 if ! test -d ${CANONICALOBJDIR}/${dir}/; then \ 140 ${ECHO} "Unable to create ${CANONICALOBJDIR}/${dir}."; \ 141 exit 1; \ 142 fi; \ 143 ${ECHO} "${CANONICALOBJDIR}/${dir} created for ${.CURDIR}"; \ 144 fi 145.endfor 146.endif 147 148.if !target(objlink) 149objlink: .PHONY 150 @if test -d ${CANONICALOBJDIR}/; then \ 151 rm -f ${.CURDIR}/obj; \ 152 ln -s ${CANONICALOBJDIR} ${.CURDIR}/obj; \ 153 else \ 154 echo "No ${CANONICALOBJDIR} to link to - do a make obj."; \ 155 fi 156.endif 157.endif # !defined(NO_OBJ) 158 159# 160# where would that obj directory be? 161# 162.if !target(whereobj) 163whereobj: .PHONY 164 @echo ${.OBJDIR} 165.endif 166 167# Same check in bsd.progs.mk 168.if ${CANONICALOBJDIR} != ${.CURDIR} && exists(${CANONICALOBJDIR}/) && \ 169 (${MK_AUTO_OBJ} == "no" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} == "") 170cleanobj: .PHONY 171 -rm -rf ${CANONICALOBJDIR} 172.else 173cleanobj: .PHONY clean cleandepend 174.endif 175 @if [ -L ${.CURDIR}/obj ]; then rm -f ${.CURDIR}/obj; fi 176 177# Tell bmake not to look for generated files via .PATH 178NOPATH_FILES+= ${CLEANFILES} 179.if !empty(NOPATH_FILES) 180.NOPATH: ${NOPATH_FILES} 181.endif 182 183.if !target(clean) 184clean: .PHONY 185.if defined(CLEANFILES) && !empty(CLEANFILES) 186 rm -f ${CLEANFILES} 187.endif 188.if defined(CLEANDIRS) && !empty(CLEANDIRS) 189 -rm -rf ${CLEANDIRS} 190.endif 191.endif 192.ORDER: clean all 193.if ${MK_AUTO_OBJ} == "yes" 194.ORDER: cleanobj all 195.ORDER: cleandir all 196.endif 197 198.include <bsd.subdir.mk> 199 200cleandir: .PHONY .WAIT cleanobj 201 202.if make(destroy*) && defined(OBJROOT) 203# this (rm -rf objdir) is much faster and more reliable than cleaning. 204 205# just in case we are playing games with these... 206_OBJDIR?= ${.OBJDIR} 207_CURDIR?= ${.CURDIR} 208 209# destroy almost everything 210destroy: .PHONY destroy-all 211destroy-all: .PHONY 212 213# just remove our objdir 214destroy-arch: .PHONY .NOMETA 215.if ${_OBJDIR} != ${_CURDIR} 216 cd ${_CURDIR} && rm -rf ${_OBJDIR} 217.endif 218 219.if defined(HOST_OBJTOP) 220destroy-host: destroy.host 221destroy.host: .PHONY .NOMETA 222 cd ${_CURDIR} && rm -rf ${HOST_OBJTOP}/${RELDIR:N.} 223.endif 224 225.if make(destroy-all) && ${RELDIR} == "." 226destroy-all: destroy-stage 227.endif 228 229# remove the stage tree 230destroy-stage: .PHONY .NOMETA 231.if defined(STAGE_ROOT) 232 cd ${_CURDIR} && rm -rf ${STAGE_ROOT} 233.endif 234 235# allow parallel destruction 236_destroy_machine_list = common host ${ALL_MACHINE_LIST} 237.for m in ${_destroy_machine_list:O:u} 238destroy-all: destroy.$m 239.if !target(destroy.$m) 240destroy.$m: .PHONY .NOMETA 241.if ${_OBJDIR} != ${_CURDIR} 242 cd ${_CURDIR} && rm -rf ${OBJROOT}$m*/${RELDIR:N.} 243.endif 244.endif 245.endfor 246 247.endif 248 249.endif # !target(__<bsd.obj.mk>__) 250