summaryrefslogtreecommitdiffstats
path: root/meta/classes/multilib.bbclass
blob: a4151658a620f937a46ac07cc8a6edb0f30f3720 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
#
# Copyright OpenEmbedded Contributors
#
# SPDX-License-Identifier: MIT
#

python multilib_virtclass_handler () {
    cls = d.getVar("BBEXTENDCURR")
    variant = d.getVar("BBEXTENDVARIANT")
    if cls != "multilib" or not variant:
        return

    localdata = bb.data.createCopy(d)
    localdata.delVar('TMPDIR')
    d.setVar('STAGING_KERNEL_DIR', localdata.getVar('STAGING_KERNEL_DIR'))

    # There should only be one kernel in multilib configs
    # We also skip multilib setup for module packages.
    provides = (d.getVar("PROVIDES") or "").split()
    non_ml_recipes = d.getVar('NON_MULTILIB_RECIPES').split()
    bpn = d.getVar("BPN")
    if ("virtual/kernel" in provides
            or bb.data.inherits_class('module-base', d)
            or bpn in non_ml_recipes):
        raise bb.parse.SkipRecipe("We shouldn't have multilib variants for %s" % bpn)

    save_var_name = d.getVar("MULTILIB_SAVE_VARNAME") or ""
    for name in save_var_name.split():
        val = d.getVar(name)
        if val:
            d.setVar(name + "_MULTILIB_ORIGINAL", val)

    # We nearly don't need this but dependencies on NON_MULTILIB_RECIPES don't work without it
    d.setVar("SSTATE_ARCHS_TUNEPKG", "${@all_multilib_tune_values(d, 'TUNE_PKGARCH')}")

    overrides = e.data.getVar("OVERRIDES", False)
    pn = e.data.getVar("PN", False)
    overrides = overrides.replace("pn-${PN}", "pn-${PN}:pn-" + pn)
    d.setVar("OVERRIDES", overrides)

    if bb.data.inherits_class('image', d):
        d.setVar("MLPREFIX", variant + "-")
        d.setVar("PN", variant + "-" + d.getVar("PN", False))
        d.setVar('SDKTARGETSYSROOT', d.getVar('SDKTARGETSYSROOT'))
        override = ":virtclass-multilib-" + variant
        d.setVar("OVERRIDES", d.getVar("OVERRIDES", False) + override)
        target_vendor = d.getVar("TARGET_VENDOR:" + "virtclass-multilib-" + variant, False)
        if target_vendor:
            d.setVar("TARGET_VENDOR", target_vendor)
        return

    if bb.data.inherits_class('cross-canadian', d):
        # Multilib cross-candian should use the same nativesdk sysroot without MLPREFIX
        d.setVar("RECIPE_SYSROOT", "${WORKDIR}/recipe-sysroot")
        d.setVar("STAGING_DIR_TARGET", "${WORKDIR}/recipe-sysroot")
        d.setVar("STAGING_DIR_HOST", "${WORKDIR}/recipe-sysroot")
        d.setVar("RECIPE_SYSROOT_MANIFEST_SUBDIR", "nativesdk-" + variant)
        d.setVar("MLPREFIX", variant + "-")
        override = ":virtclass-multilib-" + variant
        d.setVar("OVERRIDES", d.getVar("OVERRIDES", False) + override)
        return

    if bb.data.inherits_class('native', d):
        raise bb.parse.SkipRecipe("We can't extend native recipes")

    if bb.data.inherits_class('nativesdk', d) or bb.data.inherits_class('crosssdk', d):
        raise bb.parse.SkipRecipe("We can't extend nativesdk recipes")

    if (bb.data.inherits_class('allarch', d)
            and not d.getVar('MULTILIB_VARIANTS')
            and not bb.data.inherits_class('packagegroup', d)):
        raise bb.parse.SkipRecipe("Don't extend allarch recipes which are not packagegroups")

    # Expand this since this won't work correctly once we set a multilib into place
    d.setVar("ALL_MULTILIB_PACKAGE_ARCHS", d.getVar("ALL_MULTILIB_PACKAGE_ARCHS"))
 
    override = ":virtclass-multilib-" + variant

    skip_msg = d.getVarFlag('SKIP_RECIPE', d.getVar('PN'))
    if skip_msg:
        pn_new = variant + "-" + d.getVar('PN')
        if not d.getVarFlag('SKIP_RECIPE', pn_new):
            d.setVarFlag('SKIP_RECIPE', pn_new, skip_msg)

    d.setVar("MLPREFIX", variant + "-")
    d.setVar("PN", variant + "-" + d.getVar("PN", False))
    d.setVar("OVERRIDES", d.getVar("OVERRIDES", False) + override)

    # Expand INCOMPATIBLE_LICENSE_EXCEPTIONS with multilib prefix
    pkgs = d.getVar("INCOMPATIBLE_LICENSE_EXCEPTIONS")
    if pkgs:
        for pkg in pkgs.split():
            pkgs += " " + variant + "-" + pkg
        d.setVar("INCOMPATIBLE_LICENSE_EXCEPTIONS", pkgs)

    # DEFAULTTUNE can change TARGET_ARCH override so expand this now before update_data
    newtune = d.getVar("DEFAULTTUNE:" + "virtclass-multilib-" + variant, False)
    if newtune:
        d.setVar("DEFAULTTUNE", newtune)
}

