polyhorn_cli/android/tasks/
build_runtime_library.rs1use std::fs::{create_dir_all, read_dir};
2
3use super::{AndroidContext, AndroidError};
4use crate::android::Target;
5use crate::core::{CargoBuild, Manager, Task};
6
7pub struct BuildRuntimeLibrary {
10 pub target: Target<'static>,
12
13 pub profile: &'static str,
15}
16
17impl BuildRuntimeLibrary {
18 fn setup_env(&self, context: &AndroidContext) -> Result<(), AndroidError> {
19 let mut toolchain = context.android_sdk_root.clone().unwrap();
21 toolchain.push("ndk-bundle/toolchains/llvm/prebuilt");
22
23 let toolchain = match read_dir(&toolchain) {
24 Ok(mut dir) => match dir.next() {
25 Some(Ok(entry)) => entry.path(),
26 _ => return Err(AndroidError::AndroidNDKNotFound(toolchain)),
27 },
28 Err(_) => return Err(AndroidError::AndroidNDKNotFound(toolchain)),
29 };
30
31 let mut polyhorn_jar_dir = context.config.target_dir.clone();
35 polyhorn_jar_dir.push("polyhorn-android/app/libs");
36
37 let _ = create_dir_all(&polyhorn_jar_dir);
38
39 if let Some(android_sdk_root) = context.android_sdk_root.as_ref() {
40 std::env::set_var("ANDROID_SDK_ROOT", android_sdk_root);
41 }
42
43 if let Some(java_home) = context.java_home.as_ref() {
44 std::env::set_var("JAVA_HOME", java_home);
45 }
46
47 let mut sysroot = toolchain.to_path_buf();
48 sysroot.push("sysroot");
49
50 let mut toolchain = toolchain.to_path_buf();
51 toolchain.push("bin");
52
53 let mut ar = toolchain.to_path_buf();
54 ar.push(&self.target.ar);
55
56 let mut cc = toolchain.to_path_buf();
57 cc.push(&self.target.cc);
58
59 let mut cxx = toolchain.to_path_buf();
60 cxx.push(&self.target.cxx);
61
62 let mut linker = toolchain.to_path_buf();
63 linker.push(&self.target.linker);
64
65 std::env::set_var("TARGET_AR", ar);
66 std::env::set_var("TARGET_CC", cc);
67 std::env::set_var("TARGET_CXX", cxx);
68 std::env::set_var("POLYHORN_JAR_DIR", polyhorn_jar_dir);
69 std::env::set_var(
70 "CARGO_TARGET_".to_owned()
71 + &self.target.llvm_triple.replace("-", "_").to_uppercase()
72 + "_LINKER",
73 linker,
74 );
75
76 std::env::set_var(
77 "BINDGEN_EXTRA_CLANG_ARGS",
78 format!("--sysroot={}", sysroot.to_str().unwrap()),
79 );
80
81 std::env::set_var(
82 format!(
83 "CARGO_TARGET_{}_RUSTFLAGS",
84 self.target.llvm_triple.to_uppercase().replace("-", "_")
85 ),
86 "-Clink-arg=-lc++_static -Clink-arg=-lc++abi -Clink-arg=-fuse-ld=lld",
87 );
88
89 Ok(())
90 }
91}
92
93impl Task for BuildRuntimeLibrary {
94 type Context = AndroidContext;
95 type Error = AndroidError;
96
97 fn verb(&self) -> &str {
98 "Building"
99 }
100
101 fn message(&self) -> &str {
102 "runtime library"
103 }
104
105 fn detail(&self) -> &str {
106 "for Android"
107 }
108
109 fn run(
110 &self,
111 mut context: AndroidContext,
112 _manager: &mut Manager,
113 ) -> Result<AndroidContext, AndroidError> {
114 eprintln!("");
115
116 self.setup_env(&context)?;
117
118 let name = CargoBuild::new(&context.config.manifest_dir.join("Cargo.toml"))
119 .crate_type("cdylib")
120 .release(self.profile == "release")
121 .target(self.target.llvm_triple)
122 .build()?;
123
124 context.products.insert(
125 self.target.abi.to_owned(),
126 context.config.manifest_dir.join(format!(
127 "target/{}/{}/lib{}.so",
128 self.target.llvm_triple, self.profile, name
129 )),
130 );
131
132 Ok(context)
133 }
134}