xref: /openbmc/openbmc/poky/meta/classes/recipe_sanity.bbclass (revision 864cc43bcd478cb31e4ab607e596ba9baf46cd3e)
192b42cb3SPatrick Williams#
292b42cb3SPatrick Williams# Copyright OpenEmbedded Contributors
392b42cb3SPatrick Williams#
492b42cb3SPatrick Williams# SPDX-License-Identifier: MIT
592b42cb3SPatrick Williams#
692b42cb3SPatrick Williams
7eb8dc403SDave Cobbleydef __note(msg, d):
8eb8dc403SDave Cobbley    bb.note("%s: recipe_sanity: %s" % (d.getVar("P"), msg))
9eb8dc403SDave Cobbley
10eb8dc403SDave Cobbley__recipe_sanity_badruntimevars = "RDEPENDS RPROVIDES RRECOMMENDS RCONFLICTS"
11eb8dc403SDave Cobbleydef bad_runtime_vars(cfgdata, d):
12eb8dc403SDave Cobbley    if bb.data.inherits_class("native", d) or \
13eb8dc403SDave Cobbley            bb.data.inherits_class("cross", d):
14eb8dc403SDave Cobbley        return
15eb8dc403SDave Cobbley
16eb8dc403SDave Cobbley    for var in d.getVar("__recipe_sanity_badruntimevars").split():
17eb8dc403SDave Cobbley        val = d.getVar(var, False)
18eb8dc403SDave Cobbley        if val and val != cfgdata.get(var):
19*864cc43bSPatrick Williams            __note("%s should be %s:${PN}" % (var, var), d)
20eb8dc403SDave Cobbley
21eb8dc403SDave Cobbley__recipe_sanity_reqvars = "DESCRIPTION"
22eb8dc403SDave Cobbley__recipe_sanity_reqdiffvars = ""
23eb8dc403SDave Cobbleydef req_vars(cfgdata, d):
24eb8dc403SDave Cobbley    for var in d.getVar("__recipe_sanity_reqvars").split():
25eb8dc403SDave Cobbley        if not d.getVar(var, False):
26eb8dc403SDave Cobbley            __note("%s should be set" % var, d)
27eb8dc403SDave Cobbley
28eb8dc403SDave Cobbley    for var in d.getVar("__recipe_sanity_reqdiffvars").split():
29eb8dc403SDave Cobbley        val = d.getVar(var, False)
30eb8dc403SDave Cobbley        cfgval = cfgdata.get(var)
31eb8dc403SDave Cobbley
32eb8dc403SDave Cobbley        if not val:
33eb8dc403SDave Cobbley            __note("%s should be set" % var, d)
34eb8dc403SDave Cobbley        elif val == cfgval:
35eb8dc403SDave Cobbley            __note("%s should be defined to something other than default (%s)" % (var, cfgval), d)
36eb8dc403SDave Cobbley
37eb8dc403SDave Cobbleydef var_renames_overwrite(cfgdata, d):
38eb8dc403SDave Cobbley    renames = d.getVar("__recipe_sanity_renames", False)
39eb8dc403SDave Cobbley    if renames:
40eb8dc403SDave Cobbley        for (key, newkey, oldvalue, newvalue) in renames:
41eb8dc403SDave Cobbley            if oldvalue != newvalue and oldvalue != cfgdata.get(newkey):
42eb8dc403SDave Cobbley                __note("rename of variable '%s' to '%s' overwrote existing value '%s' with '%s'." % (key, newkey, oldvalue, newvalue), d)
43eb8dc403SDave Cobbley
44eb8dc403SDave Cobbleydef incorrect_nonempty_PACKAGES(cfgdata, d):
45eb8dc403SDave Cobbley    if bb.data.inherits_class("native", d) or \
46eb8dc403SDave Cobbley            bb.data.inherits_class("cross", d):
47eb8dc403SDave Cobbley        if d.getVar("PACKAGES"):
48eb8dc403SDave Cobbley            return True
49eb8dc403SDave Cobbley
50eb8dc403SDave Cobbleydef can_use_autotools_base(cfgdata, d):
51eb8dc403SDave Cobbley    cfg = d.getVar("do_configure")
52eb8dc403SDave Cobbley    if not bb.data.inherits_class("autotools", d):
53eb8dc403SDave Cobbley        return False
54eb8dc403SDave Cobbley
55eb8dc403SDave Cobbley    for i in ["autoreconf"] + ["%s_do_configure" % cls for cls in ["gnomebase", "gnome", "e", "autotools", "efl", "gpephone", "openmoko", "openmoko2", "xfce", "xlibs"]]:
56eb8dc403SDave Cobbley        if cfg.find(i) != -1:
57eb8dc403SDave Cobbley            return False
58eb8dc403SDave Cobbley
59eb8dc403SDave Cobbley    for clsfile in d.getVar("__inherit_cache", False):
60eb8dc403SDave Cobbley        (base, _) = os.path.splitext(os.path.basename(clsfile))
61eb8dc403SDave Cobbley        if cfg.find("%s_do_configure" % base) != -1:
62eb8dc403SDave Cobbley            __note("autotools_base usage needs verification, spotted %s_do_configure" % base, d)
63eb8dc403SDave Cobbley
64eb8dc403SDave Cobbley    return True
65eb8dc403SDave Cobbley
66eb8dc403SDave Cobbleydef can_delete_FILESPATH(cfgdata, d):
67eb8dc403SDave Cobbley    expected = cfgdata.get("FILESPATH")
68eb8dc403SDave Cobbley    expectedpaths = d.expand(expected)
69eb8dc403SDave Cobbley    unexpanded = d.getVar("FILESPATH", False)
70eb8dc403SDave Cobbley    filespath = d.getVar("FILESPATH").split(":")
71eb8dc403SDave Cobbley    filespath = [os.path.normpath(f) for f in filespath if os.path.exists(f)]
72eb8dc403SDave Cobbley    for fp in filespath:
73eb8dc403SDave Cobbley        if not fp in expectedpaths:
74eb8dc403SDave Cobbley            # __note("Path %s in FILESPATH not in the expected paths %s" %
75eb8dc403SDave Cobbley            # (fp, expectedpaths), d)
76eb8dc403SDave Cobbley            return False
77eb8dc403SDave Cobbley    return expected != unexpanded
78eb8dc403SDave Cobbley
79eb8dc403SDave Cobbleydef can_delete_others(p, cfgdata, d):
80eb8dc403SDave Cobbley    for k in ["S", "PV", "PN", "DESCRIPTION", "DEPENDS",
81eb8dc403SDave Cobbley              "SECTION", "PACKAGES", "EXTRA_OECONF", "EXTRA_OEMAKE"]:
82eb8dc403SDave Cobbley    #for k in cfgdata:
83eb8dc403SDave Cobbley        unexpanded = d.getVar(k, False)
84eb8dc403SDave Cobbley        cfgunexpanded = cfgdata.get(k)
85eb8dc403SDave Cobbley        if not cfgunexpanded:
86eb8dc403SDave Cobbley            continue
87eb8dc403SDave Cobbley
88eb8dc403SDave Cobbley        try:
89eb8dc403SDave Cobbley            expanded = d.getVar(k)
90eb8dc403SDave Cobbley            cfgexpanded = d.expand(cfgunexpanded)
91eb8dc403SDave Cobbley        except bb.fetch.ParameterError:
92eb8dc403SDave Cobbley            continue
93eb8dc403SDave Cobbley
94eb8dc403SDave Cobbley        if unexpanded != cfgunexpanded and \
95eb8dc403SDave Cobbley           cfgexpanded == expanded:
96eb8dc403SDave Cobbley           __note("candidate for removal of %s" % k, d)
97eb8dc403SDave Cobbley           bb.debug(1, "%s: recipe_sanity:   cfg's '%s' and d's '%s' both expand to %s" %
98eb8dc403SDave Cobbley                       (p, cfgunexpanded, unexpanded, expanded))
99eb8dc403SDave Cobbley
100eb8dc403SDave Cobbleypython do_recipe_sanity () {
101eb8dc403SDave Cobbley    p = d.getVar("P")
102eb8dc403SDave Cobbley    p = "%s %s %s" % (d.getVar("PN"), d.getVar("PV"), d.getVar("PR"))
103eb8dc403SDave Cobbley
104eb8dc403SDave Cobbley    sanitychecks = [
105eb8dc403SDave Cobbley        (can_delete_FILESPATH, "candidate for removal of FILESPATH"),
106eb8dc403SDave Cobbley        #(can_use_autotools_base, "candidate for use of autotools_base"),
107eb8dc403SDave Cobbley        (incorrect_nonempty_PACKAGES, "native or cross recipe with non-empty PACKAGES"),
108eb8dc403SDave Cobbley    ]
109eb8dc403SDave Cobbley    cfgdata = d.getVar("__recipe_sanity_cfgdata", False)
110eb8dc403SDave Cobbley
111eb8dc403SDave Cobbley    for (func, msg) in sanitychecks:
112eb8dc403SDave Cobbley        if func(cfgdata, d):
113eb8dc403SDave Cobbley            __note(msg, d)
114eb8dc403SDave Cobbley
115eb8dc403SDave Cobbley    can_delete_others(p, cfgdata, d)
116eb8dc403SDave Cobbley    var_renames_overwrite(cfgdata, d)
117eb8dc403SDave Cobbley    req_vars(cfgdata, d)
118eb8dc403SDave Cobbley    bad_runtime_vars(cfgdata, d)
119eb8dc403SDave Cobbley}
120eb8dc403SDave Cobbleydo_recipe_sanity[nostamp] = "1"
121eb8dc403SDave Cobbleyaddtask recipe_sanity
122eb8dc403SDave Cobbley
123eb8dc403SDave Cobbleydo_recipe_sanity_all[nostamp] = "1"
124eb8dc403SDave Cobbleydo_recipe_sanity_all[recrdeptask] = "do_recipe_sanity_all do_recipe_sanity"
125eb8dc403SDave Cobbleydo_recipe_sanity_all () {
126eb8dc403SDave Cobbley    :
127eb8dc403SDave Cobbley}
128eb8dc403SDave Cobbleyaddtask recipe_sanity_all after do_recipe_sanity
129eb8dc403SDave Cobbley
130eb8dc403SDave Cobbleypython recipe_sanity_eh () {
131eb8dc403SDave Cobbley    d = e.data
132eb8dc403SDave Cobbley
133eb8dc403SDave Cobbley    cfgdata = {}
134eb8dc403SDave Cobbley    for k in d.keys():
135eb8dc403SDave Cobbley        if not isinstance(d.getVar(k, False), bb.data_smart.DataSmart):
136eb8dc403SDave Cobbley            cfgdata[k] = d.getVar(k, False)
137eb8dc403SDave Cobbley
138eb8dc403SDave Cobbley    d.setVar("__recipe_sanity_cfgdata", cfgdata)
139eb8dc403SDave Cobbley    #d.setVar("__recipe_sanity_cfgdata", d)
140eb8dc403SDave Cobbley
141eb8dc403SDave Cobbley    # Sick, very sick..
142eb8dc403SDave Cobbley    from bb.data_smart import DataSmart
143eb8dc403SDave Cobbley    old = DataSmart.renameVar
144eb8dc403SDave Cobbley    def myrename(self, key, newkey):
145eb8dc403SDave Cobbley        oldvalue = self.getVar(newkey, 0)
146eb8dc403SDave Cobbley        old(self, key, newkey)
147eb8dc403SDave Cobbley        newvalue = self.getVar(newkey, 0)
148eb8dc403SDave Cobbley        if oldvalue:
149eb8dc403SDave Cobbley            renames = self.getVar("__recipe_sanity_renames", 0) or set()
150eb8dc403SDave Cobbley            renames.add((key, newkey, oldvalue, newvalue))
151eb8dc403SDave Cobbley            self.setVar("__recipe_sanity_renames", renames)
152eb8dc403SDave Cobbley    DataSmart.renameVar = myrename
153eb8dc403SDave Cobbley}
154eb8dc403SDave Cobbleyaddhandler recipe_sanity_eh
155eb8dc403SDave Cobbleyrecipe_sanity_eh[eventmask] = "bb.event.ConfigParsed"
156