xf86-video-omapfb: pandora: handle cycle/forcer events better
[openembedded.git] / classes / utils.bbclass
1 def subprocess_setup():
2    import signal
3    # Python installs a SIGPIPE handler by default. This is usually not what
4    # non-Python subprocesses expect.
5    signal.signal(signal.SIGPIPE, signal.SIG_DFL)
6
7 def oe_popen(d, cmd, **kwargs):
8     """ Convenience function to call out processes with our exported
9     variables in the environment.
10     """
11     from subprocess import Popen
12
13     if kwargs.get("env") is None:
14         env = d.getVar("__oe_popen_env", False)
15         if env is None:
16             env = {}
17             for v in d.keys():
18                 if d.getVarFlag(v, "export"):
19                     env[v] = d.getVar(v, True) or ""
20             d.setVar("__oe_popen_env", env)
21         kwargs["env"] = env
22
23     kwargs["preexec_fn"] = subprocess_setup
24
25     return Popen(cmd, **kwargs)
26
27 def oe_system(d, cmd):
28     """ Popen based version of os.system. """
29     return oe_popen(d, cmd, shell=True).wait()
30
31 # like os.path.join but doesn't treat absolute RHS specially
32 def base_path_join(a, *p):
33     path = a
34     for b in p:
35         if path == '' or path.endswith('/'):
36             path +=  b
37         else:
38             path += '/' + b
39     return path
40
41 def base_path_relative(src, dest):
42     """ Return a relative path from src to dest.
43
44     >>> base_path_relative("/usr/bin", "/tmp/foo/bar")
45     ../../tmp/foo/bar
46
47     >>> base_path_relative("/usr/bin", "/usr/lib")
48     ../lib
49
50     >>> base_path_relative("/tmp", "/tmp/foo/bar")
51     foo/bar
52     """
53     from os.path import sep, pardir, normpath, commonprefix
54
55     destlist = normpath(dest).split(sep)
56     srclist = normpath(src).split(sep)
57
58     # Find common section of the path
59     common = commonprefix([destlist, srclist])
60     commonlen = len(common)
61
62     # Climb back to the point where they differentiate
63     relpath = [ pardir ] * (len(srclist) - commonlen)
64     if commonlen < len(destlist):
65         # Add remaining portion
66         relpath += destlist[commonlen:]
67
68     return sep.join(relpath)
69
70 def base_path_out(path, d):
71     """ Prepare a path for display to the user. """
72     rel = base_path_relative(d.getVar("TOPDIR", 1), path)
73     if len(rel) > len(path):
74         return path
75     else:
76         return rel
77
78 # for MD5/SHA handling
79 def base_chk_load_parser(config_paths):
80     import ConfigParser
81     parser = ConfigParser.ConfigParser()
82     if len(parser.read(config_paths)) < 1:
83         raise ValueError("no ini files could be found")
84
85     return parser
86
87 def base_chk_file_vars(parser, localpath, params, data):
88     try:
89         name = params["name"]
90     except KeyError:
91         return False
92     if name:
93         md5flag = "%s.md5sum" % name
94         sha256flag = "%s.sha256sum" % name
95     else:
96         md5flag = "md5sum"
97         sha256flag = "sha256sum"
98     want_md5sum = bb.data.getVarFlag("SRC_URI", md5flag, data)
99     want_sha256sum = bb.data.getVarFlag("SRC_URI", sha256flag, data)
100
101     if (want_sha256sum == None and want_md5sum == None):
102         # no checksums to check, nothing to do
103         return False
104
105     if not os.path.exists(localpath):
106         localpath = base_path_out(localpath, data)
107         bb.note("The localpath does not exist '%s'" % localpath)
108         raise Exception("The path does not exist '%s'" % localpath)
109
110     if want_md5sum:
111         try:
112             md5pipe = os.popen('PATH=%s md5sum "%s"' % (bb.data.getVar('PATH', data, True), localpath))
113             md5data = (md5pipe.readline().split() or [ "" ])[0]
114             md5pipe.close()
115         except OSError, e:
116             raise Exception("Executing md5sum failed")
117         if want_md5sum != md5data:
118             bb.note("The MD5Sums did not match. Wanted: '%s' and Got: '%s'" % (want_md5sum, md5data))
119             raise Exception("MD5 Sums do not match. Wanted: '%s' Got: '%s'" % (want_md5sum, md5data))
120
121     if want_sha256sum:
122         try:
123             shapipe = os.popen('PATH=%s oe_sha256sum "%s"' % (bb.data.getVar('PATH', data, True), localpath))
124             sha256data = (shapipe.readline().split() or [ "" ])[0]
125             shapipe.close()
126         except OSError, e:
127             raise Exception("Executing shasum failed")
128         if want_sha256sum != sha256data:
129             bb.note("The SHA256Sums did not match. Wanted: '%s' and Got: '%s'" % (want_sha256sum, sha256data))
130             raise Exception("SHA256 Sums do not match. Wanted: '%s' Got: '%s'" % (want_sha256sum, sha256data))
131
132     return True
133
134
135 def base_chk_file(parser, pn, pv, src_uri, localpath, data):
136     no_checksum = False
137     # Try PN-PV-SRC_URI first and then try PN-SRC_URI
138     # we rely on the get method to create errors
139     pn_pv_src = "%s-%s-%s" % (pn,pv,src_uri)
140     pn_src    = "%s-%s" % (pn,src_uri)
141     if parser.has_section(pn_pv_src):
142         md5    = parser.get(pn_pv_src, "md5")
143         sha256 = parser.get(pn_pv_src, "sha256")
144     elif parser.has_section(pn_src):
145         md5    = parser.get(pn_src, "md5")
146         sha256 = parser.get(pn_src, "sha256")
147     elif parser.has_section(src_uri):
148         md5    = parser.get(src_uri, "md5")
149         sha256 = parser.get(src_uri, "sha256")
150     else:
151         no_checksum = True
152
153     # md5 and sha256 should be valid now
154     if not os.path.exists(localpath):
155         localpath = base_path_out(localpath, data)
156         bb.note("The localpath does not exist '%s'" % localpath)
157         raise Exception("The path does not exist '%s'" % localpath)
158
159
160     # call md5(sum) and shasum
161     try:
162         md5pipe = os.popen('PATH=%s md5sum "%s"' % (bb.data.getVar('PATH', data, True), localpath))
163         md5data = (md5pipe.readline().split() or [ "" ])[0]
164         md5pipe.close()
165     except OSError:
166         raise Exception("Executing md5sum failed")
167
168     try:
169         shapipe = os.popen('PATH=%s oe_sha256sum "%s"' % (bb.data.getVar('PATH', data, True), localpath))
170         shadata = (shapipe.readline().split() or [ "" ])[0]
171         shapipe.close()
172     except OSError:
173         raise Exception("Executing shasum failed")
174
175     if no_checksum == True:     # we do not have conf/checksums.ini entry
176         try:
177             file = open("%s/checksums.ini" % bb.data.getVar("TMPDIR", data, 1), "a")
178         except:
179             return False
180
181         if not file:
182             raise Exception("Creating checksums.ini failed")
183         
184         file.write("[%s]\nmd5=%s\nsha256=%s\n\n" % (src_uri, md5data, shadata))
185         file.close()
186
187         from string import maketrans
188         trtable = maketrans("", "")
189         uname = src_uri.split("/")[-1].translate(trtable, "-+._")
190
191         try:
192             ufile = open("%s/%s.sum" % (bb.data.getVar("TMPDIR", data, 1), uname), "wt")
193         except:
194             return False
195
196         if not ufile:
197             raise Exception("Creating %s.sum failed" % uname)
198
199         ufile.write("SRC_URI = \"%s;name=%s\"\nSRC_URI[%s.md5sum] = \"%s\"\nSRC_URI[%s.sha256sum] = \"%s\"\n" % (src_uri, uname, uname, md5data, uname, shadata))
200         ufile.close()
201
202         if not bb.data.getVar("OE_STRICT_CHECKSUMS",data, True):
203             bb.note("This package has no entry in checksums.ini, please add one")
204             bb.note("\n[%s]\nmd5=%s\nsha256=%s" % (src_uri, md5data, shadata))
205             bb.note("This package has no checksums in corresponding recipe, please add")
206             bb.note("SRC_URI = \"%s;name=%s\"\nSRC_URI[%s.md5sum] = \"%s\"\nSRC_URI[%s.sha256sum] = \"%s\"\n" % (src_uri, uname, uname, md5data, uname, shadata))
207             return True
208         else:
209             bb.note("Missing checksum")
210             return False
211
212     if not md5 == md5data:
213         bb.note("The MD5Sums did not match. Wanted: '%s' and Got: '%s'" % (md5,md5data))
214         raise Exception("MD5 Sums do not match. Wanted: '%s' Got: '%s'" % (md5, md5data))
215
216     if not sha256 == shadata:
217         bb.note("The SHA256 Sums do not match. Wanted: '%s' Got: '%s'" % (sha256,shadata))
218         raise Exception("SHA256 Sums do not match. Wanted: '%s' Got: '%s'" % (sha256, shadata))
219
220     return True
221
222 def base_read_file(filename):
223         try:
224                 f = file( filename, "r" )
225         except IOError, reason:
226                 return "" # WARNING: can't raise an error now because of the new RDEPENDS handling. This is a bit ugly. :M:
227         else:
228                 return f.read().strip()
229         return None
230
231 def base_ifelse(condition, iftrue = True, iffalse = False):
232     if condition:
233         return iftrue
234     else:
235         return iffalse
236
237 def base_conditional(variable, checkvalue, truevalue, falsevalue, d):
238         if bb.data.getVar(variable,d,1) == checkvalue:
239                 return truevalue
240         else:
241                 return falsevalue
242
243 def base_less_or_equal(variable, checkvalue, truevalue, falsevalue, d):
244         if float(bb.data.getVar(variable,d,1)) <= float(checkvalue):
245                 return truevalue
246         else:
247                 return falsevalue
248
249 def base_version_less_or_equal(variable, checkvalue, truevalue, falsevalue, d):
250     result = bb.vercmp(bb.data.getVar(variable,d,True), checkvalue)
251     if result <= 0:
252         return truevalue
253     else:
254         return falsevalue
255
256 def base_contains(variable, checkvalues, truevalue, falsevalue, d):
257         val = bb.data.getVar(variable,d,1)
258         if not val:
259                 return falsevalue
260         matches = 0
261         if type(checkvalues).__name__ == "str":
262                 checkvalues = [checkvalues]
263         for value in checkvalues:
264                 if val.find(value) != -1:
265                         matches = matches + 1
266         if matches == len(checkvalues):
267                 return truevalue
268         return falsevalue
269
270 def base_both_contain(variable1, variable2, checkvalue, d):
271        if bb.data.getVar(variable1,d,1).find(checkvalue) != -1 and bb.data.getVar(variable2,d,1).find(checkvalue) != -1:
272                return checkvalue
273        else:
274                return ""
275
276 def base_prune_suffix(var, suffixes, d):
277     # See if var ends with any of the suffixes listed and 
278     # remove it if found
279     for suffix in suffixes:
280         if var.endswith(suffix):
281             return var.replace(suffix, "")
282     return var
283
284 def oe_filter(f, str, d):
285         from re import match
286         return " ".join(filter(lambda x: match(f, x, 0), str.split()))
287
288 def oe_filter_out(f, str, d):
289         from re import match
290         return " ".join(filter(lambda x: not match(f, x, 0), str.split()))
291
292 oedebug() {
293         test $# -ge 2 || {
294                 echo "Usage: oedebug level \"message\""
295                 exit 1
296         }
297
298         test ${OEDEBUG:-0} -ge $1 && {
299                 shift
300                 echo "DEBUG:" $*
301         }
302 }
303
304 oe_soinstall() {
305         # Purpose: Install shared library file and
306         #          create the necessary links
307         # Example:
308         #
309         # oe_
310         #
311         #oenote installing shared library $1 to $2
312         #
313         libname=`basename $1`
314         install -m 755 $1 $2/$libname
315         sonamelink=`${HOST_PREFIX}readelf -d $1 |grep 'Library soname:' |sed -e 's/.*\[\(.*\)\].*/\1/'`
316         solink=`echo $libname | sed -e 's/\.so\..*/.so/'`
317         ln -sf $libname $2/$sonamelink
318         ln -sf $libname $2/$solink
319 }
320
321 oe_libinstall() {
322         # Purpose: Install a library, in all its forms
323         # Example
324         #
325         # oe_libinstall libltdl ${STAGING_LIBDIR}/
326         # oe_libinstall -C src/libblah libblah ${D}/${libdir}/
327         dir=""
328         libtool=""
329         silent=""
330         require_static=""
331         require_shared=""
332         staging_install=""
333         while [ "$#" -gt 0 ]; do
334                 case "$1" in
335                 -C)
336                         shift
337                         dir="$1"
338                         ;;
339                 -s)
340                         silent=1
341                         ;;
342                 -a)
343                         require_static=1
344                         ;;
345                 -so)
346                         require_shared=1
347                         ;;
348                 -*)
349                         oefatal "oe_libinstall: unknown option: $1"
350                         ;;
351                 *)
352                         break;
353                         ;;
354                 esac
355                 shift
356         done
357
358         libname="$1"
359         shift
360         destpath="$1"
361         if [ -z "$destpath" ]; then
362                 oefatal "oe_libinstall: no destination path specified"
363         fi
364         if echo "$destpath/" | egrep '^${STAGING_LIBDIR}/' >/dev/null
365         then
366                 staging_install=1
367         fi
368
369         __runcmd () {
370                 if [ -z "$silent" ]; then
371                         echo >&2 "oe_libinstall: $*"
372                 fi
373                 $*
374         }
375
376         if [ -z "$dir" ]; then
377                 dir=`pwd`
378         fi
379
380         dotlai=$libname.lai
381
382         # Sanity check that the libname.lai is unique
383         number_of_files=`(cd $dir; find . -name "$dotlai") | wc -l`
384         if [ $number_of_files -gt 1 ]; then
385                 oefatal "oe_libinstall: $dotlai is not unique in $dir"
386         fi
387
388
389         dir=$dir`(cd $dir;find . -name "$dotlai") | sed "s/^\.//;s/\/$dotlai\$//;q"`
390         olddir=`pwd`
391         __runcmd cd $dir
392
393         lafile=$libname.la
394
395         # If such file doesn't exist, try to cut version suffix
396         if [ ! -f "$lafile" ]; then
397                 libname1=`echo "$libname" | sed 's/-[0-9.]*$//'`
398                 lafile1=$libname.la
399                 if [ -f "$lafile1" ]; then
400                         libname=$libname1
401                         lafile=$lafile1
402                 fi
403         fi
404
405         if [ -f "$lafile" ]; then
406                 # libtool archive
407                 eval `cat $lafile|grep "^library_names="`
408                 libtool=1
409         else
410                 library_names="$libname.so* $libname.dll.a"
411         fi
412
413         __runcmd install -d $destpath/
414         dota=$libname.a
415         if [ -f "$dota" -o -n "$require_static" ]; then
416                 __runcmd install -m 0644 $dota $destpath/
417         fi
418         if [ -f "$dotlai" -a -n "$libtool" ]; then
419                 if test -n "$staging_install"
420                 then
421                         # stop libtool using the final directory name for libraries
422                         # in staging:
423                         __runcmd rm -f $destpath/$libname.la
424                         __runcmd sed -e 's/^installed=yes$/installed=no/' \
425                                      -e '/^dependency_libs=/s,${WORKDIR}[[:alnum:]/\._+-]*/\([[:alnum:]\._+-]*\),${STAGING_LIBDIR}/\1,g' \
426                                      -e "/^dependency_libs=/s,\([[:space:]']\)${libdir},\1${STAGING_LIBDIR},g" \
427                                      $dotlai >$destpath/$libname.la
428                 else
429                         __runcmd install -m 0644 $dotlai $destpath/$libname.la
430                 fi
431         fi
432
433         for name in $library_names; do
434                 files=`eval echo $name`
435                 for f in $files; do
436                         if [ ! -e "$f" ]; then
437                                 if [ -n "$libtool" ]; then
438                                         oefatal "oe_libinstall: $dir/$f not found."
439                                 fi
440                         elif [ -L "$f" ]; then
441                                 __runcmd cp -P "$f" $destpath/
442                         elif [ ! -L "$f" ]; then
443                                 libfile="$f"
444                                 __runcmd install -m 0755 $libfile $destpath/
445                         fi
446                 done
447         done
448
449         if [ -z "$libfile" ]; then
450                 if  [ -n "$require_shared" ]; then
451                         oefatal "oe_libinstall: unable to locate shared library"
452                 fi
453         elif [ -z "$libtool" ]; then
454                 # special case hack for non-libtool .so.#.#.# links
455                 baselibfile=`basename "$libfile"`
456                 if (echo $baselibfile | grep -qE '^lib.*\.so\.[0-9.]*$'); then
457                         sonamelink=`${HOST_PREFIX}readelf -d $libfile |grep 'Library soname:' |sed -e 's/.*\[\(.*\)\].*/\1/'`
458                         solink=`echo $baselibfile | sed -e 's/\.so\..*/.so/'`
459                         if [ -n "$sonamelink" -a x"$baselibfile" != x"$sonamelink" ]; then
460                                 __runcmd ln -sf $baselibfile $destpath/$sonamelink
461                         fi
462                         __runcmd ln -sf $baselibfile $destpath/$solink
463                 fi
464         fi
465
466         __runcmd cd "$olddir"
467 }
468
469 oe_machinstall() {
470         # Purpose: Install machine dependent files, if available
471         #          If not available, check if there is a default
472         #          If no default, just touch the destination
473         # Example:
474         #                $1  $2   $3         $4
475         # oe_machinstall -m 0644 fstab ${D}/etc/fstab
476         #
477         # TODO: Check argument number?
478         #
479         filename=`basename $3`
480         dirname=`dirname $3`
481
482         for o in `echo ${OVERRIDES} | tr ':' ' '`; do
483                 if [ -e $dirname/$o/$filename ]; then
484                         oenote $dirname/$o/$filename present, installing to $4
485                         install $1 $2 $dirname/$o/$filename $4
486                         return
487                 fi
488         done
489 #       oenote overrides specific file NOT present, trying default=$3...
490         if [ -e $3 ]; then
491                 oenote $3 present, installing to $4
492                 install $1 $2 $3 $4
493         else
494                 oenote $3 NOT present, touching empty $4
495                 touch $4
496         fi
497 }
498
499 def check_app_exists(app, d):
500         from bb import which, data
501
502         app = data.expand(app, d)
503         path = data.getVar('PATH', d, 1)
504         return len(which(path, app)) != 0
505
506 def explode_deps(s):
507         return bb.utils.explode_deps(s)
508
509 def base_set_filespath(path, d):
510         bb.note("base_set_filespath usage is deprecated, %s should be fixed" % d.getVar("P", 1))
511         filespath = []
512         # The ":" ensures we have an 'empty' override
513         overrides = (bb.data.getVar("OVERRIDES", d, 1) or "") + ":"
514         for p in path:
515                 for o in overrides.split(":"):
516                         filespath.append(os.path.join(p, o))
517         return ":".join(filespath)