addhandler multilib_virtclass_handler
multilib_virtclass_handler[eventmask] = "bb.event.RecipePreFinalise"

python __anonymous () {
    if bb.data.inherits_class('image', d):
        # set rpm preferred file color for 32-bit multilib image
        if d.getVar("SITEINFO_BITS") == "32":
            d.setVar("RPM_PREFER_ELF_ARCH", "1")

        variant = d.getVar("BBEXTENDVARIANT")
        import oe.classextend

        clsextend = oe.classextend.ClassExtender(variant, d)

        clsextend.map_depends_variable("PACKAGE_INSTALL")
        clsextend.map_depends_variable("LINGUAS_INSTALL")
        clsextend.map_depends_variable("RDEPENDS")
        pinstall = d.getVar("LINGUAS_INSTALL") + " " + d.getVar("PACKAGE_INSTALL")
        d.setVar("PACKAGE_INSTALL", pinstall)
        d.setVar("LINGUAS_INSTALL", "")
        # FIXME, we need to map this to something, not delete it!
        d.setVar("PACKAGE_INSTALL_ATTEMPTONLY", "")
        bb.build.deltask('do_populate_sdk_ext', d)
        return
}

python multilib_virtclass_handler_postkeyexp () {
    cls = d.getVar("BBEXTENDCURR")
    variant = d.getVar("BBEXTENDVARIANT")
    if cls != "multilib" or not variant:
        return

    variant = d.getVar("BBEXTENDVARIANT")

    import oe.classextend

    clsextend = oe.classextend.ClassExtender(variant, d)

    if bb.data.inherits_class('image', d):
        return

    clsextend.map_depends_variable("DEPENDS")
    clsextend.map_depends_variable("PACKAGE_WRITE_DEPS")
    clsextend.map_variable("PROVIDES")

    if bb.data.inherits_class('cross-canadian', d):
        return

    clsextend.rename_packages()
    clsextend.rename_package_variables((d.getVar("PACKAGEVARS") or "").split())

    clsextend.map_packagevars()
    clsextend.map_regexp_variable("PACKAGES_DYNAMIC")
    clsextend.map_variable("INITSCRIPT_PACKAGES")
    clsextend.map_variable("USERADD_PACKAGES")
    clsextend.map_variable("SYSTEMD_PACKAGES")
    clsextend.map_variable("UPDATERCPN")

    reset_alternative_priority(d)
}

addhandler multilib_virtclass_handler_postkeyexp
multilib_virtclass_handler_postkeyexp[eventmask] = "bb.event.RecipePostKeyExpansion"

