1use std::path::PathBuf;
2
3use build_crate::{BuildKind, GuestBuild};
4use ssz::Encode;
5
6const TARGET_JSON: &str = include_str!("riscv64em-javm.json");
7const TARGET_NAME: &str = "riscv64em-javm";
8
9fn watch_transpiler_sources() {
12 let manifest_dir = std::env::var("CARGO_MANIFEST_DIR").expect("CARGO_MANIFEST_DIR not set");
13 let crates_dir = PathBuf::from(&manifest_dir)
14 .parent()
15 .expect("build-javm must be inside crates/")
16 .to_path_buf();
17
18 build_crate::emit_rerun_for_dir(&crates_dir.join("javm-transpiler/src"));
20 let javm_src = crates_dir.join("javm/src");
22 println!(
23 "cargo:rerun-if-changed={}",
24 javm_src.join("program.rs").display()
25 );
26}
27
28pub fn build(manifest_dir: &str, bin_name: &str) -> PathBuf {
30 watch_transpiler_sources();
31 let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set");
32 let blob_path = PathBuf::from(&out_dir).join(format!("{bin_name}.pvm"));
33
34 if std::env::var("SKIP_GUEST_BUILD").is_ok() {
35 if !blob_path.exists() {
36 std::fs::write(&blob_path, b"").ok();
37 }
38 return blob_path;
39 }
40
41 let resolved = build_crate::resolve_manifest_dir(manifest_dir);
42 let target_json_path = build_crate::write_target_json("riscv64em-javm.json", TARGET_JSON);
43
44 let extra_rustflags = vec!["-Cllvm-args=--inline-threshold=275".to_string()];
45 let guest = GuestBuild {
46 manifest_dir: resolved,
47 target_json_path,
48 target_dir_name: TARGET_NAME.to_string(),
49 build_kind: BuildKind::Bin(bin_name.to_string()),
50 extra_rustflags,
51 extra_rustc_args: vec![],
52 env_overrides: vec![
53 (
54 "CARGO_PROFILE_RELEASE_OPT_LEVEL".to_string(),
55 "3".to_string(),
56 ),
57 ("CARGO_PROFILE_RELEASE_LTO".to_string(), "true".to_string()),
58 (
59 "CARGO_PROFILE_RELEASE_CODEGEN_UNITS".to_string(),
60 "1".to_string(),
61 ),
62 ],
63 rustc_bootstrap: true,
64 };
65
66 let elf_path = guest.build();
67 let elf_data = std::fs::read(&elf_path).expect("failed to read ELF");
68 let image =
69 javm_transpiler::link_elf(&elf_data).expect("failed to transpile ELF to Cap::Image");
70 let encoded = image.as_ssz_bytes();
71
72 std::fs::write(&blob_path, &encoded).expect("failed to write Image blob");
73 blob_path
74}
75
76pub fn build_service(manifest_dir: &str, bin_name: &str) -> PathBuf {
78 watch_transpiler_sources();
79 let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set");
80 let blob_path = PathBuf::from(&out_dir).join(format!("{bin_name}.pvm"));
81
82 if std::env::var("SKIP_GUEST_BUILD").is_ok() {
83 if !blob_path.exists() {
84 std::fs::write(&blob_path, b"").ok();
85 }
86 return blob_path;
87 }
88
89 let resolved = build_crate::resolve_manifest_dir(manifest_dir);
90 let target_json_path = build_crate::write_target_json("riscv64em-javm.json", TARGET_JSON);
91
92 let extra_rustflags = vec!["-Cllvm-args=--inline-threshold=275".to_string()];
93 let guest = GuestBuild {
94 manifest_dir: resolved,
95 target_json_path,
96 target_dir_name: TARGET_NAME.to_string(),
97 build_kind: BuildKind::Bin(bin_name.to_string()),
98 extra_rustflags,
99 extra_rustc_args: vec![],
100 env_overrides: vec![
101 (
102 "CARGO_PROFILE_RELEASE_OPT_LEVEL".to_string(),
103 "s".to_string(),
104 ),
105 ("CARGO_PROFILE_RELEASE_LTO".to_string(), "false".to_string()),
106 ],
107 rustc_bootstrap: true,
108 };
109
110 let elf_path = guest.build();
111 let elf_data = std::fs::read(&elf_path).expect("failed to read ELF");
112 let image =
113 javm_transpiler::link_elf(&elf_data).expect("failed to transpile ELF to Cap::Image");
114 let encoded = image.as_ssz_bytes();
115
116 std::fs::write(&blob_path, &encoded).expect("failed to write Image blob");
117 blob_path
118}