1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
|
#!/bin/bash
#
# Copyright (C) 2007 Lauri Leukkunen <lle@rahina.org>
#
# Redesigned/refactored by Lauri T. Aarnio;
# Portion Copyright (c) 2008 Nokia Corporation.
# All rights reserved.
#
# Licensed under GPL version 2
#
# -------------------
#
# dpkg-checkbuilddeps wrapper for SB2.
#
# Currently there are two algorithms for this: Old and new.
#
# The old one, implemented completely as a shell script,
# ignores many things that should be checked. The new one is
# is written in perl, but the implementation is still
# incomplete. Currently things work so that this shell
# script digs out the needed variables and feeds them to
# the perl script (the old algorithm is off by default).
#
# Alternatively, the old and new algorithms can both be
# enable by setting environment variable SBOX_DOUBLECHECK_DEPS
# to any non-empty value. I haven't seen any cases where the
# old algorithm would be better that the new one, but I'm
# interested to hear if there are any...before this old
# stuff will be completely removed / Lauri T. Aarnio 2009-01-31.
#
# Here is description of the OLD algorithm:
# Idea behind operation is to first check target's package db,
# then check if missing packages are tools that could be used
# from the host (or sbox_tools_root, if that has been set)
#
# There might also be dependencies that SB2 itself solves;
# for example, gcc-* dependencies might be resolved by the
# cross compiler.
#
# Requirements:
# - Package db maps to *target* package db
# - can switch temporarily to tools mode, and then the
# db maps to *tools* package db
#
# [N.B. The new algorithm solves this:
# FIXME: This implementation is still incomplete, as this does not
# check package versions while checking host/tools_root tools.
# Also, it would be a good idea to do a "visibility check" for host packages,
# too (see how sb2-check-pkg-mappings does it for target's pkg db)]
args="$*"
prog="$0"
progbase=`basename $0`
SBOX_REDIRECT_IGNORE=""
function error_not_inside_sb2()
{
echo "SB2: $progbase: This wrapper can only be used from inside"
echo "the scratchbox 2'ed environment"
exit 1
}
if [ -z "$SBOX_SESSION_DIR" ]
then
error_not_inside_sb2
fi
. $SBOX_SESSION_DIR/sb2-session.conf
# A generated, temporary package db which only contains packages that
# are usable thru the current mapping mode:
TARGET_DPKG_ADMINDIR_USABLE_PKGS=$sbox_temp_dpkg_admin_dir
cfgfile_host_accepted_pkgs=$sbox_dir/share/scratchbox2/modeconf/host-accepted-packages.$sbox_mapmode
cfgfile_host_ignored_pkgs=$sbox_dir/share/scratchbox2/modeconf/host-ignored-packages.$sbox_mapmode
# Check if a named package exists of the host.
# Returns result in three variables:
# - $installed_to_host is either "yes" or "no"
# - $check_result_msg and $check_result_msg2 return a more detailed
# explanation of the result (strings).
function check_host_pkg()
{
pkgname=$1
installed_to_host="no" # default
check_result_msg="'$pkgname' not found."
check_result_msg2=""
# Check if it can be accepted from the host:
g=`grep "^$pkgname\$" $cfgfile_host_accepted_pkgs`
if [ -z "$g" ]
then
# No, the package has not been aproved to be used from the host.
# first check if this requirement should be ignored completely:
if [ -f $cfgfile_host_ignored_pkgs ]
then
# ignorelist exists
g=`grep "^$pkgname\$" $cfgfile_host_ignored_pkgs`
if [ -z "$g" ]
then
check_result_msg="'$pkgname' is missing (must be installed to the rootstrap)"
else
check_result_msg="'$pkgname' is missing, but this is ignored by configuration"
installed_to_host="yes"
return
fi
fi
pkg_stat_tmp=`mktemp -p $SBOX_SESSION_DIR/tmp pkg-stat.XXXXXXXXXX`
# next check again if the package exists on the target,
# just to be able to give a better error message.
if dpkg-query -s "$pkgname" >$pkg_stat_tmp 2>&1
then
if grep -q "ok installed" $pkg_stat_tmp
then
rm $pkg_stat_tmp
check_result_msg="'$pkgname': OOPS. Needed from the the rootstrap (installed there),"
check_result_msg2=" but unusable (not fully visible due to SB2 mapping rules)"
return
fi
fi
rm $pkg_stat_tmp
check_result_msg="'$pkgname' is missing, must be installed to the rootstrap"
return
fi
# package is not present in the rootstrap, but
# it can be accepted from the host environment.
if SBOX_SESSION_MODE=tools dpkg-query -s "$pkgname" >/dev/null 2>&1
then
installed_to_host="yes"
check_result_msg="'$pkgname' found from the host environment"
return
fi
# not installed. Test if this can be ignored.
if [ -f $cfgfile_host_ignored_pkgs ]
then
g=`grep "^$pkgname\$" $cfgfile_host_ignored_pkgs`
if [ -n "$g" ]
then
check_result_msg="'$pkgname' is not available (ignored by configuration)"
installed_to_host="yes"
return
fi
fi
check_result_msg="'$pkgname' is missing (can be installed to the host)"
return 1
}
function check_gcc_dependency()
{
required_gcc=$1
prefix="$2"
if [ -f $HOME/.scratchbox2/$sbox_target/sb2.config.d/gcc.config.sh ]
then
# a cross compiler has been configured
if [ "$required_gcc" = "gcc" ]
then
# requires GCC, but does not depend on gcc version
echo "$prefix""SB2 provides gcc"
return 0
fi
#
# Find out if gcc version is suitable, try all configured
# toolchains
for gcc_conf_file in \
$HOME/.scratchbox2/$sbox_target/sb2.config.d/gcc*.config.sh
do
if [ -f $gcc_conf_file ]; then
. $gcc_conf_file
short_vrs="gcc-$SBOX_CROSS_GCC_SHORTVERSION"
full_vrs="gcc-$SBOX_CROSS_GCC_VERSION"
if [ "$required_gcc" = "$short_vrs" -o \
"$required_gcc" = "$full_vrs" ]; then
echo "$prefix""SB2 provides $required_gcc"
return 0
fi
fi
done
fi # else a cross-compiler is not available, gcc comes from tools
# Failed, SB2 environment does not provide a suitable gcc.
return 1
}
function check_sb2_builddeps()
{
orig_missing="$1"
prefix="$2"
new_missing=""
ret=0
# Currently, SB2 can fulfill "gcc" and "gcc-<version>"
for m in $orig_missing
do
case $m in
gcc*) check_gcc_dependency "$m" "$prefix"
if [ $? != 0 ]; then
# gcc check failed
new_missing="$new_missing $m"
fi
;;
*) # keep it in the list of missing pkgs
new_missing="$new_missing $m"
;;
esac
done
missing_deps="$new_missing"
if [ -z "$new_missing" ]; then
# all resolved.
true
else
# still missing something
false
fi
}
function check_host_builddeps()
{
missing="$1"
prefix="$2"
ret=0
# do the magic here
echo "$prefix""SB2 Checking host build deps.."
list_ok=1 # default to ok
# $m will be the package to test, or pkg/pkg[/...] if there are
# alternatives (unfortunately '|' has special meaning in shell's
# "case" statement, so we'll have to replace it by '/')
for m in $(echo $missing | sed -e 's/([^)]\+)//g' | \
sed -e 's:[ ]*|[ ]*:/:g')
do
## echo " Testing $m:"
case "$m" in
*/*) # alternatives..
has_one_alternative=0
for mmm in $(echo $m | sed -e 's:/: :')
do
echo "$prefix"" ...$mmm"
check_host_pkg $mmm
if [ "$installed_to_host" = "yes" ]
then
echo "$prefix"" $mmm = ok"
has_one_alternative=1
else
echo "$prefix"" no $mmm.."
fi
done
if [ $has_one_alternative == 0 ]
then
echo "$prefix"" Requirement $m failed; none of the alternatives were found."
list_ok=0
else
echo "$prefix"" '$m': At least one alternative found, ok."
fi
;;
*) # No alternatives.
check_host_pkg $m
echo "$prefix"" $check_result_msg"
if [ -n "$check_result_msg2" ]
then
echo "$prefix"" $check_result_msg2"
fi
if [ "$installed_to_host" = "no" ]
then
list_ok=0
fi
esac
done
if [ $list_ok == 0 ]; then
# somethings missing
false
else
true
fi
}
function check_host_builddeps_by_real_tool()
{
ret=0
echo "SB2 Checking tools build deps..."
x_missing_dep_file=`mktemp -p $SBOX_SESSION_DIR/tmp tools_missing_deps.XXXXXXXXXX`
# Run dpkg-checkbuilddeps in the "tools" mode
# Note: Can't use a pipeline here, we want to the
# dpkg-checkbuilddeps' return status.
SBOX_SESSION_MODE=tools /usr/bin/dpkg-checkbuilddeps \
$args > $x_missing_dep_file 2>&1
if [ $? == 0 ]
then
# real dpkg-checkbuilddeps says "all ok"
rm $x_missing_dep_file
tools_missing_deps=""
return 0
fi
# else real dpkg-checkbuilddeps failed.
# sed -e 's/^/ /' < $x_missing_dep_file
tools_missing_deps=$(egrep \
"^dpkg-checkbuilddeps: Unmet build dependencies:" \
$x_missing_dep_file | \
sed 's/dpkg-checkbuilddeps: Unmet build dependencies: //')
rm $x_missing_dep_file
if [ -n "$tools_missing_deps" ]; then
# failing target deps, and missing packages are listed
# in $tools_missing_deps = continue by checking if those are
# available on the host environment
return 1
else
# failing target deps, but $tools_missing_deps is empty. Something
# is fatally wrong.
echo "FATAL: Failed to check dependencies from tools_root DB"
exit 1
fi
}
function check_target_builddeps()
{
ret=0
echo "SB2 Checking target build deps..."
missing_dep_file=`mktemp -p $SBOX_SESSION_DIR/tmp missing_deps.XXXXXXXXXX`
# dpkg-checkbuilddeps with another package db..
# a special rule in the tools mode is needed because the
# version which is available in /usr/bin may not know about the
# --admindir option. Can't use a pipeline here, we want to the
# dpkg-checkbuilddeps' return status.
SBOX_TOOLS_MODE_VAR_LIB_DPKG_STATUS_LOCATION=$TARGET_DPKG_ADMINDIR_USABLE_PKGS/status \
SBOX_SESSION_MODE=tools /usr/bin/dpkg-checkbuilddeps \
$args > $missing_dep_file 2>&1
if [ $? == 0 ]
then
# real dpkg-checkbuilddeps says "all ok"
rm $missing_dep_file
return 0
fi
# else real dpkg-checkbuilddeps failed.
sed -e 's/^/ /' < $missing_dep_file
missing_deps=$(egrep \
"^dpkg-checkbuilddeps: Unmet build dependencies:" \
$missing_dep_file | \
sed 's/dpkg-checkbuilddeps: Unmet build dependencies: //')
rm $missing_dep_file
if [ -n "$missing_deps" ]; then
# failing target deps, and missing packages are listed
# in $missing_deps = continue by checking if those are
# available on the host environment
return 1
else
# failing target deps, but $missing_deps is empty. Something
# is fatally wrong.
echo "FATAL: Failed to check dependencies from target_root DB"
exit 1
fi
}
function compare_target_and_host_results_with_new_tool()
{
t_missing=$missing_deps
h_missing=$tools_missing_deps
both_required=`cat $TARGET_DPKG_ADMINDIR_USABLE_PKGS/both-required`
host_accepted=`grep -v "#" $cfgfile_host_accepted_pkgs`
host_ignored=""
if [ -f $cfgfile_host_ignored_pkgs ]
then
# ignorelist exists
host_ignored=`grep -v "#" $cfgfile_host_ignored_pkgs`
fi
echo "SB2 Combining results from target and tools..."
$sbox_dir/share/scratchbox2/lib/sb2-cmp-checkbuilddeps-output.pl \
"$t_missing" "$h_missing" "$both_required" "$host_accepted" "$host_ignored"
result2=$?
return $result2
#### if [ $? = 0 ]; then
#### result2="ok"
####else
#### result2="fail"
####fi
}
# First, make sure we are in a correct directory:
if [ ! -f debian/control ]
then
echo "Error: Can't find file debian/control"
exit 1
fi
# Next, check that the list of usable packages exists and is up-to-date.
# That list is really a temporary package database, which contains only
# packages that are usable thru this mapping mode.
sb2-check-pkg-mappings -u
check_target_builddeps
check_target_builddeps_result=$?
missing_deps_after_target_check="$missing_deps"
function old_deps_checker()
{
if [ $check_target_builddeps_result == 0 ]; then
# nothing is missing = nothing needed from the host side
echo "OLD_CHK: Target rootstrap => all dependencies OK"
return 0
fi
echo "OLD_CHK: Build dependencies missing from the target environment:"
echo "OLD_CHK: $missing_deps"
# Something is missing. Check if SB2 can fulfill the requirements:
check_sb2_builddeps "$missing_deps" "OLD_CHK: "
if [ $? == 0 ]; then
# OK now, nothing needed from the host side
echo "OLD_CHK: SB2 tools check => all dependencies OK"
return 0
fi
# Something is missing. To be able to get the missing packages from the
# host environment, at least the list of allowed packages is needed:
#
if [ ! -f $cfgfile_host_accepted_pkgs ]
then
echo "OLD_CHK:"
echo "OLD_CHK: Configuration file $cfgfile_host_accepted_pkgs"
echo "OLD_CHK: does not exist. This means that no packages have been approved to be used"
echo "OLD_CHK: from the host environment in this mapping mode ($sbox_mapmode)."
return 1
fi
check_host_builddeps "$missing_deps" "OLD_CHK: "
if [ $? != 0 ]; then
echo "OLD_CHK: Failed. Host environment did not meet all requirements."
return 1
fi
# since we're here, everything is more or less ok
echo "OLD_CHK: All OK."
return 0
}
function new_deps_checker()
{
check_sb2_builddeps "$missing_deps" ""
# $missing_deps has been updated
check_host_builddeps_by_real_tool
# $tools_missing_deps now contains a list of missing
# packages, liste by the real dpkg-checkbuilddeps
compare_target_and_host_results_with_new_tool
new_deps_checker_result=$?
}
if [ -n "$SBOX_DOUBLECHECK_DEPS" ]; then
old_deps_checker
old_deps_checker_result=$?
fi
missing_deps="$missing_deps_after_target_check"
new_deps_checker
if [ -n "$SBOX_DOUBLECHECK_DEPS" ]; then
if [ "$new_deps_checker_result" != "$old_deps_checker_result" ]; then
echo "INCONSISTENT: new and old methods do not agree:"
if [ "$new_deps_checker_result" = 0 ]; then
echo " : new => dependency checks OK"
else
echo " : new => dependency checks FAILED"
fi
if [ "$old_deps_checker_result" = 0 ]; then
echo " : old => dependency checks OK"
else
echo " : old => dependency checks FAILED"
fi
echo "Failed."
exit 1
fi
fi
if [ "$new_deps_checker_result" != "0" ]; then
echo "Failed."
exit 1
fi
# since we're here, everything is more or less ok
echo "All OK."
exit 0
|