Enlightenment-x11 meta for building.
[vuplus_openembedded] / classes / package.oeclass
1 def legitimize_package_name(s):
2         return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-')
3
4 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):
5         import os, os.path, oe
6
7         dvar = oe.data.getVar('D', d, 1)
8         if not dvar:
9                 oe.error("D not defined")
10                 return
11
12         packages = oe.data.getVar('PACKAGES', d, 1).split()
13         if not packages:
14                 # nothing to do
15                 return
16
17         if postinst:
18                 postinst = '#!/bin/sh\n' + postinst
19         if postrm:
20                 postrm = '#!/bin/sh\n' + postrm
21         if not recursive:
22                 objs = os.listdir(dvar + root)
23         else:
24                 objs = []
25                 for walkroot, dirs, files in os.walk(dvar + root):
26                         for file in files:
27                                 relpath = os.path.join(walkroot, file).replace(dvar + root + '/', '', 1)
28                                 if relpath:
29                                         objs.append(relpath)
30
31         if extra_depends == None:
32                 extra_depends = oe.data.getVar('PKG_' + packages[0], d, 1) or packages[0]
33
34         for o in objs:
35                 import re, stat
36                 if match_path:
37                         m = re.match(file_regex, o)
38                 else:
39                         m = re.match(file_regex, os.path.basename(o))
40                 
41                 if not m:
42                         continue
43                 f = os.path.join(dvar + root, o)
44                 mode = os.lstat(f).st_mode
45                 if not (stat.S_ISREG(mode) or (allow_dirs and stat.S_ISDIR(mode))):
46                         continue
47                 on = legitimize_package_name(m.group(1))
48                 pkg = output_pattern % on
49                 if not pkg in packages:
50                         if prepend:
51                                 packages = [pkg] + packages
52                         else:
53                                 packages.append(pkg)
54                         the_files = [os.path.join(root, o)]
55                         if aux_files_pattern:
56                                 if type(aux_files_pattern) is list:
57                                         for fp in aux_files_pattern:
58                                                 the_files.append(fp % on)       
59                                 else:
60                                         the_files.append(aux_files_pattern % on)
61                         oe.data.setVar('FILES_' + pkg, " ".join(the_files), d)
62                         if extra_depends != '':
63                                 oe.data.setVar('RDEPENDS_' + pkg, extra_depends, d)
64                         oe.data.setVar('DESCRIPTION_' + pkg, description % on, d)
65                         if postinst:
66                                 oe.data.setVar('pkg_postinst_' + pkg, postinst, d)
67                         if postrm:
68                                 oe.data.setVar('pkg_postrm_' + pkg, postrm, d)
69                 else:
70                         oldfiles = oe.data.getVar('FILES_' + pkg, d, 1)
71                         if not oldfiles:
72                                 oe.fatal("Package '%s' exists but has no files" % pkg)
73                         oe.data.setVar('FILES_' + pkg, oldfiles + " " + os.path.join(root, o), d)
74                 if callable(hook):
75                         hook(f, pkg, file_regex, output_pattern, m.group(1))
76
77         oe.data.setVar('PACKAGES', ' '.join(packages), d)
78
79 def package_frob_arch(d):
80         import oe, os
81         machine = oe.data.getVar('MACHINE', d, 1)
82         if not machine:
83                 # can't specialise if MACHINE not defined
84                 return
85         old_arch = oe.data.getVar('PACKAGE_ARCH', d, 1)
86         if (old_arch == machine):
87                 # Nothing to do
88                 return
89         paths = []
90         for p in [ "${FILE_DIRNAME}/${PF}", "${FILE_DIRNAME}/${P}", "${FILE_DIRNAME}/${PN}", "${FILE_DIRNAME}/files", "${FILE_DIRNAME}" ]:
91                 paths.append(oe.data.expand(os.path.join(p, machine), d))
92         for s in oe.data.getVar('SRC_URI', d, 1).split():
93                 local = oe.data.expand(oe.fetch.localpath(s, d), d)
94                 for mp in paths:
95                         if local.startswith(mp):
96                                 oe.note("overriding PACKAGE_ARCH from %s to %s" % (old_arch, machine))
97                                 oe.data.setVar('PACKAGE_ARCH', machine, d)
98                                 return
99
100 python populate_packages () {
101         import glob, copy, stat, errno, re
102
103         workdir = oe.data.getVar('WORKDIR', d, 1)
104         if not workdir:
105                 oe.error("WORKDIR not defined, unable to package")
106                 return
107
108         import os # path manipulations
109         outdir = oe.data.getVar('DEPLOY_DIR', d, 1)
110         if not outdir:
111                 oe.error("DEPLOY_DIR not defined, unable to package")
112                 return
113         oe.mkdirhier(outdir)
114
115         dvar = oe.data.getVar('D', d, 1)
116         if not dvar:
117                 oe.error("D not defined, unable to package")
118                 return
119         oe.mkdirhier(dvar)
120
121         packages = oe.data.getVar('PACKAGES', d, 1)
122         if not packages:
123                 oe.debug(1, "PACKAGES not defined, nothing to package")
124                 return
125
126         pn = oe.data.getVar('PN', d, 1)
127         if not pn:
128                 oe.error("PN not defined")
129                 return
130
131         package_frob_arch(d)
132
133         os.chdir(dvar)
134
135         def isexec(path):
136                 try:
137                         s = os.stat(path)
138                 except (os.error, AttributeError):
139                         return 0
140                 return (s[stat.ST_MODE] & stat.S_IEXEC)
141
142         for pkg in packages.split():
143                 localdata = copy.deepcopy(d)
144                 root = os.path.join(workdir, "install", pkg)
145
146                 os.system('rm -rf %s' % root)
147
148                 oe.data.setVar('ROOT', '', localdata)
149                 oe.data.setVar('ROOT_%s' % pkg, root, localdata)
150                 pkgname = oe.data.getVar('PKG_%s' % pkg, localdata, 1)
151                 if not pkgname:
152                         pkgname = pkg
153                 oe.data.setVar('PKG', pkgname, localdata)
154
155                 overrides = oe.data.getVar('OVERRIDES', localdata, 1)
156                 if not overrides:
157                         raise oe.build.FuncFailed('OVERRIDES not defined')
158                 oe.data.setVar('OVERRIDES', overrides+':'+pkg, localdata)
159
160                 oe.data.update_data(localdata)
161
162                 root = oe.data.getVar('ROOT', localdata, 1)
163                 oe.mkdirhier(root)
164                 filesvar = oe.data.getVar('FILES', localdata, 1) or ""
165                 files = filesvar.split()
166                 stripfunc = ""
167                 for file in files:
168                         if os.path.isabs(file):
169                                 file = '.' + file
170                         if not os.path.islink(file):
171                                 if os.path.isdir(file):
172                                         newfiles =  [ os.path.join(file,x) for x in os.listdir(file) ]
173                                         if newfiles:
174                                                 files += newfiles
175                                                 continue
176                         globbed = glob.glob(file)
177                         if globbed:
178                                 if [ file ] != globbed:
179                                         files += globbed
180                                         continue
181                         if (not os.path.islink(file)) and (not os.path.exists(file)):
182                                 continue
183                         fpath = os.path.join(root,file)
184                         dpath = os.path.dirname(fpath)
185                         oe.mkdirhier(dpath)
186                         if (oe.data.getVar('INHIBIT_PACKAGE_STRIP', d, 1) != '1') and not os.path.islink(file) and isexec(file):
187                                 stripfunc += "${STRIP} %s || : ;\n" % fpath
188                         ret = oe.movefile(file,fpath)
189                         if ret is None or ret == 0:
190                                 raise oe.build.FuncFailed("File population failed")
191                 if not stripfunc == "":
192                         from oe import build
193                         # strip
194                         oe.data.setVar('RUNSTRIP', '%s\nreturn 0' % stripfunc, localdata)
195                         oe.data.setVarFlag('RUNSTRIP', 'func', 1, localdata)
196                         oe.build.exec_func('RUNSTRIP', localdata)
197                 del localdata
198         os.chdir(workdir)
199
200         unshipped = []
201         for root, dirs, files in os.walk(dvar):
202                 for f in files:
203                         path = os.path.join(root[len(dvar):], f)
204                         unshipped.append(path)
205
206         if unshipped != []:
207                 oe.note("the following files were installed but not shipped in any package:")
208                 for f in unshipped:
209                         oe.note("  " + f)
210
211         oe.build.exec_func("package_name_hook", d)
212
213         for pkg in packages.split():
214                 if oe.data.getVar('PKG_%s' % pkg, d, 1) is None:
215                         oe.data.setVar('PKG_%s' % pkg, pkg, d)
216
217         dangling_links = {}
218         pkg_files = {}
219         for pkg in packages.split():
220                 dangling_links[pkg] = []
221                 pkg_files[pkg] = []
222                 inst_root = os.path.join(workdir, "install", pkg)
223                 for root, dirs, files in os.walk(inst_root):
224                         for f in files:
225                                 path = os.path.join(root, f)
226                                 rpath = path[len(inst_root):]
227                                 pkg_files[pkg].append(rpath)
228                                 try:
229                                         s = os.stat(path)
230                                 except OSError, (err, strerror):
231                                         if err != errno.ENOENT:
232                                                 raise
233                                         target = os.readlink(path)
234                                         if target[0] != '/':
235                                                 target = os.path.join(root[len(inst_root):], target)
236                                         dangling_links[pkg].append(os.path.normpath(target))
237
238         for pkg in packages.split():
239                 rdepends = explode_deps(oe.data.getVar('RDEPENDS_' + pkg, d, 1) or oe.data.getVar('RDEPENDS', d, 1) or "")
240                 for l in dangling_links[pkg]:
241                         found = False
242                         oe.debug(1, "%s contains dangling link %s" % (pkg, l))
243                         for p in packages.split():
244                                 for f in pkg_files[p]:
245                                         if f == l:
246                                                 found = True
247                                                 oe.debug(1, "target found in %s" % p)
248                                                 dp = oe.data.getVar('PKG_' + p, d, 1) or p
249                                                 if not dp in rdepends:
250                                                         rdepends.append(dp)
251                                                 break
252                         if found == False:
253                                 oe.note("%s contains dangling symlink to %s" % (pkg, l))
254                 oe.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d)
255
256         def write_if_exists(f, pkg, var):
257                 def encode(str):
258                         import codecs
259                         c = codecs.getencoder("string_escape")
260                         return c(str)[0]
261
262                 val = oe.data.getVar('%s_%s' % (var, pkg), d, 1)
263                 if val:
264                         f.write('%s_%s: %s\n' % (var, pkg, encode(val)))
265
266         data_file = os.path.join(workdir, "install", pn + ".package")
267         f = open(data_file, 'w')
268         f.write("PACKAGES: %s\n" % packages)
269         for pkg in packages.split():
270                 write_if_exists(f, pkg, 'DESCRIPTION')
271                 write_if_exists(f, pkg, 'RDEPENDS')
272                 write_if_exists(f, pkg, 'RPROVIDES')
273                 write_if_exists(f, pkg, 'PKG')
274                 write_if_exists(f, pkg, 'ALLOW_EMPTY')
275                 write_if_exists(f, pkg, 'FILES')
276                 write_if_exists(f, pkg, 'pkg_postinst')
277                 write_if_exists(f, pkg, 'pkg_postrm')
278         f.close()
279         oe.build.exec_func("read_subpackage_metadata", d)
280 }
281
282 ldconfig_postinst_fragment() {
283 if [ x"$D" = "x" ]; then
284         ldconfig
285 fi
286 }
287
288 python package_do_shlibs() {
289         import os, re, os.path
290
291         lib_re = re.compile("^lib.*\.so")
292         libdir_re = re.compile(".*/lib$")
293
294         packages = oe.data.getVar('PACKAGES', d, 1)
295         if not packages:
296                 oe.debug(1, "no packages to build; not calculating shlibs")
297                 return
298
299         workdir = oe.data.getVar('WORKDIR', d, 1)
300         if not workdir:
301                 oe.error("WORKDIR not defined")
302                 return
303
304         staging = oe.data.getVar('STAGING_DIR', d, 1)
305         if not staging:
306                 oe.error("STAGING_DIR not defined")
307                 return
308
309         ver = oe.data.getVar('PV', d, 1)
310         if not ver:
311                 oe.error("PV not defined")
312                 return
313
314         target_sys = oe.data.getVar('TARGET_SYS', d, 1)
315         if not target_sys:
316                 oe.error("TARGET_SYS not defined")
317                 return
318
319         shlibs_dir = os.path.join(staging, target_sys, "shlibs")
320         old_shlibs_dir = os.path.join(staging, "shlibs")
321         oe.mkdirhier(shlibs_dir)
322
323         needed = {}
324         for pkg in packages.split():
325                 needs_ldconfig = False
326                 oe.debug(2, "calculating shlib provides for %s" % pkg)
327
328                 pkgname = oe.data.getVar('PKG_%s' % pkg, d, 1)
329                 if not pkgname:
330                         pkgname = pkg
331
332                 needed[pkg] = []
333                 sonames = list()
334                 top = os.path.join(workdir, "install", pkg)
335                 for root, dirs, files in os.walk(top):
336                         for file in files:
337                                 soname = None
338                                 path = os.path.join(root, file)
339                                 if os.access(path, os.X_OK) or lib_re.match(file):
340                                         cmd = (oe.data.getVar('BUILD_PREFIX', d, 1) or "") + "objdump -p " + path + " 2>/dev/null"
341                                         fd = os.popen(cmd)
342                                         lines = fd.readlines()
343                                         fd.close()
344                                         for l in lines:
345                                                 m = re.match("\s+NEEDED\s+([^\s]*)", l)
346                                                 if m:
347                                                         needed[pkg].append(m.group(1))
348                                                 m = re.match("\s+SONAME\s+([^\s]*)", l)
349                                                 if m and not m.group(1) in sonames:
350                                                         sonames.append(m.group(1))
351                                                 if m and libdir_re.match(root):
352                                                         needs_ldconfig = True
353                 shlibs_file = os.path.join(shlibs_dir, pkgname + ".list")
354                 if os.path.exists(shlibs_file):
355                         os.remove(shlibs_file)
356                 shver_file = os.path.join(shlibs_dir, pkgname + ".ver")
357                 if os.path.exists(shver_file):
358                         os.remove(shver_file)
359                 if len(sonames):
360                         fd = open(shlibs_file, 'w')
361                         for s in sonames:
362                                 fd.write(s + '\n')
363                         fd.close()
364                         fd = open(shver_file, 'w')
365                         fd.write(ver + '\n')
366                         fd.close()
367                 if needs_ldconfig:
368                         oe.note('adding ldconfig call to postinst for %s' % pkg)
369                         postinst = oe.data.getVar('pkg_postinst_%s' % pkg, d, 1) or oe.data.getVar('pkg_postinst', d, 1)
370                         if not postinst:
371                                 postinst = '#!/bin/sh\n'
372                         postinst += oe.data.getVar('ldconfig_postinst_fragment', d, 1)
373                         oe.data.setVar('pkg_postinst_%s' % pkg, postinst, d)
374
375         shlib_provider = {}
376         list_re = re.compile('^(.*)\.list$')
377         for dir in [shlibs_dir, old_shlibs_dir]: 
378                 if not os.path.exists(dir):
379                         continue
380                 for file in os.listdir(dir):
381                         m = list_re.match(file)
382                         if m:
383                                 dep_pkg = m.group(1)
384                                 fd = open(os.path.join(dir, file))
385                                 lines = fd.readlines()
386                                 fd.close()
387                                 ver_file = os.path.join(dir, dep_pkg + '.ver')
388                                 lib_ver = None
389                                 if os.path.exists(ver_file):
390                                         fd = open(ver_file)
391                                         lib_ver = fd.readline().rstrip()
392                                         fd.close()
393                                 for l in lines:
394                                         shlib_provider[l.rstrip()] = (dep_pkg, lib_ver)
395
396
397         for pkg in packages.split():
398                 oe.debug(2, "calculating shlib requirements for %s" % pkg)
399
400                 deps = list()
401                 for n in needed[pkg]:
402                         if n in shlib_provider.keys():
403                                 (dep_pkg, ver_needed) = shlib_provider[n]
404
405                                 if ver_needed:
406                                         dep = "%s (>= %s)" % (dep_pkg, ver_needed)
407                                 else:
408                                         dep = dep_pkg
409                                 if not dep in deps:
410                                         deps.append(dep)
411                         else:
412                                 oe.note("Couldn't find shared library provider for %s" % n)
413
414
415                 deps_file = os.path.join(workdir, "install", pkg + ".shlibdeps")
416                 if os.path.exists(deps_file):
417                         os.remove(deps_file)
418                 if len(deps):
419                         fd = open(deps_file, 'w')
420                         for dep in deps:
421                                 fd.write(dep + '\n')
422                         fd.close()
423 }
424
425 python package_do_pkgconfig () {
426         import re, os
427
428         packages = oe.data.getVar('PACKAGES', d, 1)
429         if not packages:
430                 oe.debug(1, "no packages to build; not calculating pkgconfig dependencies")
431                 return
432
433         workdir = oe.data.getVar('WORKDIR', d, 1)
434         if not workdir:
435                 oe.error("WORKDIR not defined")
436                 return
437
438         staging = oe.data.getVar('STAGING_DIR', d, 1)
439         if not staging:
440                 oe.error("STAGING_DIR not defined")
441                 return
442
443         pc_re = re.compile('(.*)\.pc$')
444         var_re = re.compile('(.*)=(.*)')
445         field_re = re.compile('(.*): (.*)')
446
447         pkgconfig_provided = {}
448         pkgconfig_needed = {}
449         for pkg in packages.split():
450                 pkgconfig_provided[pkg] = []
451                 pkgconfig_needed[pkg] = []
452                 top = os.path.join(workdir, "install", pkg)
453                 for root, dirs, files in os.walk(top):
454                         for file in files:
455                                 m = pc_re.match(file)
456                                 if m:
457                                         pd = {}
458                                         name = m.group(1)
459                                         pkgconfig_provided[pkg].append(name)
460                                         path = os.path.join(root, file)
461                                         if not os.access(path, os.R_OK):
462                                                 continue
463                                         f = open(path, 'r')
464                                         lines = f.readlines()
465                                         f.close()
466                                         for l in lines:
467                                                 m = var_re.match(l)
468                                                 if m:
469                                                         name = m.group(1)
470                                                         val = m.group(2)
471                                                         oe.data.setVar(name, oe.data.expand(val, pd), pd)
472                                                         continue
473                                                 m = field_re.match(l)
474                                                 if m:
475                                                         hdr = m.group(1)
476                                                         exp = oe.data.expand(m.group(2), pd)
477                                                         if hdr == 'Requires':
478                                                                 pkgconfig_needed[pkg] += exp.replace(',', ' ').split()
479
480         shlibs_dir = os.path.join(staging, "shlibs")
481         oe.mkdirhier(shlibs_dir)
482
483         for pkg in packages.split():
484                 pkgs_file = os.path.join(shlibs_dir, pkg + ".pclist")
485                 if os.path.exists(pkgs_file):
486                         os.remove(pkgs_file)
487                 if pkgconfig_provided[pkg] != []:
488                         f = open(pkgs_file, 'w')
489                         for p in pkgconfig_provided[pkg]:
490                                 f.write('%s\n' % p)
491                         f.close()
492
493         for file in os.listdir(shlibs_dir):
494                 m = re.match('^(.*)\.pclist$', file)
495                 if m:
496                         pkg = m.group(1)
497                         fd = open(os.path.join(shlibs_dir, file))
498                         lines = fd.readlines()
499                         fd.close()
500                         pkgconfig_provided[pkg] = []
501                         for l in lines:
502                                 pkgconfig_provided[pkg].append(l.rstrip())
503
504         for pkg in packages.split():
505                 deps = []
506                 for n in pkgconfig_needed[pkg]:
507                         found = False
508                         for k in pkgconfig_provided.keys():
509                                 if n in pkgconfig_provided[k]:
510                                         if k != pkg and not (k in deps):
511                                                 deps.append(k)
512                                         found = True
513                         if found == False:
514                                 oe.note("couldn't find pkgconfig module '%s' in any package" % n)
515                 deps_file = os.path.join(workdir, "install", pkg + ".pcdeps")
516                 if os.path.exists(deps_file):
517                         os.remove(deps_file)
518                 if len(deps):
519                         fd = open(deps_file, 'w')
520                         for dep in deps:
521                                 fd.write(dep + '\n')
522                         fd.close()
523 }
524
525 python package_do_split_locales() {
526         import os
527
528         if (oe.data.getVar('PACKAGE_NO_LOCALE', d, 1) == '1'):
529                 oe.debug(1, "package requested not splitting locales")
530                 return
531
532         packages = (oe.data.getVar('PACKAGES', d, 1) or "").split()
533         if not packages:
534                 oe.debug(1, "no packages to build; not splitting locales")
535                 return
536
537         datadir = oe.data.getVar('datadir', d, 1)
538         if not datadir:
539                 oe.note("datadir not defined")
540                 return
541
542         dvar = oe.data.getVar('D', d, 1)
543         if not dvar:
544                 oe.error("D not defined")
545                 return
546
547         pn = oe.data.getVar('PN', d, 1)
548         if not pn:
549                 oe.error("PN not defined")
550                 return
551
552         if pn + '-locale' in packages:
553                 packages.remove(pn + '-locale')
554
555         localedir = os.path.join(dvar + datadir, 'locale')
556
557         if not os.path.isdir(localedir):
558                 oe.note("No locale files in this package")
559                 return
560
561         locales = os.listdir(localedir)
562
563         mainpkg = packages[0]
564
565         for l in locales:
566                 ln = legitimize_package_name(l)
567                 pkg = pn + '-locale-' + ln
568                 packages.append(pkg)
569                 oe.data.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l), d)
570                 oe.data.setVar('RDEPENDS_' + pkg, '${PKG_%s} virtual-locale-%s' % (mainpkg, ln), d)
571                 oe.data.setVar('RPROVIDES_' + pkg, '%s-locale %s-translation' % (pn, ln), d)
572                 oe.data.setVar('DESCRIPTION_' + pkg, '%s translation for %s' % (l, pn), d)
573
574         oe.data.setVar('PACKAGES', ' '.join(packages), d)
575
576         rrec = (oe.data.getVar('RRECOMMENDS_%s' % mainpkg, d, 1) or oe.data.getVar('RRECOMMENDS', d, 1) or "").split()
577         rrec.append('%s-locale*' % pn)
578         oe.data.setVar('RRECOMMENDS_%s' % mainpkg, ' '.join(rrec), d)
579 }
580
581 python package_do_package () {
582         oe.build.exec_func('do_install', d)
583         oe.build.exec_func('package_do_split_locales', d)
584         oe.build.exec_func('populate_packages', d)
585         oe.build.exec_func('package_do_shlibs', d)
586         oe.build.exec_func('package_do_pkgconfig', d)
587         oe.build.exec_func('read_shlibdeps', d)
588 }
589
590 do_package[dirs] = "${D}"
591 populate_packages[dirs] = "${D}"
592 EXPORT_FUNCTIONS do_package do_shlibs do_split_locales
593 addtask package before do_build after do_populate_staging