From: Deepesh Varatharajan Date: Thu, 5 Feb 2026 10:22:49 +0000 (-0800) Subject: rust: Add new nightly script X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=731fa70ccec07697fd909ed52f4cd7c19ebc6955;p=thirdparty%2Fopenembedded%2Fopenembedded-core-contrib.git rust: Add new nightly script Signed-off-by: Deepesh Varatharajan --- diff --git a/scripts/rust-new-nightly b/scripts/rust-new-nightly new file mode 100755 index 00000000000..347f7e62110 --- /dev/null +++ b/scripts/rust-new-nightly @@ -0,0 +1,211 @@ +#!/usr/bin/env python3 + +import os +import re +import sys +import hashlib +import requests +import subprocess +from datetime import datetime, timedelta + +LOCAL_CONF = "conf/local.conf" +RUST_INC = "../openembedded-core/meta/recipes-devtools/rust/rust-source.inc" + +MACHINES = [ + "qemux86-64", + "qemux86", + "qemuarm64", + "qemuarm", + "qemuriscv64", +] + +RECIPES = [ + "rust", + "cargo", + "nativesdk-rust", +] + +def switch_machine(machine): + print(f"\n=== Switching MACHINE to {machine} ===") + with open(LOCAL_CONF, "r") as f: + content = f.read() + + match = re.search(r'MACHINE\s*\?\?=\s*".*?"', content) + if not match: + raise RuntimeError("MACHINE ??= line not found in local.conf") + + old_line = match.group(0) + new_line = f'MACHINE ??= "{machine}"' + + if old_line != new_line: + content = content.replace(old_line, new_line) + with open(LOCAL_CONF, "w") as f: + f.write(content) + print(f"{old_line} -> {new_line}") + else: + print("MACHINE already set") + +def run_bitbake_with_tee(machine, recipe): + log_file = f"{machine}-{recipe}.log" + + print(f"\nRunning bitbake {recipe} for MACHINE={machine}") + print(f"Logging to {log_file}") + + cmd = f"set -o pipefail; bitbake {recipe} 2>&1 | tee {log_file}" + + process = subprocess.Popen(["bash", "-c", cmd]) + process.wait() + + if process.returncode != 0: + print(f"FAILED: {recipe} for {machine}") + return False + + print(f"SUCCESS: {recipe} for {machine}") + return True + +def run_all_recipes(machine): + results = {} + for recipe in RECIPES: + results[recipe] = run_bitbake_with_tee(machine, recipe) + return results + + +def get_yesterday_date(): + return (datetime.today() - timedelta(days=1)).strftime('%Y-%m-%d') + +def update_rust_url_and_sha256(file_path): + yesterday = get_yesterday_date() + new_url = f"https://static.rust-lang.org/dist/{yesterday}/rustc-nightly-src.tar.xz" + temp_file = "rustc-nightly-src.tar.xz" + + print(f"Checking URL: {new_url}") + response = requests.head(new_url) + if response.status_code != 200: + print(f"URL not accessible: {new_url} (Status: {response.status_code})") + return False + + print("Downloading tarball to compute SHA256...") + with open(temp_file, "wb") as f: + f.write(requests.get(new_url).content) + + with open(temp_file, "rb") as f: + sha256 = hashlib.sha256(f.read()).hexdigest() + print(f"SHA256 computed: {sha256}") + + os.remove(temp_file) + print("Deleted downloaded tarball.") + + with open(file_path, 'r') as f: + content = f.read() + + url_pattern = r"https://static\.rust-lang\.org/dist/\d{4}-\d{2}-\d{2}/rustc-nightly-src\.tar\.xz" + content, url_count = re.subn(url_pattern, new_url, content) + + sha256_pattern = r'SRC_URI\[rust\.sha256sum\] = ".*?"' + sha256_replacement = f'SRC_URI[rust.sha256sum] = "{sha256}"' + content, sha256_count = re.subn(sha256_pattern, sha256_replacement, content) + + with open(file_path, 'w') as f: + f.write(content) + + print(f"Updated {url_count} URL(s) and {sha256_count} SHA256 line(s) in '{file_path}'") + return True + +def do_update_snapshot(machine): + switch_machine(machine) + snapshot_log = "snapshot.log" + + print(f"\nRunning bitbake rust -c do_update_snapshot for MACHINE={machine}") + cmd = f"set -o pipefail; bitbake rust -c do_update_snapshot 2>&1 | tee {snapshot_log}" + + process = subprocess.Popen(["bash", "-c", cmd]) + process.wait() + + if process.returncode != 0: + print(f"WARNING: do_update_snapshot failed. Check {snapshot_log}") + else: + print(f"do_update_snapshot completed successfully. Stage0 compiler updated.") + +def insert_sanity_tested_distro(conf_file): + with open(conf_file, "r") as f: + lines = f.readlines() + + updated_lines = [] + inserted = False + for line in lines: + updated_lines.append(line) + if not inserted and "MACHINE ??=" in line: + updated_lines.append('SANITY_TESTED_DISTROS = ""\n') + inserted = True + + if inserted: + with open(conf_file, "w") as f: + f.writelines(updated_lines) + print("Inserted SANITY_TESTED_DISTROS after MACHINE ??=") + else: + print("MACHINE ??= not found, no changes made.") + +def main(): + print("Updating rust snapshot in rust-source.inc ...") + if not update_rust_url_and_sha256(RUST_INC): + print("Failed to update rust snapshot. Exiting.") + sys.exit(1) + + baseline_machine = "qemux86-64" + do_update_snapshot(baseline_machine) + + all_failures = {} + + try: + for machine in MACHINES: + print(f" BUILDING FOR MACHINE: {machine}") + + switch_machine(machine) + results = run_all_recipes(machine) + + failed_recipes = [r for r, ok in results.items() if not ok] + if failed_recipes: + all_failures[machine] = failed_recipes + + finally: + switch_machine("qemux86-64") + print("\nMACHINE restored to qemux86-64") + + insert_sanity_tested_distro(LOCAL_CONF) + + for machine in MACHINES: + switch_machine(machine) + + selftest_log = f"oe-selftest-{machine}.log" + cmd = f"oe-selftest -r rust -K 2>&1 | tee {selftest_log}" + + print(f"Running: {cmd}") + process = subprocess.Popen(["bash", "-c", cmd], stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, bufsize=1) + for line in process.stdout: + print(line, end="") + process.wait() + + if process.returncode != 0: + print(f"WARNING: oe-selftest failed for {machine}, check {selftest_log}") + else: + print(f"oe-selftest completed successfully for {machine}") + + build_st_dir = "../build-st" + target_dir = f"../build-{machine}-st" + if os.path.exists(build_st_dir): + print(f"Moving {build_st_dir} -> {target_dir}") + if os.path.exists(target_dir): + subprocess.run(["rm", "-rf", target_dir]) + subprocess.run(["mv", build_st_dir, target_dir]) + else: + print(f"No build-st directory found for {machine}, skipping move.") + + if not all_failures: + print("All machines and recipes completed successfully") + else: + print("Failures detected:") + for machine, recipes in all_failures.items(): + print(f" {machine}: {', '.join(recipes)}") + +if __name__ == "__main__": + main()