meta.stage.mk revision 246149
1251881Speter# $Id: meta.stage.mk,v 1.17 2013/01/24 01:02:23 sjg Exp $ 2251881Speter# 3251881Speter# @(#) Copyright (c) 2011, Simon J. Gerraty 4251881Speter# 5251881Speter# This file is provided in the hope that it will 6251881Speter# be of use. There is absolutely NO WARRANTY. 7251881Speter# Permission to copy, redistribute or otherwise 8251881Speter# use this file is hereby granted provided that 9251881Speter# the above copyright notice and this notice are 10251881Speter# left intact. 11251881Speter# 12251881Speter# Please send copies of changes and bug-fixes to: 13251881Speter# sjg@crufty.net 14251881Speter# 15251881Speter 16251881Speter.if !target(__${.PARSEFILE}__) 17251881Speter__${.PARSEFILE}__: 18251881Speter 19251881Speter.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} != "" 20251881Speter# this is generally safer anyway 21251881Speter_dirdep = ${RELDIR}.${MACHINE} 22251881Speter.else 23251881Speter_dirdep = ${RELDIR} 24251881Speter.endif 25251881Speter 26251881Speter# this allows us to trace dependencies back to their src dir 27251881Speter.dirdep: 28251881Speter @echo '${_dirdep}' > $@ 29251881Speter 30251881Speter.if defined(NO_POSIX_SHELL) || ${type printf:L:sh:Mbuiltin} == "" 31299742Sdim_stage_file_basename = `basename $$f` 32299742Sdim_stage_target_dirname = `dirname $$t` 33251881Speter.else 34251881Speter_stage_file_basename = $${f\#\#*/} 35251881Speter_stage_target_dirname = $${t%/*} 36251881Speter.endif 37251881Speter 38251881Speter_objroot ?= ${_OBJROOT:tA} 39251881Speter# make sure this is global 40251881Speter_STAGED_DIRS ?= 41251881Speter.export _STAGED_DIRS 42251881Speter# add each dir we stage to to _STAGED_DIRS 43251881Speter# and make sure we have absolute paths so that bmake 44251881Speter# will match against .MAKE.META.BAILIWICK 45251881SpeterSTAGE_DIR_FILTER = tA:@d@$${_STAGED_DIRS::+=$$d}$$d@ 46251881Speter# convert _STAGED_DIRS into suitable filters 47251881SpeterGENDIRDEPS_FILTER += Nnot-empty-is-important \ 48299742Sdim ${_STAGED_DIRS:O:u:M${OBJTOP}*:S,${OBJTOP}/,N,} \ 49251881Speter ${_STAGED_DIRS:O:u:N${OBJTOP}*:S,${_objroot},,:C,^([^/]+)/(.*),N\2.\1,:S,${HOST_TARGET},.host,} 50251881Speter 51299742Sdim# it is an error for more than one src dir to try and stage 52251881Speter# the same file 53251881SpeterSTAGE_DIRDEP_SCRIPT = StageDirdep() { \ 54251881Speter t=$$1; \ 55251881Speter if [ -s $$t.dirdep ]; then \ 56251881Speter cmp -s .dirdep $$t.dirdep && return; \ 57251881Speter echo "ERROR: $$t installed by `cat $$t.dirdep` not ${_dirdep}" >&2; \ 58251881Speter exit 1; \ 59251881Speter fi; \ 60251881Speter ln .dirdep $$t.dirdep 2> /dev/null || \ 61251881Speter cp .dirdep $$t.dirdep; } 62251881Speter 63251881Speter# common logic for staging files 64251881Speter# this all relies on RELDIR being set to a subdir of SRCTOP 65251881Speter# we use ln(1) if we can, else cp(1) 66251881SpeterSTAGE_FILE_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageFiles() { \ 67251881Speter case "$$1" in -m) mode=$$2; shift 2;; *) mode=;; esac; \ 68251881Speter dest=$$1; shift; \ 69251881Speter mkdir -p $$dest; \ 70251881Speter [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ 71251881Speter for f in "$$@"; do \ 72251881Speter case "$$f" in */*) t=$$dest/${_stage_file_basename};; *) t=$$dest/$$f;; esac; \ 73251881Speter StageDirdep $$t; \ 74251881Speter rm -f $$t; \ 75251881Speter { ln $$f $$t 2> /dev/null || \ 76251881Speter cp -p $$f $$t; }; \ 77251881Speter $${mode:+chmod $$mode $$t}; \ 78251881Speter done; :; } 79251881Speter 80251881SpeterSTAGE_LINKS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageLinks() { \ 81251881Speter case "$$1" in --) shift;; -*) ldest= lnf=$$1; shift;; /*) ldest=$$1/;; esac; \ 82251881Speter dest=$$1; shift; \ 83251881Speter mkdir -p $$dest; \ 84251881Speter [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ 85251881Speter while test $$\# -ge 2; do \ 86251881Speter l=$$ldest$$1; shift; \ 87251881Speter t=$$dest/$$1; \ 88251881Speter case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \ 89251881Speter shift; \ 90251881Speter StageDirdep $$t; \ 91251881Speter rm -f $$t 2>/dev/null; \ 92251881Speter ln $$lnf $$l $$t; \ 93251881Speter done; :; } 94251881Speter 95251881SpeterSTAGE_AS_SCRIPT = ${STAGE_DIRDEP_SCRIPT}; StageAs() { \ 96251881Speter case "$$1" in -m) mode=$$2; shift 2;; *) mode=;; esac; \ 97251881Speter dest=$$1; shift; \ 98251881Speter mkdir -p $$dest; \ 99251881Speter [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ 100251881Speter while test $$\# -ge 2; do \ 101251881Speter s=$$1; shift; \ 102251881Speter t=$$dest/$$1; \ 103251881Speter case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \ 104251881Speter shift; \ 105251881Speter StageDirdep $$t; \ 106251881Speter rm -f $$t; \ 107251881Speter { ln $$s $$t 2> /dev/null || \ 108251881Speter cp -p $$s $$t; }; \ 109251881Speter $${mode:+chmod $$mode $$t}; \ 110251881Speter done; :; } 111251881Speter 112251881Speter# this is simple, a list of the "staged" files depends on this, 113251881Speter_STAGE_BASENAME_USE: .USE ${.TARGET:T} 114251881Speter @${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H:${STAGE_DIR_FILTER}} ${.TARGET:T} 115251881Speter 116251881Speter.if !empty(STAGE_INCSDIR) 117251881SpeterCLEANFILES += stage_incs 118251881Speter 119251881SpeterSTAGE_INCS ?= ${.ALLSRC:N.dirdep} 120251881Speter 121251881Speterstage_incs: .dirdep 122251881Speter @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_INCSDIR:${STAGE_DIR_FILTER}} ${STAGE_INCS} 123251881Speter @touch $@ 124251881Speter.endif 125251881Speter 126251881Speter.if !empty(STAGE_LIBDIR) 127251881SpeterCLEANFILES += stage_libs 128251881Speter 129251881SpeterSTAGE_LIBS ?= ${.ALLSRC:N.dirdep} 130251881Speter 131251881Speterstage_libs: .dirdep 132251881Speter @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${STAGE_LIBS} 133251881Speter.if !empty(SHLIB_LINKS) 134251881Speter @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} \ 135251881Speter ${SHLIB_LINKS:@t@${STAGE_LIBS:T:M$t.*} $t@} 136251881Speter.elif !empty(SHLIB_LINK) && !empty(SHLIB_NAME) 137251881Speter @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR:${STAGE_DIR_FILTER}} ${SHLIB_NAME} ${SHLIB_LINK} ${SYMLINKS:T} 138251881Speter.endif 139251881Speter @touch $@ 140251881Speter.endif 141251881Speter 142251881Speter.if !empty(STAGE_DIR) 143251881SpeterSTAGE_SETS += _default 144251881SpeterSTAGE_DIR._default = ${STAGE_DIR} 145251881SpeterSTAGE_LINKS_DIR._default = ${STAGE_LINKS_DIR:U${STAGE_OBJTOP}} 146251881SpeterSTAGE_SYMLINKS_DIR._default = ${STAGE_SYMLINKS_DIR:U${STAGE_OBJTOP}} 147251881SpeterSTAGE_FILES._default = ${STAGE_FILES} 148251881SpeterSTAGE_LINKS._default = ${STAGE_LINKS} 149251881SpeterSTAGE_SYMLINKS._default = ${STAGE_SYMLINKS} 150251881SpeterSTAGE_FILES ?= ${.ALLSRC:N.dirdep:Nstage_*} 151251881SpeterSTAGE_SYMLINKS ?= ${.ALLSRC:T:N.dirdep:Nstage_*} 152251881Speter.endif 153251881Speter 154251881Speter.if !empty(STAGE_SETS) 155251881Speter 156251881SpeterCLEANFILES += ${STAGE_SETS:@s@stage*$s@} 157251881Speter 158251881Speter# some makefiles need to populate multiple directories 159251881Speter.for s in ${STAGE_SETS:O:u} 160251881SpeterSTAGE_FILES.$s ?= ${.ALLSRC:N.dirdep} 161251881SpeterSTAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep} 162251881SpeterSTAGE_LINKS_DIR.$s ?= ${STAGE_OBJTOP} 163251881SpeterSTAGE_SYMLINKS_DIR.$s ?= ${STAGE_OBJTOP} 164251881Speter 165251881Speter.if $s != "_default" 166251881Speterstage_files: stage_files.$s 167251881Speterstage_files.$s: .dirdep 168251881Speter.else 169251881Speterstage_files: .dirdep 170251881Speter.endif 171251881Speter @${STAGE_FILE_SCRIPT}; StageFiles ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_FILES.$s} 172251881Speter @touch $@ 173251881Speter 174251881Speter.if $s != "_default" 175251881Speterstage_links: stage_links.$s 176251881Speterstage_links.$s: .dirdep 177251881Speter.else 178251881Speterstage_links: .dirdep 179251881Speter.endif 180251881Speter @${STAGE_LINKS_SCRIPT}; StageLinks ${STAGE_LINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_LINKS.$s} 181251881Speter @touch $@ 182251881Speter 183251881Speter.if $s != "_default" 184251881Speterstage_symlinks: stage_symlinks.$s 185251881Speterstage_symlinks.$s: .dirdep 186251881Speter.else 187251881Speterstage_symlinks: .dirdep 188251881Speter.endif 189251881Speter @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_SYMLINKS_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_SYMLINKS.$s} 190251881Speter @touch $@ 191251881Speter 192251881Speter.endfor 193251881Speter.endif 194251881Speter 195251881Speter.if !empty(STAGE_AS_SETS) 196251881SpeterCLEANFILES += ${STAGE_AS_SETS:@s@stage*$s@} 197251881Speter 198251881Speter# sometimes things need to be renamed as they are staged 199251881Speter# each ${file} will be staged as ${STAGE_AS_${file:T}} 200251881Speter# one could achieve the same with SYMLINKS 201251881Speter.for s in ${STAGE_AS_SETS:O:u} 202251881SpeterSTAGE_AS.$s ?= ${.ALLSRC:N.dirdep} 203251881Speter 204251881Speterstage_as: stage_as.$s 205251881Speterstage_as.$s: .dirdep 206251881Speter @${STAGE_AS_SCRIPT}; StageAs ${FLAGS.$@} ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}:${STAGE_DIR_FILTER}} ${STAGE_AS.$s:@f@$f ${STAGE_AS_${f:T}:U${f:T}}@} 207251881Speter @touch $@ 208251881Speter 209251881Speter.endfor 210251881Speter.endif 211251881Speter 212251881Speter.endif 213251881Speter