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_wantdirs= ${SRCS:M*/*:H} ${DPSRCS:M*/*:H} 60.if !empty(_wantdirs) 61_wantdirs:= ${_wantdirs:O:u} 62_needdirs= 63.for _dir in ${_wantdirs} 64.if !exists(${.OBJDIR}/${_dir}/) 65_needdirs+= ${_dir} 66.endif 67.endfor 68.endif 69.if !empty(_needdirs) 70#_mkneededdirs!= umask ${OBJDIR_UMASK:U002}; ${Mkdirs} ${_needdirs} 71__objdir_made != umask ${OBJDIR_UMASK:U002}; ${Mkdirs}; \ 72 for dir in ${_needdirs}; do \ 73 dir=${.OBJDIR}/$${dir}; \ 74 ${ECHO_TRACE} "[Creating nested objdir $${dir}...]" >&2; \ 75 Mkdirs $${dir}; \ 76 done 77.endif 78.endif # !empty(SRCS:M*/*) || !empty(DPSRCS:M*/*) 79.elif !empty(MAKEOBJDIRPREFIX) 80CANONICALOBJDIR:=${MAKEOBJDIRPREFIX}${.CURDIR} 81.elif defined(MAKEOBJDIR) && ${MAKEOBJDIR:M/*} != "" 82CANONICALOBJDIR:=${MAKEOBJDIR} 83OBJTOP?= ${MAKEOBJDIR} 84.else 85CANONICALOBJDIR:=/usr/obj${.CURDIR} 86.endif 87 88.if defined(SRCTOP) && defined(RELDIR) && \ 89 (${CANONICALOBJDIR} == /${RELDIR} || ${.OBJDIR} == /${RELDIR}) 90.error .OBJDIR incorrectly set to /${RELDIR} 91.endif 92 93OBJTOP?= ${.OBJDIR:S,${.CURDIR},,}${SRCTOP} 94 95# 96# Warn of unorthodox object directory. 97# 98# The following directories are tried in order for ${.OBJDIR}: 99# 100# 1. ${MAKEOBJDIRPREFIX}/`pwd` 101# 2. ${MAKEOBJDIR} 102# 3. obj.${MACHINE} 103# 4. obj 104# 5. /usr/obj/`pwd` 105# 6. ${.CURDIR} 106# 107# If ${.OBJDIR} is constructed using canonical cases 1 or 5, or 108# case 2 (using MAKEOBJDIR), don't issue a warning. Otherwise, 109# issue a warning differentiating between cases 6 and (3 or 4). 110# 111objwarn: .PHONY 112.if !defined(NO_OBJ) && ${.OBJDIR} != ${CANONICALOBJDIR} && \ 113 !(defined(MAKEOBJDIRPREFIX) && exists(${CANONICALOBJDIR}/)) && \ 114 !(defined(MAKEOBJDIR) && exists(${MAKEOBJDIR}/)) 115.if ${.OBJDIR} == ${.CURDIR} 116 @${ECHO} "Warning: Object directory not changed from original ${.CURDIR}" 117.elif exists(${.CURDIR}/obj.${MACHINE}/) || exists(${.CURDIR}/obj/) 118 @${ECHO} "Warning: Using ${.OBJDIR} as object directory instead of\ 119 canonical ${CANONICALOBJDIR}" 120.endif 121.endif 122beforebuild: objwarn 123 124.if !defined(NO_OBJ) 125.if !target(obj) 126obj: .PHONY 127 @if ! test -d ${CANONICALOBJDIR}/; then \ 128 mkdir -p ${CANONICALOBJDIR}; \ 129 if ! test -d ${CANONICALOBJDIR}/; then \ 130 ${ECHO} "Unable to create ${CANONICALOBJDIR}."; \ 131 exit 1; \ 132 fi; \ 133 ${ECHO} "${CANONICALOBJDIR} created for ${.CURDIR}"; \ 134 fi 135.for dir in ${SRCS:H:O:u} ${DPSRCS:H:O:u} 136 @if ! test -d ${CANONICALOBJDIR}/${dir}/; then \ 137 mkdir -p ${CANONICALOBJDIR}/${dir}; \ 138 if ! test -d ${CANONICALOBJDIR}/${dir}/; then \ 139 ${ECHO} "Unable to create ${CANONICALOBJDIR}/${dir}."; \ 140 exit 1; \ 141 fi; \ 142 ${ECHO} "${CANONICALOBJDIR}/${dir} created for ${.CURDIR}"; \ 143 fi 144.endfor 145.endif 146 147.if !target(objlink) 148objlink: .PHONY 149 @if test -d ${CANONICALOBJDIR}/; then \ 150 rm -f ${.CURDIR}/obj; \ 151 ln -s ${CANONICALOBJDIR} ${.CURDIR}/obj; \ 152 else \ 153 echo "No ${CANONICALOBJDIR} to link to - do a make obj."; \ 154 fi 155.endif 156.endif # !defined(NO_OBJ) 157 158# 159# where would that obj directory be? 160# 161.if !target(whereobj) 162whereobj: .PHONY 163 @echo ${.OBJDIR} 164.endif 165 166# Same check in bsd.progs.mk 167.if ${CANONICALOBJDIR} != ${.CURDIR} && exists(${CANONICALOBJDIR}/) && \ 168 (${MK_AUTO_OBJ} == "no" || ${.TARGETS:Nclean*:N*clean:Ndestroy*} == "") 169cleanobj: .PHONY 170 -rm -rf ${CANONICALOBJDIR} 171.else 172cleanobj: .PHONY clean cleandepend 173.endif 174 @if [ -L ${.CURDIR}/obj ]; then rm -f ${.CURDIR}/obj; fi 175 176# Tell bmake not to look for generated files via .PATH 177NOPATH_FILES+= ${CLEANFILES} 178.if !empty(NOPATH_FILES) 179.NOPATH: ${NOPATH_FILES} 180.endif 181 182.if !target(clean) 183clean: .PHONY 184.if defined(CLEANFILES) && !empty(CLEANFILES) 185 rm -f ${CLEANFILES} 186.endif 187.if defined(CLEANDIRS) && !empty(CLEANDIRS) 188 -rm -rf ${CLEANDIRS} 189.endif 190.endif 191.ORDER: clean all 192.if ${MK_AUTO_OBJ} == "yes" 193.ORDER: cleanobj all 194.ORDER: cleandir all 195.endif 196 197.include <bsd.subdir.mk> 198 199cleandir: .PHONY .WAIT cleanobj 200 201.if make(destroy*) && defined(OBJROOT) 202# this (rm -rf objdir) is much faster and more reliable than cleaning. 203 204# just in case we are playing games with these... 205_OBJDIR?= ${.OBJDIR} 206_CURDIR?= ${.CURDIR} 207 208# destroy almost everything 209destroy: .PHONY destroy-all 210destroy-all: .PHONY 211 212# just remove our objdir 213destroy-arch: .PHONY .NOMETA 214.if ${_OBJDIR} != ${_CURDIR} 215 cd ${_CURDIR} && rm -rf ${_OBJDIR} 216.endif 217 218.if defined(HOST_OBJTOP) 219destroy-host: destroy.host 220destroy.host: .PHONY .NOMETA 221 cd ${_CURDIR} && rm -rf ${HOST_OBJTOP}/${RELDIR:N.} 222.endif 223 224.if make(destroy-all) && ${RELDIR} == "." 225destroy-all: destroy-stage 226.endif 227 228# remove the stage tree 229destroy-stage: .PHONY .NOMETA 230.if defined(STAGE_ROOT) 231 cd ${_CURDIR} && rm -rf ${STAGE_ROOT} 232.endif 233 234# allow parallel destruction 235_destroy_machine_list = common host ${ALL_MACHINE_LIST} 236.for m in ${_destroy_machine_list:O:u} 237destroy-all: destroy.$m 238.if !target(destroy.$m) 239destroy.$m: .PHONY .NOMETA 240.if ${_OBJDIR} != ${_CURDIR} 241 cd ${_CURDIR} && rm -rf ${OBJROOT}$m*/${RELDIR:N.} 242.endif 243.endif 244.endfor 245 246.endif 247 248.endif # !target(__<bsd.obj.mk>__) 249