linux-qubasis
linux oasis port as a qubes template
git clone https://9o.is/git/linux-qubasis.git
genfn.sh
(3131B)
1 main() {
2 DIR=.
3 OUTDIR=./out
4 NINJA_FILE=local.ninja
5 NINJA_FILES=$DIR/$NINJA_FILE
6 GEN_FILES='./gen.sh ./genfn.sh'
7 GEN_OUTS=$DIR/$NINJA_FILE
8
9 set_target "$1"
10 init_file
11 trap gen_done EXIT
12 }
13
14 init_file() {
15 if persist && [ -e $DIR/$NINJA_FILE.tmp ]; then
16 rm -f $DIR/$NINJA_FILE.tmp
17 fi
18 }
19
20 fini_file() {
21 _f=$DIR/$NINJA_FILE
22 if persist && [ -e $_f.tmp ]; then
23 if cmp -s $_f.tmp $_f; then
24 rm -f $_f.tmp
25 else
26 mv $_f.tmp $_f
27 fi
28 fi
29 }
30
31 gen_done() {
32 gen "$GEN_OUTS" '|' $GEN_FILES
33 phony $dir/ninja $NINJA_FILES
34 fini_file
35 wait
36 }
37
38 import() {
39 GEN_FILES="$GEN_FILES $DIR/$1"
40 . $DIR/$1
41 }
42
43 set_target() {
44 TARGET=
45 TARGET_ROUTE=
46
47 case "$1" in
48 .|./)
49 TARGET=.
50 ;;
51 '')
52 return
53 ;;
54 *)
55 TARGET=${1%/}
56 TARGET=./${TARGET#./}
57 set_target_route $TARGET
58 ;;
59 esac
60 }
61
62 set_target_route() {
63 TARGET_ROUTE="$TARGET_ROUTE $1"
64 if [ $1 = . ]; then return; fi
65 set_target_route $(dirname $1)
66 }
67
68 in_target_route() {
69 [ ! "$TARGET" ] || has $DIR/$1 $TARGET_ROUTE
70 }
71
72 persist() {
73 [ ! "$TARGET" ] || [ $TARGET = $DIR ]
74 }
75
76 write() {
77 if persist; then
78 printf '%s\n' "$@" >> $DIR/$NINJA_FILE.tmp
79 fi
80 }
81
82 sub() (
83 write "subninja $dir/$1.ninja"
84 NINJA_FILE=$1.ninja
85 init_file
86
87 [ "${2-}" ] && eval "$2 $1"
88 $1
89 [ "${3-}" ] && eval "$3 $1"
90 fini_file
91 )
92
93 subgen() {
94 write "subninja $dir/$1/$NINJA_FILE"
95 NINJA_FILES="$NINJA_FILES $dir/$1/ninja"
96
97 if in_target_route $1; then
98 (
99 DIR=$DIR/$1
100 OUTDIR=$OUTDIR/$1
101 NINJA_FILES=$DIR/local.ninja
102 GEN_FILES="$GEN_FILES $DIR/gen.sh"
103 GEN_OUTS=$DIR/$NINJA_FILE
104
105 init_file
106
107 var dir $dir/$1
108 var outdir $outdir/$1
109
110 [ "${2-}" ] && eval "$2 $1"
111
112 . $DIR/gen.sh
113
114 [ "${3-}" ] && eval "$3 $1"
115
116 gen_done
117 ) &
118 fi
119 }
120
121 var() {
122 _v1=$1
123 shift
124 inline _vs $*
125 write "$_v1 = $_vs"
126 eval "$_v1='\$$_v1'"
127 }
128
129 bind() {
130 _v1=$1
131 shift
132 inline _vs $*
133 write " $_v1 = $_vs"
134 }
135
136 build() {
137 _v1=$1
138 prefix _v2 $outdir $2
139 shift 2
140 prefix _vs $dir $*
141 build_parse $_vs
142 write "build $_v2: $_v1 $_vs $_vd $_vo"
143 }
144
145 build_parse() {
146 _vs=
147 _vd=
148 _vo=
149 _mode=vs
150
151 for _v in $*; do
152 case $_v in
153 '|') _mode=vd;;
154 '||') _mode=vo;;
155 *)
156 case $_mode in
157 vs) _vs="$_vs $_v";;
158 vd) _vd="${_vd:-|} $_v";;
159 vo) _vo="${_vo:-||} $_v";;
160 esac
161 esac
162 done
163 }
164
165 rule() {
166 _rule=$1
167 _cmd="$2"
168
169 write "rule $_rule"
170 bind command "$_cmd"
171
172 _d=
173 for _v in $_cmd; do
174 case "$_v" in
175 *\$*dir/*) _d="${_d:-'|'} \$${_v#*$}";;
176 esac
177 done
178
179 eval "$_rule() { _v=\"\$1\"; shift; build $_rule \"\$_v\" \$* $_d; }"
180 }
181
182 default() {
183 prefix _v $dir $1
184 write "default $_v"
185 }
186
187 phony() {
188 prefix _v $dir $1
189 shift
190 write "build $_v: phony $*"
191 }
192
193 prefix() {
194 _var=$1
195 _pre=$2
196 _vs=
197 shift 2
198
199 for _v in $*; do
200 case $_v in
201 \$* | \|* | /* | .*) ;;
202 *) _v=$_pre/$_v;;
203 esac
204 _vs="$_vs $_v"
205 done
206
207 eval "$_var='$_vs'"
208 }
209
210 inline() {
211 _var=$1
212 _vs=
213 shift
214
215 for _v in $*; do
216 _vs="$_vs $_v"
217 done
218
219 eval "$_var='$_vs'"
220 }
221
222 error() {
223 printf "Error gen $DIR: %s\n" "$*"
224 exit 1
225 }
226
227 has() {
228 _val=$1
229 shift
230 for _v in $*; do
231 if [ $_v = $_val ]; then
232 return 0
233 fi
234 done
235 return 1
236 }
237
238 foreach() {
239 while read -r line; do
240 $2 $line
241 done <$DIR/$1
242 GEN_FILES="$GEN_FILES $DIR/$1"
243 }
244
245 main "${1-}"