packages/tuxbox/tuxbox-image-info.bb: update to 2.8.1
[vuplus_openembedded] / classes / package.bbclass
1 def legitimize_package_name(s):
2         import re
3
4         def fixutf(m):
5                 cp = m.group(1)
6                 if cp:
7                         return ('\u%s' % cp).decode('unicode_escape').encode('utf-8')
8
9         # Handle unicode codepoints encoded as <U0123>, as in glibc locale files.
10         s = re.sub('<U([0-9A-Fa-f]{1,4})>', fixutf, s)
11
12         # Remaining package name validity fixes
13         return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')
14
15 STAGING_PKGMAPS_DIR ?= "${STAGING_DIR}/pkgmaps"
16
17 def add_package_mapping (pkg, new_name, d):
18         import bb, os
19
20         def encode(str):
21                 import codecs
22                 c = codecs.getencoder("string_escape")
23                 return c(str)[0]
24
25         pmap_dir = bb.data.getVar('STAGING_PKGMAPS_DIR', d, 1)
26
27         bb.mkdirhier(pmap_dir)
28
29         data_file = os.path.join(pmap_dir, pkg)
30
31         f = open(data_file, 'w')
32         f.write("%s\n" % encode(new_name))
33         f.close()
34
35 def get_package_mapping (pkg, d):
36         import bb, os
37
38         def decode(str):
39                 import codecs
40                 c = codecs.getdecoder("string_escape")
41                 return c(str)[0]
42
43         data_file = bb.data.expand("${STAGING_PKGMAPS_DIR}/%s" % pkg, d)
44
45         if os.access(data_file, os.R_OK):
46                 f = file(data_file, 'r')
47                 lines = f.readlines()
48                 f.close()
49                 for l in lines:
50                         return decode(l).strip()
51         return pkg
52
53 def runtime_mapping_rename (varname, d):
54         import bb, os
55
56         #bb.note("%s before: %s" % (varname, bb.data.getVar(varname, d, 1)))    
57
58         new_depends = []
59         for depend in explode_deps(bb.data.getVar(varname, d, 1) or ""):
60                 # Have to be careful with any version component of the depend
61                 split_depend = depend.split(' (')
62                 new_depend = get_package_mapping(split_depend[0].strip(), d)
63                 if len(split_depend) > 1:
64                         new_depends.append("%s (%s" % (new_depend, split_depend[1]))
65                 else:
66                         new_depends.append(new_depend)
67
68         bb.data.setVar(varname, " ".join(new_depends) or None, d)
69
70         #bb.note("%s after: %s" % (varname, bb.data.getVar(varname, d, 1)))
71
72 python package_mapping_rename_hook () {
73         runtime_mapping_rename("RDEPENDS", d)
74         runtime_mapping_rename("RRECOMMENDS", d)
75         runtime_mapping_rename("RSUGGESTS", d)
76         runtime_mapping_rename("RPROVIDES", d)
77         runtime_mapping_rename("RREPLACES", d)
78         runtime_mapping_rename("RCONFLICTS", d)
79 }
80
81
82 def do_split_packages(d, root, file_regex, output_pattern, description, postinst=None, recursive=False, hook=None, extra_depends=None, aux_files_pattern=None, postrm=None, allow_dirs=False, prepend=False, match_path=False, aux_files_pattern_verbatim=None):
83         import os, os.path, bb
84
85         dvar = bb.data.getVar('D', d, 1)
86         if not dvar:
87                 bb.error("D not defined")
88                 return
89
90         packages = bb.data.getVar('PACKAGES', d, 1).split()
91         if not packages:
92                 # nothing to do
93                 return
94
95         if postinst:
96                 postinst = '#!/bin/sh\n' + postinst + '\n'
97         if postrm:
98                 postrm = '#!/bin/sh\n' + postrm + '\n'
99         if not recursive:
100                 objs = os.listdir(dvar + root)
101         else:
102                 objs = []
103                 for walkroot, dirs, files in os.walk(dvar + root):
104                         for file in files:
105                                 relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1)
106                                 if relpath:
107                                         objs.append(relpath)
108
109         if extra_depends == None:
110                 extra_depends = bb.data.getVar('PKG_' + packages[1], d, 1) or packages[1]
111
112         for o in objs:
113                 import re, stat
114                 if match_path:
115                         m = re.match(file_regex, o)
116                 else:
117                         m = re.match(file_regex, os.path.basename(o))
118                 
119                 if not m:
120                         continue
121                 f = os.path.join(dvar + root, o)
122                 mode = os.lstat(f).st_mode
123                 if not (stat.S_ISREG(mode) or stat.S_ISLNK(mode) or (allow_dirs and stat.S_ISDIR(mode))):
124                         continue
125                 on = legitimize_package_name(m.group(1))
126                 pkg = output_pattern % on
127                 if not pkg in packages:
128                         if prepend:
129                                 packages = [pkg] + packages
130                         else:
131                                 packages.append(pkg)
132                         the_files = [os.path.join(root, o)]
133                         if aux_files_pattern:
134                                 if type(aux_files_pattern) is list:
135                                         for fp in aux_files_pattern:
136                                                 the_files.append(fp % on)       
137                                 else:
138                                         the_files.append(aux_files_pattern % on)
139                         if aux_files_pattern_verbatim:
140                                 if type(aux_files_pattern_verbatim) is list:
141                                         for fp in aux_files_pattern_verbatim:
142                                                 the_files.append(fp % m.group(1))       
143                                 else:
144                                         the_files.append(aux_files_pattern_verbatim % m.group(1))
145                         bb.data.setVar('FILES_' + pkg, " ".join(the_files), d)
146                         if extra_depends != '':
147                                 the_depends = bb.data.getVar('RDEPENDS_' + pkg, d, 1)
148                                 if the_depends:
149                                         the_depends = '%s %s' % (the_depends, extra_depends)
150                                 else:
151                                         the_depends = extra_depends
152                                 bb.data.setVar('RDEPENDS_' + pkg, the_depends, d)
153                         bb.data.setVar('DESCRIPTION_' + pkg, description % on, d)
154                         if postinst:
155                                 bb.data.setVar('pkg_postinst_' + pkg, postinst, d)
156                         if postrm:
157                                 bb.data.setVar('pkg_postrm_' + pkg, postrm, d)
158                 else:
159                         oldfiles = bb.data.getVar('FILES_' + pkg, d, 1)
160                         if not oldfiles:
161                                 bb.fatal("Package '%s' exists but has no files" % pkg)
162                         bb.data.setVar('FILES_' + pkg, oldfiles + " " + os.path.join(root, o), d)
163                 if callable(hook):
164                         hook(f, pkg, file_regex, output_pattern, m.group(1))
165
166         bb.data.setVar('PACKAGES', ' '.join(packages), d)
167
168 # Function to strip a single file, called from RUNSTRIP below
169 # A working 'file' (one which works on the target architecture)
170 # is necessary for this stuff to work.
171 PACKAGE_DEPENDS ?= "file-native"
172 DEPENDS_prepend =+ "${PACKAGE_DEPENDS} "
173 # file(1) output to match to consider a file an unstripped executable
174 FILE_UNSTRIPPED_MATCH ?= "not stripped"
175 #FIXME: this should be "" when any errors are gone!
176 IGNORE_STRIP_ERRORS ?= "1"
177
178 runstrip() {
179         local ro st
180         st=0
181         if {    file "$1" || {
182                         oewarn "file $1: failed (forced strip)" >&2
183                         echo '${FILE_UNSTRIPPED_MATCH}'
184                 }
185            } | grep -q '${FILE_UNSTRIPPED_MATCH}'
186         then
187                 oenote "${STRIP} $1"
188                 ro=
189                 test -w "$1" || {
190                         ro=1
191                         chmod +w "$1"
192                 }
193                 mkdir -p $(dirname "$1")/.debug
194                 debugfile="$(dirname "$1")/.debug/$(basename "$1")"
195                 '${OBJCOPY}' --only-keep-debug "$1" "$debugfile"
196                 '${STRIP}' "$1"
197                 st=$?
198                 '${OBJCOPY}' --add-gnu-debuglink="$debugfile" "$1"
199                 test -n "$ro" && chmod -w "$1"
200                 if test $st -ne 0
201                 then
202                         oewarn "runstrip: ${STRIP} $1: strip failed" >&2
203                         if [ x${IGNORE_STRIP_ERRORS} == x1 ]
204                         then
205                                 #FIXME: remove this, it's for error detection
206                                 if file "$1" 2>/dev/null >&2
207                                 then
208                                         (oefatal "${STRIP} $1: command failed" >/dev/tty)
209                                 else
210                                         (oefatal "file $1: command failed" >/dev/tty)
211                                 fi
212                                 st=0
213                         fi
214                 fi
215         else
216                 oenote "runstrip: skip $1"
217         fi
218         return $st
219 }
220
221 python populate_packages () {
222         import glob, stat, errno, re
223
224         workdir = bb.data.getVar('WORKDIR', d, 1)
225         if not workdir:
226                 bb.error("WORKDIR not defined, unable to package")
227                 return
228
229         import os # path manipulations
230         outdir = bb.data.getVar('DEPLOY_DIR', d, 1)
231         if not outdir:
232                 bb.error("DEPLOY_DIR not defined, unable to package")
233                 return
234         bb.mkdirhier(outdir)
235
236         dvar = bb.data.getVar('D', d, 1)
237         if not dvar:
238                 bb.error("D not defined, unable to package")
239                 return
240         bb.mkdirhier(dvar)
241
242         packages = bb.data.getVar('PACKAGES', d, 1)
243         if not packages:
244                 bb.debug(1, "PACKAGES not defined, nothing to package")
245                 return
246
247         pn = bb.data.getVar('PN', d, 1)
248         if not pn:
249                 bb.error("PN not defined")
250                 return
251
252         os.chdir(dvar)
253
254         def isexec(path):
255                 try:
256                         s = os.stat(path)
257                 except (os.error, AttributeError):
258                         return 0
259                 return (s[stat.ST_MODE] & stat.S_IEXEC)
260
261         # Sanity check PACKAGES for duplicates - should be moved to 
262         # sanity.bbclass once we have the infrastucture
263         package_list = []
264         for pkg in packages.split():
265                 if pkg in package_list:
266                         bb.error("-------------------")
267                         bb.error("%s is listed in PACKAGES mutliple times, this leads to packaging errors." % pkg)
268                         bb.error("Please fix the metadata/report this as bug to OE bugtracker.")
269                         bb.error("-------------------")
270                 else:
271                         package_list.append(pkg)
272
273         if (bb.data.getVar('INHIBIT_PACKAGE_STRIP', d, 1) != '1'):
274                 stripfunc = ""
275                 for root, dirs, files in os.walk(dvar):
276                         for f in files:
277                                 file = os.path.join(root, f)
278                                 if not os.path.islink(file) and isexec(file):
279                                         stripfunc += "\trunstrip %s || st=1\n" % (file)
280                 if not stripfunc == "":
281                         from bb import build
282                         localdata = bb.data.createCopy(d)
283                         # strip
284                         bb.data.setVar('RUNSTRIP', '\tlocal st\n\tst=0\n%s\treturn $st' % stripfunc, localdata)
285                         bb.data.setVarFlag('RUNSTRIP', 'func', 1, localdata)
286                         bb.build.exec_func('RUNSTRIP', localdata)
287
288         for pkg in package_list:
289                 localdata = bb.data.createCopy(d)
290                 root = os.path.join(workdir, "install", pkg)
291
292                 os.system('rm -rf %s' % root)
293
294                 bb.data.setVar('ROOT', '', localdata)
295                 bb.data.setVar('ROOT_%s' % pkg, root, localdata)
296                 pkgname = bb.data.getVar('PKG_%s' % pkg, localdata, 1)
297                 if not pkgname:
298                         pkgname = pkg
299                 bb.data.setVar('PKG', pkgname, localdata)
300
301                 overrides = bb.data.getVar('OVERRIDES', localdata, 1)
302                 if not overrides:
303                         raise bb.build.FuncFailed('OVERRIDES not defined')
304                 bb.data.setVar('OVERRIDES', overrides+':'+pkg, localdata)
305
306                 bb.data.update_data(localdata)
307
308                 root = bb.data.getVar('ROOT', localdata, 1)
309                 bb.mkdirhier(root)
310                 filesvar = bb.data.getVar('FILES', localdata, 1) or ""
311                 files = filesvar.split()
312                 for file in files:
313                         if os.path.isabs(file):
314                                 file = '.' + file
315                         if not os.path.islink(file):
316                                 if os.path.isdir(file):
317                                         newfiles =  [ os.path.join(file,x) for x in os.listdir(file) ]
318                                         if newfiles:
319                                                 files += newfiles
320                                                 continue
321                         globbed = glob.glob(file)
322                         if globbed:
323                                 if [ file ] != globbed:
324                                         files += globbed
325                                         continue
326                         if (not os.path.islink(file)) and (not os.path.exists(file)):
327                                 continue
328                         if file.find('.pyo') != -1:
329                                 continue
330                         fpath = os.path.join(root,file)
331                         dpath = os.path.dirname(fpath)
332                         bb.mkdirhier(dpath)
333                         ret = bb.movefile(file,fpath)
334                         if ret is None or ret == 0:
335                                 raise bb.build.FuncFailed("File population failed")
336                 del localdata
337         os.chdir(workdir)
338
339         unshipped = []
340         for root, dirs, files in os.walk(dvar):
341                 for f in files:
342                         path = os.path.join(root[len(dvar):], f)
343                         unshipped.append(path)
344
345         if unshipped != []:
346                 bb.note("the following files were installed but not shipped in any package:")
347                 for f in unshipped:
348                         bb.note("  " + f)
349
350         bb.build.exec_func("package_name_hook", d)
351
352         for pkg in package_list:
353                 pkgname = bb.data.getVar('PKG_%s' % pkg, d, 1)
354                 if pkgname is None:
355                         bb.data.setVar('PKG_%s' % pkg, pkg, d)
356                 else:
357                         add_package_mapping(pkg, pkgname, d)
358
359         dangling_links = {}
360         pkg_files = {}
361         for pkg in package_list:
362                 dangling_links[pkg] = []
363                 pkg_files[pkg] = []
364                 inst_root = os.path.join(workdir, "install", pkg)
365                 for root, dirs, files in os.walk(inst_root):
366                         for f in files:
367                                 path = os.path.join(root, f)
368                                 rpath = path[len(inst_root):]
369                                 pkg_files[pkg].append(rpath)
370                                 try:
371                                         s = os.stat(path)
372                                 except OSError, (err, strerror):
373                                         if err != errno.ENOENT:
374                                                 raise
375                                         target = os.readlink(path)
376                                         if target[0] != '/':
377                                                 target = os.path.join(root[len(inst_root):], target)
378                                         dangling_links[pkg].append(os.path.normpath(target))
379
380         for pkg in package_list:
381                 rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "")
382                 for l in dangling_links[pkg]:
383                         found = False
384                         bb.debug(1, "%s contains dangling link %s" % (pkg, l))
385                         for p in package_list:
386                                 for f in pkg_files[p]:
387                                         if f == l:
388                                                 found = True
389                                                 bb.debug(1, "target found in %s" % p)
390                                                 if p == pkg:
391                                                         break
392                                                 dp = bb.data.getVar('PKG_' + p, d, 1) or p
393                                                 if not dp in rdepends:
394                                                         rdepends.append(dp)
395                                                 break
396                         if found == False:
397                                 bb.note("%s contains dangling symlink to %s" % (pkg, l))
398                 bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d)
399
400         def write_if_exists(f, pkg, var):
401                 def encode(str):
402                         import codecs
403                         c = codecs.getencoder("string_escape")
404                         return c(str)[0]
405
406                 val = bb.data.getVar('%s_%s' % (var, pkg), d, 1)
407                 if val:
408                         f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
409
410         data_file = os.path.join(workdir, "install", pn + ".package")
411         f = open(data_file, 'w')
412         f.write("PACKAGES: %s\n" % packages)
413         for pkg in package_list:
414                 write_if_exists(f, pkg, 'DESCRIPTION')
415                 write_if_exists(f, pkg, 'RDEPENDS')
416                 write_if_exists(f, pkg, 'RPROVIDES')
417                 write_if_exists(f, pkg, 'PKG')
418                 write_if_exists(f, pkg, 'ALLOW_EMPTY')
419                 write_if_exists(f, pkg, 'FILES')
420                 write_if_exists(f, pkg, 'pkg_postinst')
421                 write_if_exists(f, pkg, 'pkg_postrm')
422                 write_if_exists(f, pkg, 'pkg_preinst')
423                 write_if_exists(f, pkg, 'pkg_prerm')
424         f.close()
425         bb.build.exec_func("read_subpackage_metadata", d)
426 }
427
428 ldconfig_postinst_fragment() {
429 if [ x"$D" = "x" ]; then
430         ldconfig
431 fi
432 }
433
434 python package_do_shlibs() {
435         import os, re, os.path
436
437         exclude_shlibs = bb.data.getVar('EXCLUDE_FROM_SHLIBS', d, 0)
438         if exclude_shlibs:
439                 bb.note("not generating shlibs")
440                 return
441                 
442         lib_re = re.compile("^lib.*\.so")
443         libdir_re = re.compile(".*/lib$")
444
445         packages = bb.data.getVar('PACKAGES', d, 1)
446         if not packages:
447                 bb.debug(1, "no packages to build; not calculating shlibs")
448                 return
449
450         workdir = bb.data.getVar('WORKDIR', d, 1)
451         if not workdir:
452                 bb.error("WORKDIR not defined")
453                 return
454
455         staging = bb.data.getVar('STAGING_DIR', d, 1)
456         if not staging:
457                 bb.error("STAGING_DIR not defined")
458                 return
459
460         ver = bb.data.getVar('PV', d, 1)
461         if not ver:
462                 bb.error("PV not defined")
463                 return
464
465         target_sys = bb.data.getVar('TARGET_SYS', d, 1)
466         if not target_sys:
467                 bb.error("TARGET_SYS not defined")
468                 return
469
470         shlibs_dir = os.path.join(staging, target_sys, "shlibs")
471         old_shlibs_dir = os.path.join(staging, "shlibs")
472         bb.mkdirhier(shlibs_dir)
473
474         needed = {}
475         for pkg in packages.split():
476                 needs_ldconfig = False
477                 bb.debug(2, "calculating shlib provides for %s" % pkg)
478
479                 pkgname = bb.data.getVar('PKG_%s' % pkg, d, 1)
480                 if not pkgname:
481                         pkgname = pkg
482
483                 needed[pkg] = []
484                 sonames = list()
485                 top = os.path.join(workdir, "install", pkg)
486                 for root, dirs, files in os.walk(top):
487                         for file in files:
488                                 soname = None
489                                 path = os.path.join(root, file)
490                                 if os.access(path, os.X_OK) or lib_re.match(file):
491                                         cmd = (bb.data.getVar('BUILD_PREFIX', d, 1) or "") + "objdump -p " + path + " 2>/dev/null"
492                                         fd = os.popen(cmd)
493                                         lines = fd.readlines()
494                                         fd.close()
495                                         for l in lines:
496                                                 m = re.match("\s+NEEDED\s+([^\s]*)", l)
497                                                 if m:
498                                                         needed[pkg].append(m.group(1))
499                                                 m = re.match("\s+SONAME\s+([^\s]*)", l)
500                                                 if m and not m.group(1) in sonames:
501                                                         sonames.append(m.group(1))
502                                                 if m and libdir_re.match(root):
503                                                         needs_ldconfig = True
504                 shlibs_file = os.path.join(shlibs_dir, pkgname + ".list")
505                 if os.path.exists(shlibs_file):
506                         os.remove(shlibs_file)
507                 shver_file = os.path.join(shlibs_dir, pkgname + ".ver")
508                 if os.path.exists(shver_file):
509                         os.remove(shver_file)
510                 if len(sonames):
511                         fd = open(shlibs_file, 'w')
512                         for s in sonames:
513                                 fd.write(s + '\n')
514                         fd.close()
515                         fd = open(shver_file, 'w')
516                         fd.write(ver + '\n')
517                         fd.close()
518                 if needs_ldconfig:
519                         bb.debug(1, 'adding ldconfig call to postinst for %s' % pkg)
520                         postinst = bb.data.getVar('pkg_postinst_%s' % pkg, d, 1) or bb.data.getVar('pkg_postinst', d, 1)
521                         if not postinst:
522                                 postinst = '#!/bin/sh\n'
523                         postinst += bb.data.getVar('ldconfig_postinst_fragment', d, 1)
524                         bb.data.setVar('pkg_postinst_%s' % pkg, postinst, d)
525
526         shlib_provider = {}
527         list_re = re.compile('^(.*)\.list$')
528         for dir in [old_shlibs_dir, shlibs_dir]: 
529                 if not os.path.exists(dir):
530                         continue
531                 for file in os.listdir(dir):
532                         m = list_re.match(file)
533                         if m:
534                                 dep_pkg = m.group(1)
535                                 fd = open(os.path.join(dir, file))
536                                 lines = fd.readlines()
537                                 fd.close()
538                                 ver_file = os.path.join(dir, dep_pkg + '.ver')
539                                 lib_ver = None
540                                 if os.path.exists(ver_file):
541                                         fd = open(ver_file)
542                                         lib_ver = fd.readline().rstrip()
543                                         fd.close()
544                                 for l in lines:
545                                         shlib_provider[l.rstrip()] = (dep_pkg, lib_ver)
546
547
548         for pkg in packages.split():
549                 bb.debug(2, "calculating shlib requirements for %s" % pkg)
550
551                 p_pkg = bb.data.getVar("PKG_%s" % pkg, d, 1) or pkg
552
553                 deps = list()
554                 for n in needed[pkg]:
555                         if n in shlib_provider.keys():
556                                 (dep_pkg, ver_needed) = shlib_provider[n]
557
558                                 if dep_pkg == p_pkg:
559                                         continue
560
561                                 if ver_needed:
562                                         dep = "%s (>= %s)" % (dep_pkg, ver_needed)
563                                 else:
564                                         dep = dep_pkg
565                                 if not dep in deps:
566                                         deps.append(dep)
567                         else:
568                                 bb.note("Couldn't find shared library provider for %s" % n)
569
570
571                 deps_file = os.path.join(workdir, "install", pkg + ".shlibdeps")
572                 if os.path.exists(deps_file):
573                         os.remove(deps_file)
574                 if len(deps):
575                         fd = open(deps_file, 'w')
576                         for dep in deps:
577                                 fd.write(dep + '\n')
578                         fd.close()
579 }
580
581 python package_do_pkgconfig () {
582         import re, os
583
584         packages = bb.data.getVar('PACKAGES', d, 1)
585         if not packages:
586                 bb.debug(1, "no packages to build; not calculating pkgconfig dependencies")
587                 return
588
589         workdir = bb.data.getVar('WORKDIR', d, 1)
590         if not workdir:
591                 bb.error("WORKDIR not defined")
592                 return
593
594         staging = bb.data.getVar('STAGING_DIR', d, 1)
595         if not staging:
596                 bb.error("STAGING_DIR not defined")
597                 return
598
599         target_sys = bb.data.getVar('TARGET_SYS', d, 1)
600         if not target_sys:
601                 bb.error("TARGET_SYS not defined")
602                 return
603
604         shlibs_dir = os.path.join(staging, target_sys, "shlibs")
605         old_shlibs_dir = os.path.join(staging, "shlibs")
606         bb.mkdirhier(shlibs_dir)
607
608         pc_re = re.compile('(.*)\.pc$')
609         var_re = re.compile('(.*)=(.*)')
610         field_re = re.compile('(.*): (.*)')
611
612         pkgconfig_provided = {}
613         pkgconfig_needed = {}
614         for pkg in packages.split():
615                 pkgconfig_provided[pkg] = []
616                 pkgconfig_needed[pkg] = []
617                 top = os.path.join(workdir, "install", pkg)
618                 for root, dirs, files in os.walk(top):
619                         for file in files:
620                                 m = pc_re.match(file)
621                                 if m:
622                                         pd = bb.data.init()
623                                         name = m.group(1)
624                                         pkgconfig_provided[pkg].append(name)
625                                         path = os.path.join(root, file)
626                                         if not os.access(path, os.R_OK):
627                                                 continue
628                                         f = open(path, 'r')
629                                         lines = f.readlines()
630                                         f.close()
631                                         for l in lines:
632                                                 m = var_re.match(l)
633                                                 if m:
634                                                         name = m.group(1)
635                                                         val = m.group(2)
636                                                         bb.data.setVar(name, bb.data.expand(val, pd), pd)
637                                                         continue
638                                                 m = field_re.match(l)
639                                                 if m:
640                                                         hdr = m.group(1)
641                                                         exp = bb.data.expand(m.group(2), pd)
642                                                         if hdr == 'Requires':
643                                                                 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
644
645         for pkg in packages.split():
646                 ppkg = bb.data.getVar("PKG_" + pkg, d, 1) or pkg
647                 pkgs_file = os.path.join(shlibs_dir, ppkg + ".pclist")
648                 if os.path.exists(pkgs_file):
649                         os.remove(pkgs_file)
650                 if pkgconfig_provided[pkg] != []:
651                         f = open(pkgs_file, 'w')
652                         for p in pkgconfig_provided[pkg]:
653                                 f.write('%s\n' % p)
654                         f.close()
655
656         for dir in [old_shlibs_dir, shlibs_dir]:
657                 if not os.path.exists(dir):
658                         continue
659                 for file in os.listdir(dir):
660                         m = re.match('^(.*)\.pclist$', file)
661                         if m:
662                                 pkg = m.group(1)
663                                 fd = open(os.path.join(dir, file))
664                                 lines = fd.readlines()
665                                 fd.close()
666                                 pkgconfig_provided[pkg] = []
667                                 for l in lines:
668                                         pkgconfig_provided[pkg].append(l.rstrip())
669
670         for pkg in packages.split():
671                 deps = []
672                 for n in pkgconfig_needed[pkg]:
673                         found = False
674                         for k in pkgconfig_provided.keys():
675                                 if n in pkgconfig_provided[k]:
676                                         if k != pkg and not (k in deps):
677                                                 deps.append(k)
678                                         found = True
679                         if found == False:
680                                 bb.note("couldn't find pkgconfig module '%s' in any package" % n)
681                 deps_file = os.path.join(workdir, "install", pkg + ".pcdeps")
682                 if os.path.exists(deps_file):
683                         os.remove(deps_file)
684                 if len(deps):
685                         fd = open(deps_file, 'w')
686                         for dep in deps:
687                                 fd.write(dep + '\n')
688                         fd.close()
689 }
690
691 python package_do_split_locales() {
692         import os
693
694         if (bb.data.getVar('PACKAGE_NO_LOCALE', d, 1) == '1'):
695                 bb.debug(1, "package requested not splitting locales")
696                 return
697
698         packages = (bb.data.getVar('PACKAGES', d, 1) or "").split()
699         if not packages:
700                 bb.debug(1, "no packages to build; not splitting locales")
701                 return
702
703         datadir = bb.data.getVar('datadir', d, 1)
704         if not datadir:
705                 bb.note("datadir not defined")
706                 return
707
708         dvar = bb.data.getVar('D', d, 1)
709         if not dvar:
710                 bb.error("D not defined")
711                 return
712
713         pn = bb.data.getVar('PN', d, 1)
714         if not pn:
715                 bb.error("PN not defined")
716                 return
717
718         if pn + '-locale' in packages:
719                 packages.remove(pn + '-locale')
720
721         localedir = os.path.join(dvar + datadir, 'locale')
722
723         if not os.path.isdir(localedir):
724                 bb.debug(1, "No locale files in this package")
725                 return
726
727         locales = os.listdir(localedir)
728
729         mainpkg = packages[0]
730
731         for l in locales:
732                 ln = legitimize_package_name(l)
733                 pkg = pn + '-locale-' + ln
734                 packages.append(pkg)
735                 bb.data.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l), d)
736                 bb.data.setVar('RDEPENDS_' + pkg, '${PKG_%s} virtual-locale-%s' % (mainpkg, ln), d)
737                 bb.data.setVar('RPROVIDES_' + pkg, '%s-locale %s-translation' % (pn, ln), d)
738                 bb.data.setVar('DESCRIPTION_' + pkg, '%s translation for %s' % (l, pn), d)
739
740         bb.data.setVar('PACKAGES', ' '.join(packages), d)
741
742 # we don't want to RDEPEND any package on created locales.
743 #       rdep = (bb.data.getVar('RDEPENDS_%s' % mainpkg, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "").split()
744 #       rdep.append('%s-locale*' % pn)
745 #       bb.data.setVar('RDEPENDS_%s' % mainpkg, ' '.join(rdep), d)
746 }
747
748 PACKAGEFUNCS ?= " package_do_split_locales \
749                 populate_packages package_do_shlibs \
750                 package_do_pkgconfig read_shlibdeps"
751 python package_do_package () {
752         for f in (bb.data.getVar('PACKAGEFUNCS', d, 1) or '').split():
753                 bb.build.exec_func(f, d)
754 }
755
756 do_package[dirs] = "${D}"
757 # shlibs requires any DEPENDS to have already packaged for the *.list files
758 do_package[deptask] = "do_package"
759 populate_packages[dirs] = "${D}"
760 EXPORT_FUNCTIONS do_package do_shlibs do_split_locales mapping_rename_hook
761 addtask package before do_build after do_install