xref: /freebsd/share/mk/meta.stage.mk (revision 7750ad47a9a7dbc83f87158464170c8640723293)
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