diff options
Diffstat (limited to 'meta/lib/oeqa/selftest/cases/toolchain.py')
-rw-r--r-- | meta/lib/oeqa/selftest/cases/toolchain.py | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/meta/lib/oeqa/selftest/cases/toolchain.py b/meta/lib/oeqa/selftest/cases/toolchain.py new file mode 100644 index 0000000000..b4b280d037 --- /dev/null +++ b/meta/lib/oeqa/selftest/cases/toolchain.py | |||
@@ -0,0 +1,71 @@ | |||
1 | # | ||
2 | # Copyright OpenEmbedded Contributors | ||
3 | # | ||
4 | # SPDX-License-Identifier: MIT | ||
5 | # | ||
6 | |||
7 | import shutil | ||
8 | import subprocess | ||
9 | import tempfile | ||
10 | from types import SimpleNamespace | ||
11 | |||
12 | import oe.path | ||
13 | from oeqa.selftest.case import OESelftestTestCase | ||
14 | from oeqa.utils.commands import bitbake, get_bb_var, get_bb_vars | ||
15 | |||
16 | class ToolchainTests(OESelftestTestCase): | ||
17 | |||
18 | def test_toolchain_switching(self): | ||
19 | """ | ||
20 | Test that a configuration that uses GCC by default but clang for one | ||
21 | specific recipe does infact do that. | ||
22 | """ | ||
23 | |||
24 | def extract_comment(objcopy, filename): | ||
25 | """ | ||
26 | Using the specified `objcopy`, return the .comment segment from | ||
27 | `filename` as a bytes(). | ||
28 | """ | ||
29 | with tempfile.NamedTemporaryFile(prefix="comment-") as f: | ||
30 | cmd = [objcopy, "--dump-section", ".comment=" + f.name, filename] | ||
31 | subprocess.run(cmd, check=True) | ||
32 | # clang's objcopy writes to a temporary file and renames, so we need to re-open. | ||
33 | with open(f.name, "rb") as f2: | ||
34 | return f2.read() | ||
35 | |||
36 | def check_recipe(recipe, filename, override, comment_present, comment_absent=None): | ||
37 | """ | ||
38 | Check that `filename` in `recipe`'s bindir contains `comment`, and | ||
39 | the overrides contain `override`. | ||
40 | """ | ||
41 | d = SimpleNamespace(**get_bb_vars(("D", "bindir", "OBJCOPY", "OVERRIDES", "PATH"), target=recipe)) | ||
42 | |||
43 | self.assertIn(override, d.OVERRIDES) | ||
44 | |||
45 | binary = oe.path.join(d.D, d.bindir, filename) | ||
46 | |||
47 | objcopy = shutil.which(d.OBJCOPY, path=d.PATH) | ||
48 | self.assertIsNotNone(objcopy) | ||
49 | |||
50 | comment = extract_comment(objcopy, binary) | ||
51 | self.assertIn(comment_present, comment) | ||
52 | if comment_absent: | ||
53 | self.assertNotIn(comment_absent, comment) | ||
54 | |||
55 | |||
56 | # GCC by default, clang for selftest-hello. | ||
57 | self.write_config(""" | ||
58 | TOOLCHAIN = "gcc" | ||
59 | TOOLCHAIN:pn-selftest-hello = "clang" | ||
60 | """) | ||
61 | |||
62 | # Force these recipes to re-install so we can extract the .comments from | ||
63 | # the install directory, as they're stripped out of the final packages. | ||
64 | bitbake("m4 selftest-hello -C install") | ||
65 | |||
66 | # m4 should be built with GCC and only GCC | ||
67 | check_recipe("m4", "m4", "toolchain-gcc", b"GCC: (GNU)", b"clang") | ||
68 | |||
69 | # helloworld should be built with clang. We can't assert that GCC is not | ||
70 | # present as it will be linked against glibc which is built with GCC. | ||
71 | check_recipe("selftest-hello", "helloworld", "toolchain-clang", b"clang version") | ||