1*4882a593Smuzhiyuninherit terminal 2*4882a593Smuzhiyun 3*4882a593Smuzhiyunpython do_ccmake() { 4*4882a593Smuzhiyun import shutil 5*4882a593Smuzhiyun 6*4882a593Smuzhiyun # copy current config for diffing 7*4882a593Smuzhiyun config = os.path.join(d.getVar("B"), "CMakeCache.txt") 8*4882a593Smuzhiyun if os.path.exists(config): 9*4882a593Smuzhiyun shutil.copy(config, config + ".orig") 10*4882a593Smuzhiyun 11*4882a593Smuzhiyun oe_terminal(d.expand("ccmake ${OECMAKE_GENERATOR_ARGS} ${OECMAKE_SOURCEPATH} -Wno-dev"), 12*4882a593Smuzhiyun d.getVar("PN") + " - ccmake", d) 13*4882a593Smuzhiyun 14*4882a593Smuzhiyun if os.path.exists(config) and os.path.exists(config + ".orig"): 15*4882a593Smuzhiyun if bb.utils.md5_file(config) != bb.utils.md5_file(config + ".orig"): 16*4882a593Smuzhiyun # the cmake class uses cmake --build, which will by default 17*4882a593Smuzhiyun # regenerate configuration, simply mark the compile step as tainted 18*4882a593Smuzhiyun # to ensure it is re-run 19*4882a593Smuzhiyun bb.note("Configuration changed, recompile will be forced") 20*4882a593Smuzhiyun bb.build.write_taint('do_compile', d) 21*4882a593Smuzhiyun 22*4882a593Smuzhiyun} 23*4882a593Smuzhiyundo_ccmake[depends] += "cmake-native:do_populate_sysroot" 24*4882a593Smuzhiyundo_ccmake[nostamp] = "1" 25*4882a593Smuzhiyundo_ccmake[dirs] = "${B}" 26*4882a593Smuzhiyunaddtask ccmake after do_configure 27*4882a593Smuzhiyun 28*4882a593Smuzhiyundef cmake_parse_config_cache(path): 29*4882a593Smuzhiyun with open(path, "r") as f: 30*4882a593Smuzhiyun for i in f: 31*4882a593Smuzhiyun i = i.rstrip("\n") 32*4882a593Smuzhiyun if len(i) == 0 or i.startswith("//") or i.startswith("#"): 33*4882a593Smuzhiyun continue # empty or comment 34*4882a593Smuzhiyun key, value = i.split("=", 1) 35*4882a593Smuzhiyun key, keytype = key.split(":") 36*4882a593Smuzhiyun if keytype in ["INTERNAL", "STATIC"]: 37*4882a593Smuzhiyun continue # skip internal and static config options 38*4882a593Smuzhiyun yield key, keytype, value 39*4882a593Smuzhiyun 40*4882a593Smuzhiyundef cmake_diff_config_vars(a, b): 41*4882a593Smuzhiyun removed, added = [], [] 42*4882a593Smuzhiyun 43*4882a593Smuzhiyun for ak, akt, av in a: 44*4882a593Smuzhiyun found = False 45*4882a593Smuzhiyun for bk, bkt, bv in b: 46*4882a593Smuzhiyun if bk == ak: 47*4882a593Smuzhiyun found = True 48*4882a593Smuzhiyun if bkt != akt or bv != av: # changed 49*4882a593Smuzhiyun removed.append((ak, akt, av)) 50*4882a593Smuzhiyun added.append((bk, bkt, bv)) 51*4882a593Smuzhiyun break 52*4882a593Smuzhiyun # remove any missing from b 53*4882a593Smuzhiyun if not found: 54*4882a593Smuzhiyun removed.append((ak, akt, av)) 55*4882a593Smuzhiyun 56*4882a593Smuzhiyun # add any missing from a 57*4882a593Smuzhiyun for bk, bkt, bv in b: 58*4882a593Smuzhiyun if not any(bk == ak for ak, akt, av in a): 59*4882a593Smuzhiyun added.append((bk, bkt, bv)) 60*4882a593Smuzhiyun 61*4882a593Smuzhiyun return removed, added 62*4882a593Smuzhiyun 63*4882a593Smuzhiyunpython do_ccmake_diffconfig() { 64*4882a593Smuzhiyun import shutil 65*4882a593Smuzhiyun config = os.path.join(d.getVar("B"), "CMakeCache.txt") 66*4882a593Smuzhiyun if os.path.exists(config) and os.path.exists(config + ".orig"): 67*4882a593Smuzhiyun if bb.utils.md5_file(config) != bb.utils.md5_file(config + ".orig"): 68*4882a593Smuzhiyun # scan the changed options 69*4882a593Smuzhiyun old = list(cmake_parse_config_cache(config + ".orig")) 70*4882a593Smuzhiyun new = list(cmake_parse_config_cache(config)) 71*4882a593Smuzhiyun _, added = cmake_diff_config_vars(old, new) 72*4882a593Smuzhiyun 73*4882a593Smuzhiyun if len(added) != 0: 74*4882a593Smuzhiyun with open(d.expand("${WORKDIR}/configuration.inc"), "w") as f: 75*4882a593Smuzhiyun f.write("EXTRA_OECMAKE += \" \\\n") 76*4882a593Smuzhiyun for k, kt, v in added: 77*4882a593Smuzhiyun escaped = v if " " not in v else "\"{0}\"".format(v) 78*4882a593Smuzhiyun f.write(" -D{0}:{1}={2} \\\n".format(k, kt, escaped)) 79*4882a593Smuzhiyun f.write(" \"\n") 80*4882a593Smuzhiyun bb.plain("Configuration recipe fragment written to: {0}".format(d.expand("${WORKDIR}/configuration.inc"))) 81*4882a593Smuzhiyun 82*4882a593Smuzhiyun with open(d.expand("${WORKDIR}/site-file.cmake"), "w") as f: 83*4882a593Smuzhiyun for k, kt, v in added: 84*4882a593Smuzhiyun f.write("SET({0} \"{1}\" CACHE {2} \"\")\n".format(k, v, kt)) 85*4882a593Smuzhiyun bb.plain("Configuration cmake fragment written to: {0}".format(d.expand("${WORKDIR}/site-file.cmake"))) 86*4882a593Smuzhiyun 87*4882a593Smuzhiyun # restore the original config 88*4882a593Smuzhiyun shutil.copy(config + ".orig", config) 89*4882a593Smuzhiyun else: 90*4882a593Smuzhiyun bb.plain("No configuration differences, skipping configuration fragment generation.") 91*4882a593Smuzhiyun else: 92*4882a593Smuzhiyun bb.fatal("No config files found. Did you run ccmake?") 93*4882a593Smuzhiyun} 94*4882a593Smuzhiyundo_ccmake_diffconfig[nostamp] = "1" 95*4882a593Smuzhiyundo_ccmake_diffconfig[dirs] = "${B}" 96*4882a593Smuzhiyunaddtask ccmake_diffconfig 97*4882a593Smuzhiyun 98