1# $Id: meta.stage.mk,v 1.11 2011/05/05 15:01:05 sjg Exp $ 2# 3# @(#) Copyright (c) 2011, Simon J. Gerraty 4# 5# This file is provided in the hope that it will 6# be of use. There is absolutely NO WARRANTY. 7# Permission to copy, redistribute or otherwise 8# use this file is hereby granted provided that 9# the above copyright notice and this notice are 10# left intact. 11# 12# Please send copies of changes and bug-fixes to: 13# sjg@crufty.net 14# 15 16.if !target(__${.PARSEFILE}__) 17__${.PARSEFILE}__: 18 19.if ${.MAKE.DEPENDFILE_PREFERENCE:U${.MAKE.DEPENDFILE}:M*.${MACHINE}} != "" 20# this is generally safer anyway 21_dirdep = ${RELDIR}.${MACHINE} 22.else 23_dirdep = ${RELDIR} 24.endif 25 26# this allows us to trace dependencies back to their src dir 27.dirdep: 28 @echo '${_dirdep}' > $@ 29 30.if defined(NO_POSIX_SHELL) || ${type printf:L:sh:Mbuiltin} == "" 31_stage_file_basename = `basename $$f` 32_stage_target_dirname = `dirname $$t` 33.else 34_stage_file_basename = $${f\#\#*/} 35_stage_target_dirname = $${t%/*} 36.endif 37 38# common logic for staging files 39# this all relies on RELDIR being set to a subdir of SRCTOP 40# we use ln(1) if we can, else cp(1) 41STAGE_FILE_SCRIPT = StageFiles() { \ 42 dest=$$1; shift; \ 43 mkdir -p $$dest; \ 44 [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ 45 for f in "$$@"; do \ 46 case "$$f" in */*) t=$$dest/${_stage_file_basename};; *) t=$$dest/$$f;; esac; \ 47 rm -f $$t $$t.dirdep; \ 48 { ln $$f $$t 2> /dev/null || \ 49 cp -p $$f $$t; } && \ 50 { ln .dirdep $$t.dirdep 2> /dev/null || \ 51 cp .dirdep $$t.dirdep; }; \ 52 done; } 53 54STAGE_LINKS_SCRIPT = StageLinks() { \ 55 case "$$1" in --) shift;; -*) lnf=$$1; shift;; esac; \ 56 dest=$$1; shift; \ 57 mkdir -p $$dest; \ 58 [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ 59 while test $$\# -ge 2; do \ 60 l=$$1; shift; \ 61 t=$$dest/$$1; \ 62 case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \ 63 shift; \ 64 rm -f $$t $$t.dirdep 2>/dev/null; \ 65 ln $$lnf $$l $$t; \ 66 { ln .dirdep $$t.dirdep 2> /dev/null || \ 67 cp .dirdep $$t.dirdep; }; \ 68 done; :; } 69 70STAGE_AS_SCRIPT = StageAs() { \ 71 dest=$$1; shift; \ 72 mkdir -p $$dest; \ 73 [ -s .dirdep ] || echo '${_dirdep}' > .dirdep; \ 74 while test $$\# -ge 2; do \ 75 s=$$1; shift; \ 76 t=$$dest/$$1; \ 77 case "$$1" in */*) mkdir -p ${_stage_target_dirname};; esac; \ 78 shift; \ 79 rm -f $$t $$t.dirdep; \ 80 { ln $$s $$t 2> /dev/null || \ 81 cp -p $$s $$t; } && \ 82 { ln .dirdep $$t.dirdep 2> /dev/null || \ 83 cp .dirdep $$t.dirdep; }; \ 84 done; } 85 86# this is simple, a list of the "staged" files depends on this, 87_STAGE_BASENAME_USE: .USE ${.TARGET:T} 88 @${STAGE_FILE_SCRIPT}; StageFiles ${.TARGET:H} ${.TARGET:T} 89 90.if !empty(STAGE_INCSDIR) 91STAGE_INCS ?= ${.ALLSRC:N.dirdep} 92 93stage_incs: .dirdep 94 @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_INCSDIR} ${STAGE_INCS} 95 @touch $@ 96.endif 97 98.if !empty(STAGE_LIBDIR) 99STAGE_LIBS ?= ${.ALLSRC:N.dirdep} 100 101stage_libs: .dirdep 102 @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_LIBDIR} ${STAGE_LIBS} 103.if !empty(SHLIB_LINKS) 104 @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR} \ 105 ${SHLIB_LINKS:@t@${STAGE_LIBS:T:M$t.*} $t@} 106.elif !empty(SHLIB_LINK) && !empty(SHLIB_NAME) 107 @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_LIBDIR} ${SHLIB_NAME} ${SHLIB_LINK} ${SYMLINKS:T} 108.endif 109 @touch $@ 110.endif 111 112.if !empty(STAGE_DIR) 113STAGE_SETS += _default 114STAGE_DIR._default = ${STAGE_DIR} 115STAGE_SYMLINKS_DIR._default = ${STAGE_SYMLINKS_DIR:U${STAGE_DIR}} 116STAGE_FILES._default = ${STAGE_FILES} 117STAGE_SYMLINKS._default = ${STAGE_SYMLINKS} 118STAGE_FILES ?= ${.ALLSRC:N.dirdep:Nstage_*} 119STAGE_SYMLINKS ?= ${.ALLSRC:T:N.dirdep:Nstage_*} 120.endif 121 122.if !empty(STAGE_SETS) 123 124# some makefiles need to populate multiple directories 125.for s in ${STAGE_SETS:O:u} 126STAGE_FILES.$s ?= ${.ALLSRC:N.dirdep} 127STAGE_SYMLINKS.$s ?= ${.ALLSRC:N.dirdep} 128 129.if $s != "_default" 130stage_files: stage_files.$s 131stage_files.$s: .dirdep 132.else 133stage_files: .dirdep 134.endif 135 @${STAGE_FILE_SCRIPT}; StageFiles ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}} ${STAGE_FILES.$s} 136 @touch $@ 137 138.if $s != "_default" 139stage_symlinks: stage_symlinks.$s 140stage_symlinks.$s: .dirdep 141.else 142stage_symlinks: .dirdep 143.endif 144 @${STAGE_LINKS_SCRIPT}; StageLinks -s ${STAGE_SYMLINKS_DIR.$s:U${STAGE_DIR.$s}} ${STAGE_SYMLINKS.$s} 145 @touch $@ 146 147.endfor 148.endif 149 150.if !empty(STAGE_AS_SETS) 151 152# sometimes things need to be renamed as they are staged 153# each ${file} will be staged as ${STAGE_AS_${file:T}} 154# one could achieve the same with SYMLINKS 155.for s in ${STAGE_AS_SETS:O:u} 156STAGE_AS.$s ?= ${.ALLSRC:N.dirdep} 157 158stage_as: stage_as.$s 159stage_as.$s: .dirdep 160 @${STAGE_AS_SCRIPT}; StageAs ${STAGE_FILES_DIR.$s:U${STAGE_DIR.$s}} ${STAGE_AS.$s:@f@$f ${STAGE_AS_${f:T}:U${f:T}}@} 161 @touch $@ 162 163.endfor 164.endif 165 166.endif 167