diff options
Diffstat (limited to 'meta/classes/package.bbclass')
-rw-r--r-- | meta/classes/package.bbclass | 386 |
1 files changed, 219 insertions, 167 deletions
diff --git a/meta/classes/package.bbclass b/meta/classes/package.bbclass index e2e98624ca..271c8f585c 100644 --- a/meta/classes/package.bbclass +++ b/meta/classes/package.bbclass | |||
@@ -1,4 +1,11 @@ | |||
1 | # | ||
2 | # General packaging help functions | ||
3 | # | ||
4 | |||
1 | def legitimize_package_name(s): | 5 | def legitimize_package_name(s): |
6 | """ | ||
7 | Make sure package names are legitimate strings | ||
8 | """ | ||
2 | import re | 9 | import re |
3 | 10 | ||
4 | def fixutf(m): | 11 | def fixutf(m): |
@@ -12,74 +19,11 @@ def legitimize_package_name(s): | |||
12 | # Remaining package name validity fixes | 19 | # Remaining package name validity fixes |
13 | return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-') | 20 | return s.lower().replace('_', '-').replace('@', '+').replace(',', '+').replace('/', '-') |
14 | 21 | ||
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): | 22 | 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): |
23 | """ | ||
24 | Used in .bb files to split up dynamically generated subpackages of a | ||
25 | given package, usually plugins or modules. | ||
26 | """ | ||
83 | import os, os.path, bb | 27 | import os, os.path, bb |
84 | 28 | ||
85 | dvar = bb.data.getVar('D', d, 1) | 29 | dvar = bb.data.getVar('D', d, 1) |
@@ -165,15 +109,16 @@ def do_split_packages(d, root, file_regex, output_pattern, description, postinst | |||
165 | 109 | ||
166 | bb.data.setVar('PACKAGES', ' '.join(packages), d) | 110 | bb.data.setVar('PACKAGES', ' '.join(packages), d) |
167 | 111 | ||
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" | 112 | #PACKAGE_DEPENDS ?= "file-native" |
172 | #DEPENDS_prepend =+ "${PACKAGE_DEPENDS} " | 113 | #DEPENDS_prepend =+ "${PACKAGE_DEPENDS} " |
173 | #FIXME: this should be "" when any errors are gone! | 114 | #FIXME: this should be "" when any errors are gone! |
174 | IGNORE_STRIP_ERRORS ?= "1" | 115 | IGNORE_STRIP_ERRORS ?= "1" |
175 | 116 | ||
176 | runstrip() { | 117 | runstrip() { |
118 | # Function to strip a single file, called from RUNSTRIP in populate_packages below | ||
119 | # A working 'file' (one which works on the target architecture) | ||
120 | # is necessary for this stuff to work, hence the addition to PACKAGES_DEPENDS | ||
121 | |||
177 | local ro st | 122 | local ro st |
178 | st=0 | 123 | st=0 |
179 | if { file "$1" || { | 124 | if { file "$1" || { |
@@ -216,6 +161,128 @@ runstrip() { | |||
216 | return $st | 161 | return $st |
217 | } | 162 | } |
218 | 163 | ||
164 | |||
165 | # | ||
166 | # Package data handling routines | ||
167 | # | ||
168 | |||
169 | STAGING_PKGMAPS_DIR ?= "${STAGING_DIR}/pkgmaps" | ||
170 | |||
171 | def add_package_mapping (pkg, new_name, d): | ||
172 | import bb, os | ||
173 | |||
174 | def encode(str): | ||
175 | import codecs | ||
176 | c = codecs.getencoder("string_escape") | ||
177 | return c(str)[0] | ||
178 | |||
179 | pmap_dir = bb.data.getVar('STAGING_PKGMAPS_DIR', d, 1) | ||
180 | |||
181 | bb.mkdirhier(pmap_dir) | ||
182 | |||
183 | data_file = os.path.join(pmap_dir, pkg) | ||
184 | |||
185 | f = open(data_file, 'w') | ||
186 | f.write("%s\n" % encode(new_name)) | ||
187 | f.close() | ||
188 | |||
189 | def get_package_mapping (pkg, d): | ||
190 | import bb, os | ||
191 | |||
192 | def decode(str): | ||
193 | import codecs | ||
194 | c = codecs.getdecoder("string_escape") | ||
195 | return c(str)[0] | ||
196 | |||
197 | data_file = bb.data.expand("${STAGING_PKGMAPS_DIR}/%s" % pkg, d) | ||
198 | |||
199 | if os.access(data_file, os.R_OK): | ||
200 | f = file(data_file, 'r') | ||
201 | lines = f.readlines() | ||
202 | f.close() | ||
203 | for l in lines: | ||
204 | return decode(l).strip() | ||
205 | return pkg | ||
206 | |||
207 | def runtime_mapping_rename (varname, d): | ||
208 | import bb, os | ||
209 | |||
210 | #bb.note("%s before: %s" % (varname, bb.data.getVar(varname, d, 1))) | ||
211 | |||
212 | new_depends = [] | ||
213 | for depend in explode_deps(bb.data.getVar(varname, d, 1) or ""): | ||
214 | # Have to be careful with any version component of the depend | ||
215 | split_depend = depend.split(' (') | ||
216 | new_depend = get_package_mapping(split_depend[0].strip(), d) | ||
217 | if len(split_depend) > 1: | ||
218 | new_depends.append("%s (%s" % (new_depend, split_depend[1])) | ||
219 | else: | ||
220 | new_depends.append(new_depend) | ||
221 | |||
222 | bb.data.setVar(varname, " ".join(new_depends) or None, d) | ||
223 | |||
224 | #bb.note("%s after: %s" % (varname, bb.data.getVar(varname, d, 1))) | ||
225 | |||
226 | # | ||
227 | # Package functions suitable for inclusion in PACKAGEFUNCS | ||
228 | # | ||
229 | |||
230 | python package_do_split_locales() { | ||
231 | import os | ||
232 | |||
233 | if (bb.data.getVar('PACKAGE_NO_LOCALE', d, 1) == '1'): | ||
234 | bb.debug(1, "package requested not splitting locales") | ||
235 | return | ||
236 | |||
237 | packages = (bb.data.getVar('PACKAGES', d, 1) or "").split() | ||
238 | if not packages: | ||
239 | bb.debug(1, "no packages to build; not splitting locales") | ||
240 | return | ||
241 | |||
242 | datadir = bb.data.getVar('datadir', d, 1) | ||
243 | if not datadir: | ||
244 | bb.note("datadir not defined") | ||
245 | return | ||
246 | |||
247 | dvar = bb.data.getVar('D', d, 1) | ||
248 | if not dvar: | ||
249 | bb.error("D not defined") | ||
250 | return | ||
251 | |||
252 | pn = bb.data.getVar('PN', d, 1) | ||
253 | if not pn: | ||
254 | bb.error("PN not defined") | ||
255 | return | ||
256 | |||
257 | if pn + '-locale' in packages: | ||
258 | packages.remove(pn + '-locale') | ||
259 | |||
260 | localedir = os.path.join(dvar + datadir, 'locale') | ||
261 | |||
262 | if not os.path.isdir(localedir): | ||
263 | bb.debug(1, "No locale files in this package") | ||
264 | return | ||
265 | |||
266 | locales = os.listdir(localedir) | ||
267 | |||
268 | mainpkg = packages[0] | ||
269 | |||
270 | for l in locales: | ||
271 | ln = legitimize_package_name(l) | ||
272 | pkg = pn + '-locale-' + ln | ||
273 | packages.append(pkg) | ||
274 | bb.data.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l), d) | ||
275 | bb.data.setVar('RDEPENDS_' + pkg, '%s virtual-locale-%s' % (mainpkg, ln), d) | ||
276 | bb.data.setVar('RPROVIDES_' + pkg, '%s-locale %s-translation' % (pn, ln), d) | ||
277 | bb.data.setVar('DESCRIPTION_' + pkg, '%s translation for %s' % (l, pn), d) | ||
278 | |||
279 | bb.data.setVar('PACKAGES', ' '.join(packages), d) | ||
280 | |||
281 | rdep = (bb.data.getVar('RDEPENDS_%s' % mainpkg, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "").split() | ||
282 | rdep.append('%s-locale*' % pn) | ||
283 | bb.data.setVar('RDEPENDS_%s' % mainpkg, ' '.join(rdep), d) | ||
284 | } | ||
285 | |||
219 | python populate_packages () { | 286 | python populate_packages () { |
220 | import glob, stat, errno, re | 287 | import glob, stat, errno, re |
221 | 288 | ||
@@ -387,6 +454,7 @@ python populate_packages () { | |||
387 | 454 | ||
388 | bb.build.exec_func('emit_pkgdata', d) | 455 | bb.build.exec_func('emit_pkgdata', d) |
389 | } | 456 | } |
457 | populate_packages[dirs] = "${D}" | ||
390 | 458 | ||
391 | python emit_pkgdata() { | 459 | python emit_pkgdata() { |
392 | def write_if_exists(f, pkg, var): | 460 | def write_if_exists(f, pkg, var): |
@@ -424,6 +492,7 @@ python emit_pkgdata() { | |||
424 | sf.close() | 492 | sf.close() |
425 | bb.build.exec_func("read_subpackage_metadata", d) | 493 | bb.build.exec_func("read_subpackage_metadata", d) |
426 | } | 494 | } |
495 | emit_pkgdata[dirs] = "${STAGING_DIR}/pkgdata/runtime" | ||
427 | 496 | ||
428 | ldconfig_postinst_fragment() { | 497 | ldconfig_postinst_fragment() { |
429 | if [ x"$D" = "x" ]; then | 498 | if [ x"$D" = "x" ]; then |
@@ -431,57 +500,6 @@ if [ x"$D" = "x" ]; then | |||
431 | fi | 500 | fi |
432 | } | 501 | } |
433 | 502 | ||
434 | python package_depchains() { | ||
435 | """ | ||
436 | For a given set of prefix and postfix modifiers, make those packages | ||
437 | RRECOMMENDS on the corresponding packages for its DEPENDS. | ||
438 | |||
439 | Example: If package A depends upon package B, and A's .bb emits an | ||
440 | A-dev package, this would make A-dev Recommends: B-dev. | ||
441 | """ | ||
442 | |||
443 | packages = bb.data.getVar('PACKAGES', d, 1) | ||
444 | postfixes = (bb.data.getVar('DEPCHAIN_POST', d, 1) or '').split() | ||
445 | prefixes = (bb.data.getVar('DEPCHAIN_PRE', d, 1) or '').split() | ||
446 | |||
447 | def pkg_addrrecs(pkg, base, func, d): | ||
448 | rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + base, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "") | ||
449 | # bb.note('rdepends for %s is %s' % (base, rdepends)) | ||
450 | rreclist = [] | ||
451 | |||
452 | for depend in rdepends: | ||
453 | split_depend = depend.split(' (') | ||
454 | name = split_depend[0].strip() | ||
455 | func(rreclist, name) | ||
456 | |||
457 | bb.data.setVar('RRECOMMENDS_%s' % pkg, ' '.join(rreclist), d) | ||
458 | |||
459 | def packaged(pkg, d): | ||
460 | return os.access(bb.data.expand('${STAGING_DIR}/pkgdata/runtime/%s.packaged' % pkg, d), os.R_OK) | ||
461 | |||
462 | for pkg in packages.split(): | ||
463 | for postfix in postfixes: | ||
464 | def func(list, name): | ||
465 | pkg = '%s%s' % (name, postfix) | ||
466 | if packaged(pkg, d): | ||
467 | list.append(pkg) | ||
468 | |||
469 | base = pkg[:-len(postfix)] | ||
470 | if pkg.endswith(postfix): | ||
471 | pkg_addrrecs(pkg, base, func, d) | ||
472 | continue | ||
473 | |||
474 | for prefix in prefixes: | ||
475 | def func(list, name): | ||
476 | pkg = '%s%s' % (prefix, name) | ||
477 | if packaged(pkg, d): | ||
478 | list.append(pkg) | ||
479 | |||
480 | base = pkg[len(prefix):] | ||
481 | if pkg.startswith(prefix): | ||
482 | pkg_addrrecs(pkg, base, func, d) | ||
483 | } | ||
484 | |||
485 | python package_do_shlibs() { | 503 | python package_do_shlibs() { |
486 | import os, re, os.path | 504 | import os, re, os.path |
487 | 505 | ||
@@ -731,66 +749,86 @@ python package_do_pkgconfig () { | |||
731 | fd.close() | 749 | fd.close() |
732 | } | 750 | } |
733 | 751 | ||
734 | python package_do_split_locales() { | 752 | python read_shlibdeps () { |
735 | import os | ||
736 | |||
737 | if (bb.data.getVar('PACKAGE_NO_LOCALE', d, 1) == '1'): | ||
738 | bb.debug(1, "package requested not splitting locales") | ||
739 | return | ||
740 | |||
741 | packages = (bb.data.getVar('PACKAGES', d, 1) or "").split() | 753 | packages = (bb.data.getVar('PACKAGES', d, 1) or "").split() |
742 | if not packages: | 754 | for pkg in packages: |
743 | bb.debug(1, "no packages to build; not splitting locales") | 755 | rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + pkg, d, 0) or bb.data.getVar('RDEPENDS', d, 0) or "") |
744 | return | 756 | shlibsfile = bb.data.expand("${WORKDIR}/install/" + pkg + ".shlibdeps", d) |
757 | if os.access(shlibsfile, os.R_OK): | ||
758 | fd = file(shlibsfile) | ||
759 | lines = fd.readlines() | ||
760 | fd.close() | ||
761 | for l in lines: | ||
762 | rdepends.append(l.rstrip()) | ||
763 | pcfile = bb.data.expand("${WORKDIR}/install/" + pkg + ".pcdeps", d) | ||
764 | if os.access(pcfile, os.R_OK): | ||
765 | fd = file(pcfile) | ||
766 | lines = fd.readlines() | ||
767 | fd.close() | ||
768 | for l in lines: | ||
769 | rdepends.append(l.rstrip()) | ||
770 | bb.data.setVar('RDEPENDS_' + pkg, " " + " ".join(rdepends), d) | ||
771 | } | ||
745 | 772 | ||
746 | datadir = bb.data.getVar('datadir', d, 1) | 773 | python package_depchains() { |
747 | if not datadir: | 774 | """ |
748 | bb.note("datadir not defined") | 775 | For a given set of prefix and postfix modifiers, make those packages |
749 | return | 776 | RRECOMMENDS on the corresponding packages for its DEPENDS. |
750 | 777 | ||
751 | dvar = bb.data.getVar('D', d, 1) | 778 | Example: If package A depends upon package B, and A's .bb emits an |
752 | if not dvar: | 779 | A-dev package, this would make A-dev Recommends: B-dev. |
753 | bb.error("D not defined") | 780 | """ |
754 | return | ||
755 | 781 | ||
756 | pn = bb.data.getVar('PN', d, 1) | 782 | packages = bb.data.getVar('PACKAGES', d, 1) |
757 | if not pn: | 783 | postfixes = (bb.data.getVar('DEPCHAIN_POST', d, 1) or '').split() |
758 | bb.error("PN not defined") | 784 | prefixes = (bb.data.getVar('DEPCHAIN_PRE', d, 1) or '').split() |
759 | return | ||
760 | 785 | ||
761 | if pn + '-locale' in packages: | 786 | def pkg_addrrecs(pkg, base, func, d): |
762 | packages.remove(pn + '-locale') | 787 | rdepends = explode_deps(bb.data.getVar('RDEPENDS_' + base, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "") |
788 | # bb.note('rdepends for %s is %s' % (base, rdepends)) | ||
789 | rreclist = [] | ||
763 | 790 | ||
764 | localedir = os.path.join(dvar + datadir, 'locale') | 791 | for depend in rdepends: |
792 | split_depend = depend.split(' (') | ||
793 | name = split_depend[0].strip() | ||
794 | func(rreclist, name) | ||
765 | 795 | ||
766 | if not os.path.isdir(localedir): | 796 | bb.data.setVar('RRECOMMENDS_%s' % pkg, ' '.join(rreclist), d) |
767 | bb.debug(1, "No locale files in this package") | ||
768 | return | ||
769 | 797 | ||
770 | locales = os.listdir(localedir) | 798 | def packaged(pkg, d): |
799 | return os.access(bb.data.expand('${STAGING_DIR}/pkgdata/runtime/%s.packaged' % pkg, d), os.R_OK) | ||
771 | 800 | ||
772 | mainpkg = packages[0] | 801 | for pkg in packages.split(): |
802 | for postfix in postfixes: | ||
803 | def func(list, name): | ||
804 | pkg = '%s%s' % (name, postfix) | ||
805 | if packaged(pkg, d): | ||
806 | list.append(pkg) | ||
773 | 807 | ||
774 | for l in locales: | 808 | base = pkg[:-len(postfix)] |
775 | ln = legitimize_package_name(l) | 809 | if pkg.endswith(postfix): |
776 | pkg = pn + '-locale-' + ln | 810 | pkg_addrrecs(pkg, base, func, d) |
777 | packages.append(pkg) | 811 | continue |
778 | bb.data.setVar('FILES_' + pkg, os.path.join(datadir, 'locale', l), d) | ||
779 | bb.data.setVar('RDEPENDS_' + pkg, '%s virtual-locale-%s' % (mainpkg, ln), d) | ||
780 | bb.data.setVar('RPROVIDES_' + pkg, '%s-locale %s-translation' % (pn, ln), d) | ||
781 | bb.data.setVar('DESCRIPTION_' + pkg, '%s translation for %s' % (l, pn), d) | ||
782 | 812 | ||
783 | bb.data.setVar('PACKAGES', ' '.join(packages), d) | 813 | for prefix in prefixes: |
814 | def func(list, name): | ||
815 | pkg = '%s%s' % (prefix, name) | ||
816 | if packaged(pkg, d): | ||
817 | list.append(pkg) | ||
784 | 818 | ||
785 | rdep = (bb.data.getVar('RDEPENDS_%s' % mainpkg, d, 1) or bb.data.getVar('RDEPENDS', d, 1) or "").split() | 819 | base = pkg[len(prefix):] |
786 | rdep.append('%s-locale*' % pn) | 820 | if pkg.startswith(prefix): |
787 | bb.data.setVar('RDEPENDS_%s' % mainpkg, ' '.join(rdep), d) | 821 | pkg_addrrecs(pkg, base, func, d) |
788 | } | 822 | } |
789 | 823 | ||
824 | |||
790 | PACKAGEFUNCS = "package_do_split_locales \ | 825 | PACKAGEFUNCS = "package_do_split_locales \ |
791 | populate_packages package_do_shlibs \ | 826 | populate_packages \ |
792 | package_do_pkgconfig read_shlibdeps \ | 827 | package_do_shlibs \ |
828 | package_do_pkgconfig \ | ||
829 | read_shlibdeps \ | ||
793 | package_depchains" | 830 | package_depchains" |
831 | |||
794 | python package_do_package () { | 832 | python package_do_package () { |
795 | for f in (bb.data.getVar('PACKAGEFUNCS', d, 1) or '').split(): | 833 | for f in (bb.data.getVar('PACKAGEFUNCS', d, 1) or '').split(): |
796 | bb.build.exec_func(f, d) | 834 | bb.build.exec_func(f, d) |
@@ -799,6 +837,20 @@ python package_do_package () { | |||
799 | do_package[dirs] = "${D}" | 837 | do_package[dirs] = "${D}" |
800 | # shlibs requires any DEPENDS to have already packaged for the *.list files | 838 | # shlibs requires any DEPENDS to have already packaged for the *.list files |
801 | do_package[deptask] = "do_package" | 839 | do_package[deptask] = "do_package" |
802 | populate_packages[dirs] = "${STAGING_DIR}/pkgdata/runtime ${D}" | 840 | EXPORT_FUNCTIONS do_package |
803 | EXPORT_FUNCTIONS do_package do_shlibs do_split_locales mapping_rename_hook | ||
804 | addtask package before do_build after do_install | 841 | addtask package before do_build after do_install |
842 | |||
843 | # | ||
844 | # Helper functions for the package writing classes | ||
845 | # | ||
846 | |||
847 | python package_mapping_rename_hook () { | ||
848 | runtime_mapping_rename("RDEPENDS", d) | ||
849 | runtime_mapping_rename("RRECOMMENDS", d) | ||
850 | runtime_mapping_rename("RSUGGESTS", d) | ||
851 | runtime_mapping_rename("RPROVIDES", d) | ||
852 | runtime_mapping_rename("RREPLACES", d) | ||
853 | runtime_mapping_rename("RCONFLICTS", d) | ||
854 | } | ||
855 | |||
856 | EXPORT_FUNCTIONS mapping_rename_hook | ||