def reset_alternative_priority(d):
    if not bb.data.inherits_class('update-alternatives', d):
        return

    # There might be multiple multilibs at the same time, e.g., lib32 and
    # lib64, each of them should have a different priority.
    multilib_variants = d.getVar('MULTILIB_VARIANTS')
    bbextendvariant = d.getVar('BBEXTENDVARIANT')
    reset_gap = multilib_variants.split().index(bbextendvariant) + 1

    # ALTERNATIVE_PRIORITY = priority
    alt_priority_recipe = d.getVar('ALTERNATIVE_PRIORITY')
    # Reset ALTERNATIVE_PRIORITY when found
    if alt_priority_recipe:
        reset_priority = int(alt_priority_recipe) - reset_gap
        bb.debug(1, '%s: Setting ALTERNATIVE_PRIORITY to %s' % (d.getVar('PN'), reset_priority))
        d.setVar('ALTERNATIVE_PRIORITY', reset_priority)

    handled_pkgs = []
    for pkg in (d.getVar('PACKAGES') or "").split():
        # ALTERNATIVE_PRIORITY_pkg = priority
        alt_priority_pkg = d.getVar('ALTERNATIVE_PRIORITY_%s' % pkg)
        # Reset ALTERNATIVE_PRIORITY_pkg when found
        if alt_priority_pkg:
            reset_priority = int(alt_priority_pkg) - reset_gap
            if not pkg in handled_pkgs:
                handled_pkgs.append(pkg)
                bb.debug(1, '%s: Setting ALTERNATIVE_PRIORITY_%s to %s' % (pkg, pkg, reset_priority))
                d.setVar('ALTERNATIVE_PRIORITY_%s' % pkg, reset_priority)

        for alt_name in (d.getVar('ALTERNATIVE:%s' % pkg) or "").split():
            # ALTERNATIVE_PRIORITY_pkg[tool]  = priority
            alt_priority_pkg_name = d.getVarFlag('ALTERNATIVE_PRIORITY_%s' % pkg, alt_name)
            # ALTERNATIVE_PRIORITY[tool] = priority
            alt_priority_name = d.getVarFlag('ALTERNATIVE_PRIORITY', alt_name)

            if alt_priority_pkg_name:
                reset_priority = int(alt_priority_pkg_name) - reset_gap
                bb.debug(1, '%s: Setting ALTERNATIVE_PRIORITY_%s[%s] to %s' % (pkg, pkg, alt_name, reset_priority))
                d.setVarFlag('ALTERNATIVE_PRIORITY_%s' % pkg, alt_name, reset_priority)
            elif alt_priority_name:
                reset_priority = int(alt_priority_name) - reset_gap
                bb.debug(1, '%s: Setting ALTERNATIVE_PRIORITY[%s] to %s' % (pkg, alt_name, reset_priority))
                d.setVarFlag('ALTERNATIVE_PRIORITY', alt_name, reset_priority)

PACKAGEFUNCS:append = " do_package_qa_multilib"

python do_package_qa_multilib() {

    def check_mlprefix(pkg, var, mlprefix):
        values = bb.utils.explode_deps(d.getVar('%s:%s' % (var, pkg)) or d.getVar(var) or "")
        candidates = []
        for i in values:
            if i.startswith('virtual/'):
                i = i[len('virtual/'):]

            if (not (i.startswith(mlprefix) or i.startswith("kernel-") \
                    or ('cross-canadian' in i) or i.startswith("nativesdk-") \
                    or i.startswith("rtld") or i.startswith("/"))):
                candidates.append(i)

        if len(candidates) > 0:
            msg = "%s package %s - suspicious values '%s' in %s" \
                   % (d.getVar('PN'), pkg, ' '.join(candidates), var)
            oe.qa.handle_error("multilib", msg, d)

    ml = d.getVar('MLPREFIX')
    if not ml:
        return

    # exception for ${MLPREFIX}target-sdk-provides-dummy
    if 'target-sdk-provides-dummy' in d.getVar('PN'):
        return

    packages = d.getVar('PACKAGES')
    for pkg in packages.split():
        check_mlprefix(pkg, 'RDEPENDS', ml)
        check_mlprefix(pkg, 'RPROVIDES', ml)
        check_mlprefix(pkg, 'RRECOMMENDS', ml)
        check_mlprefix(pkg, 'RSUGGESTS', ml)
        check_mlprefix(pkg, 'RREPLACES', ml)
        check_mlprefix(pkg, 'RCONFLICTS', ml)
    oe.qa.exit_if_errors(d)
}