summaryrefslogtreecommitdiffstats
path: root/meta
diff options
context:
space:
mode:
authorNathan Rossi <nathan@nathanrossi.com>2019-04-03 05:37:02 +0000
committerRichard Purdie <richard.purdie@linuxfoundation.org>2019-04-09 13:44:39 +0100
commit9e685e2591c81c28c4fe27d8554af78b52f3a1dc (patch)
tree94a2aa04157a65271678033f08ff5b01bcfb63a0 /meta
parent5da6073d47dcdc335d5c225a8945f5f85609580e (diff)
downloadpoky-9e685e2591c81c28c4fe27d8554af78b52f3a1dc.tar.gz
ccmake.bbclass: Create a cml1 style class for the CMake curses UI
The ccmake bbclass implements two tasks. The first task 'ccmake' preserves the configured state of CMakeCache.txt (generated from the configure task) and invokes the 'ccmake' program within a oe_terminal execution. The user can then review, select and modify configuration options and once satisfied with the configuration exit ccmake. Once ccmake has exited the build can be run and the updated configuration should be reflected in the output build. The ccmake bbclass has a second task 'ccmake_diffconfig' to compute the differences in configuration which was modified by ccmake. Since there are many ways to persist the configuration changes within recipes and layer configuration, the differences are emitted as a bitbake recipe fragment (configuration.inc) using EXTRA_OECMAKE as well as a CMake script file which can be used as a input to cmake via the '-C' argument. Both files are generated in the WORKDIR of the build and the paths to the files are written as output from the build. It is then up to the user to take this configuration and apply it to the desired location. (From OE-Core rev: 091c46a8ecba6b6b7c44078ae2b567a2ef6e72e9) Signed-off-by: Nathan Rossi <nathan@nathanrossi.com> Signed-off-by: Richard Purdie <richard.purdie@linuxfoundation.org>
Diffstat (limited to 'meta')
-rw-r--r--meta/classes/ccmake.bbclass97
1 files changed, 97 insertions, 0 deletions
diff --git a/meta/classes/ccmake.bbclass b/meta/classes/ccmake.bbclass
new file mode 100644
index 0000000000..4114daa61b
--- /dev/null
+++ b/meta/classes/ccmake.bbclass
@@ -0,0 +1,97 @@
1inherit terminal
2
3python do_ccmake() {
4 import shutil
5
6 # copy current config for diffing
7 config = os.path.join(d.getVar("B"), "CMakeCache.txt")
8 if os.path.exists(config):
9 shutil.copy(config, config + ".orig")
10
11 oe_terminal(d.expand("ccmake ${OECMAKE_GENERATOR_ARGS} ${OECMAKE_SOURCEPATH} -Wno-dev"),
12 d.getVar("PN") + " - ccmake", d)
13
14 if os.path.exists(config) and os.path.exists(config + ".orig"):
15 if bb.utils.md5_file(config) != bb.utils.md5_file(config + ".orig"):
16 # the cmake class uses cmake --build, which will by default
17 # regenerate configuration, simply mark the compile step as tainted
18 # to ensure it is re-run
19 bb.note("Configuration changed, recompile will be forced")
20 bb.build.write_taint('do_compile', d)
21
22}
23do_ccmake[depends] += "cmake-native:do_populate_sysroot"
24do_ccmake[nostamp] = "1"
25do_ccmake[dirs] = "${B}"
26addtask ccmake after do_configure
27
28def cmake_parse_config_cache(path):
29 with open(path, "r") as f:
30 for i in f:
31 i = i.rstrip("\n")
32 if len(i) == 0 or i.startswith("//") or i.startswith("#"):
33 continue # empty or comment
34 key, value = i.split("=", 1)
35 key, keytype = key.split(":")
36 if keytype in ["INTERNAL", "STATIC"]:
37 continue # skip internal and static config options
38 yield key, keytype, value
39
40def cmake_diff_config_vars(a, b):
41 removed, added = [], []
42
43 for ak, akt, av in a:
44 found = False
45 for bk, bkt, bv in b:
46 if bk == ak:
47 found = True
48 if bkt != akt or bv != av: # changed
49 removed.append((ak, akt, av))
50 added.append((bk, bkt, bv))
51 break
52 # remove any missing from b
53 if not found:
54 removed.append((ak, akt, av))
55
56 # add any missing from a
57 for bk, bkt, bv in b:
58 if not any(bk == ak for ak, akt, av in a):
59 added.append((bk, bkt, bv))
60
61 return removed, added
62
63python do_ccmake_diffconfig() {
64 import shutil
65 config = os.path.join(d.getVar("B"), "CMakeCache.txt")
66 if os.path.exists(config) and os.path.exists(config + ".orig"):
67 if bb.utils.md5_file(config) != bb.utils.md5_file(config + ".orig"):
68 # scan the changed options
69 old = list(cmake_parse_config_cache(config + ".orig"))
70 new = list(cmake_parse_config_cache(config))
71 _, added = cmake_diff_config_vars(old, new)
72
73 if len(added) != 0:
74 with open(d.expand("${WORKDIR}/configuration.inc"), "w") as f:
75 f.write("EXTRA_OECMAKE += \" \\\n")
76 for k, kt, v in added:
77 escaped = v if " " not in v else "\"{0}\"".format(v)
78 f.write(" -D{0}:{1}={2} \\\n".format(k, kt, escaped))
79 f.write(" \"\n")
80 bb.plain("Configuration recipe fragment written to: {0}".format(d.expand("${WORKDIR}/configuration.inc")))
81
82 with open(d.expand("${WORKDIR}/site-file.cmake"), "w") as f:
83 for k, kt, v in added:
84 f.write("SET({0} \"{1}\" CACHE {2} "")\n".format(k, v, kt))
85 bb.plain("Configuration cmake fragment written to: {0}".format(d.expand("${WORKDIR}/site-file.cmake")))
86
87 # restore the original config
88 shutil.copy(config + ".orig", config)
89 else:
90 bb.plain("No configuration differences, skipping configuration fragment generation.")
91 else:
92 bb.fatal("No config files found. Did you run ccmake?")
93}
94do_ccmake_diffconfig[nostamp] = "1"
95do_ccmake_diffconfig[dirs] = "${B}"
96addtask ccmake_diffconfig
97