xref: /openbmc/openbmc/poky/meta/classes/multilib.bbclass (revision edff49234e31f23dc79f823473c9e286a21596c1)
1#
2# Copyright OpenEmbedded Contributors
3#
4# SPDX-License-Identifier: MIT
5#
6
7python multilib_virtclass_handler () {
8    cls = d.getVar("BBEXTENDCURR")
9    variant = d.getVar("BBEXTENDVARIANT")
10    if cls != "multilib" or not variant:
11        return
12
13    localdata = bb.data.createCopy(d)
14    localdata.delVar('TMPDIR')
15    d.setVar('STAGING_KERNEL_DIR', localdata.getVar('STAGING_KERNEL_DIR'))
16
17    # There should only be one kernel in multilib configs
18    # We also skip multilib setup for module packages.
19    provides = (d.getVar("PROVIDES") or "").split()
20    non_ml_recipes = d.getVar('NON_MULTILIB_RECIPES').split()
21    bpn = d.getVar("BPN")
22    if ("virtual/kernel" in provides
23            or bb.data.inherits_class('module-base', d)
24            or bpn in non_ml_recipes):
25        raise bb.parse.SkipRecipe("We shouldn't have multilib variants for %s" % bpn)
26
27    save_var_name = d.getVar("MULTILIB_SAVE_VARNAME") or ""
28    for name in save_var_name.split():
29        val = d.getVar(name)
30        if val:
31            d.setVar(name + "_MULTILIB_ORIGINAL", val)
32
33    # We nearly don't need this but dependencies on NON_MULTILIB_RECIPES don't work without it
34    d.setVar("SSTATE_ARCHS_TUNEPKG", "${@all_multilib_tune_values(d, 'TUNE_PKGARCH')}")
35
36    overrides = e.data.getVar("OVERRIDES", False)
37    pn = e.data.getVar("PN", False)
38    overrides = overrides.replace("pn-${PN}", "pn-${PN}:pn-" + pn)
39    d.setVar("OVERRIDES", overrides)
40
41    if bb.data.inherits_class('image', d):
42        d.setVar("MLPREFIX", variant + "-")
43        d.setVar("PN", variant + "-" + d.getVar("PN", False))
44        d.setVar('SDKTARGETSYSROOT', d.getVar('SDKTARGETSYSROOT'))
45        override = ":virtclass-multilib-" + variant
46        d.setVar("OVERRIDES", d.getVar("OVERRIDES", False) + override)
47        target_vendor = d.getVar("TARGET_VENDOR:" + "virtclass-multilib-" + variant, False)
48        if target_vendor:
49            d.setVar("TARGET_VENDOR", target_vendor)
50        return
51
52    if bb.data.inherits_class('cross-canadian', d):
53        # Multilib cross-candian should use the same nativesdk sysroot without MLPREFIX
54        d.setVar("RECIPE_SYSROOT", "${WORKDIR}/recipe-sysroot")
55        d.setVar("STAGING_DIR_TARGET", "${WORKDIR}/recipe-sysroot")
56        d.setVar("STAGING_DIR_HOST", "${WORKDIR}/recipe-sysroot")
57        d.setVar("RECIPE_SYSROOT_MANIFEST_SUBDIR", "nativesdk-" + variant)
58        d.setVar("MLPREFIX", variant + "-")
59        override = ":virtclass-multilib-" + variant
60        d.setVar("OVERRIDES", d.getVar("OVERRIDES", False) + override)
61        return
62
63    if bb.data.inherits_class('native', d):
64        raise bb.parse.SkipRecipe("We can't extend native recipes")
65
66    if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('crosssdk', d):
67        raise bb.parse.SkipRecipe("We can't extend nativesdk recipes")
68
69    if (bb.data.inherits_class('allarch', d)
70            and not d.getVar('MULTILIB_VARIANTS')
71            and not bb.data.inherits_class('packagegroup', d)):
72        raise bb.parse.SkipRecipe("Don't extend allarch recipes which are not packagegroups")
73
74    # Expand this since this won't work correctly once we set a multilib into place
75    d.setVar("ALL_MULTILIB_PACKAGE_ARCHS", d.getVar("ALL_MULTILIB_PACKAGE_ARCHS"))
76
77    override = ":virtclass-multilib-" + variant
78
79    skip_msg = d.getVarFlag('SKIP_RECIPE', d.getVar('PN'))
80    if skip_msg:
81        pn_new = variant + "-" + d.getVar('PN')
82        if not d.getVarFlag('SKIP_RECIPE', pn_new):
83            d.setVarFlag('SKIP_RECIPE', pn_new, skip_msg)
84
85    d.setVar("MLPREFIX", variant + "-")
86    d.setVar("PN", variant + "-" + d.getVar("PN", False))
87    d.setVar("OVERRIDES", d.getVar("OVERRIDES", False) + override)
88
89    # Expand INCOMPATIBLE_LICENSE_EXCEPTIONS with multilib prefix
90    pkgs = d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS")
91    if pkgs:
92        for pkg in pkgs.split():
93            pkgs += " " + variant + "-" + pkg
94        d.setVar("INCOMPATIBLE_LICENSE_EXCEPTIONS", pkgs)
95
96    # DEFAULTTUNE can change TARGET_ARCH override so expand this now before update_data
97    newtune = d.getVar("DEFAULTTUNE:" + "virtclass-multilib-" + variant, False)
98    if newtune:
99        d.setVar("DEFAULTTUNE", newtune)
100}
101
102addhandler multilib_virtclass_handler
103multilib_virtclass_handler[eventmask] = "bb.event.RecipePreFinalise"
104
105python __anonymous () {
106    if bb.data.inherits_class('image', d):
107        # set rpm preferred file color for 32-bit multilib image
108        if d.getVar("SITEINFO_BITS") == "32":
109            d.setVar("RPM_PREFER_ELF_ARCH", "1")
110
111        variant = d.getVar("BBEXTENDVARIANT")
112        import oe.classextend
113
114        clsextend = oe.classextend.ClassExtender(variant, d)
115
116        clsextend.map_depends_variable("PACKAGE_INSTALL")
117        clsextend.map_depends_variable("LINGUAS_INSTALL")
118        clsextend.map_depends_variable("RDEPENDS")
119        pinstall = d.getVar("LINGUAS_INSTALL") + " " + d.getVar("PACKAGE_INSTALL")
120        d.setVar("PACKAGE_INSTALL", pinstall)
121        d.setVar("LINGUAS_INSTALL", "")
122        # FIXME, we need to map this to something, not delete it!
123        d.setVar("PACKAGE_INSTALL_ATTEMPTONLY", "")
124        bb.build.deltask('do_populate_sdk_ext', d)
125        return
126}
127
128python multilib_virtclass_handler_postkeyexp () {
129    cls = d.getVar("BBEXTENDCURR")
130    variant = d.getVar("BBEXTENDVARIANT")
131    if cls != "multilib" or not variant:
132        return
133
134    variant = d.getVar("BBEXTENDVARIANT")
135
136    import oe.classextend
137
138    clsextend = oe.classextend.ClassExtender(variant, d)
139
140    if bb.data.inherits_class('image', d):
141        return
142
143    clsextend.map_depends_variable("DEPENDS")
144    clsextend.map_depends_variable("PACKAGE_WRITE_DEPS")
145    clsextend.map_variable("PROVIDES")
146
147    if bb.data.inherits_class('cross-canadian', d):
148        return
149
150    clsextend.rename_packages()
151    clsextend.rename_package_variables((d.getVar("PACKAGEVARS") or "").split())
152
153    clsextend.map_packagevars()
154    clsextend.map_regexp_variable("PACKAGES_DYNAMIC")
155    clsextend.map_variable("INITSCRIPT_PACKAGES")
156    clsextend.map_variable("USERADD_PACKAGES")
157    clsextend.map_variable("SYSTEMD_PACKAGES")
158    clsextend.map_variable("UPDATERCPN")
159
160    reset_alternative_priority(d)
161}
162
163addhandler multilib_virtclass_handler_postkeyexp
164multilib_virtclass_handler_postkeyexp[eventmask] = "bb.event.RecipePostKeyExpansion"
165
166def reset_alternative_priority(d):
167    if not bb.data.inherits_class('update-alternatives', d):
168        return
169
170    # There might be multiple multilibs at the same time, e.g., lib32 and
171    # lib64, each of them should have a different priority.
172    multilib_variants = d.getVar('MULTILIB_VARIANTS')
173    bbextendvariant = d.getVar('BBEXTENDVARIANT')
174    reset_gap = multilib_variants.split().index(bbextendvariant) + 1
175
176    # ALTERNATIVE_PRIORITY = priority
177    alt_priority_recipe = d.getVar('ALTERNATIVE_PRIORITY')
178    # Reset ALTERNATIVE_PRIORITY when found
179    if alt_priority_recipe:
180        reset_priority = int(alt_priority_recipe) - reset_gap
181        bb.debug(1, '%s: Setting ALTERNATIVE_PRIORITY to %s' % (d.getVar('PN'), reset_priority))
182        d.setVar('ALTERNATIVE_PRIORITY', reset_priority)
183
184    handled_pkgs = []
185    for pkg in (d.getVar('PACKAGES') or "").split():
186        # ALTERNATIVE_PRIORITY_pkg = priority
187        alt_priority_pkg = d.getVar('ALTERNATIVE_PRIORITY_%s' % pkg)
188        # Reset ALTERNATIVE_PRIORITY_pkg when found
189        if alt_priority_pkg:
190            reset_priority = int(alt_priority_pkg) - reset_gap
191            if not pkg in handled_pkgs:
192                handled_pkgs.append(pkg)
193                bb.debug(1, '%s: Setting ALTERNATIVE_PRIORITY_%s to %s' % (pkg, pkg, reset_priority))
194                d.setVar('ALTERNATIVE_PRIORITY_%s' % pkg, reset_priority)
195
196        for alt_name in (d.getVar('ALTERNATIVE:%s' % pkg) or "").split():
197            # ALTERNATIVE_PRIORITY_pkg[tool]  = priority
198            alt_priority_pkg_name = d.getVarFlag('ALTERNATIVE_PRIORITY_%s' % pkg, alt_name)
199            # ALTERNATIVE_PRIORITY[tool] = priority
200            alt_priority_name = d.getVarFlag('ALTERNATIVE_PRIORITY', alt_name)
201
202            if alt_priority_pkg_name:
203                reset_priority = int(alt_priority_pkg_name) - reset_gap
204                bb.debug(1, '%s: Setting ALTERNATIVE_PRIORITY_%s[%s] to %s' % (pkg, pkg, alt_name, reset_priority))
205                d.setVarFlag('ALTERNATIVE_PRIORITY_%s' % pkg, alt_name, reset_priority)
206            elif alt_priority_name:
207                reset_priority = int(alt_priority_name) - reset_gap
208                bb.debug(1, '%s: Setting ALTERNATIVE_PRIORITY[%s] to %s' % (pkg, alt_name, reset_priority))
209                d.setVarFlag('ALTERNATIVE_PRIORITY', alt_name, reset_priority)
210
211PACKAGEFUNCS:append = " do_package_qa_multilib"
212
213python do_package_qa_multilib() {
214
215    def check_mlprefix(pkg, var, mlprefix):
216        values = bb.utils.explode_deps(d.getVar('%s:%s' % (var, pkg)) or d.getVar(var) or "")
217        candidates = []
218        for i in values:
219            if i.startswith('virtual/'):
220                i = i[len('virtual/'):]
221
222            if (not (i.startswith(mlprefix) or i.startswith("kernel-") \
223                    or ('cross-canadian' in i) or i.startswith("nativesdk-") \
224                    or i.startswith("rtld") or i.startswith("/"))):
225                candidates.append(i)
226
227        if len(candidates) > 0:
228            msg = "%s package %s - suspicious values '%s' in %s" \
229                   % (d.getVar('PN'), pkg, ' '.join(candidates), var)
230            oe.qa.handle_error("multilib", msg, d)
231
232    ml = d.getVar('MLPREFIX')
233    if not ml:
234        return
235
236    # exception for ${MLPREFIX}target-sdk-provides-dummy
237    if 'target-sdk-provides-dummy' in d.getVar('PN'):
238        return
239
240    packages = d.getVar('PACKAGES')
241    for pkg in packages.split():
242        check_mlprefix(pkg, 'RDEPENDS', ml)
243        check_mlprefix(pkg, 'RPROVIDES', ml)
244        check_mlprefix(pkg, 'RRECOMMENDS', ml)
245        check_mlprefix(pkg, 'RSUGGESTS', ml)
246        check_mlprefix(pkg, 'RREPLACES', ml)
247        check_mlprefix(pkg, 'RCONFLICTS', ml)
248    oe.qa.exit_if_errors(d)
249}
250