1 // Copyright (C) 2023 The Android Open Source Project
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 use std::{
16 env,
17 ffi::OsString,
18 path::Path,
19 process::{Command, Output},
20 time::{Duration, SystemTime},
21 };
22
23 use anyhow::{Context, Result};
24 use rooted_path::RootedPath;
25
26 use crate::SuccessOrError;
27
add_bpfmt_to_path(repo_root: impl AsRef<Path>) -> Result<OsString>28 fn add_bpfmt_to_path(repo_root: impl AsRef<Path>) -> Result<OsString> {
29 let host_bin = repo_root.as_ref().join("prebuilts/build-tools/linux-x86/bin");
30 let new_path = match env::var_os("PATH") {
31 Some(p) => {
32 let mut paths = vec![host_bin];
33 paths.extend(env::split_paths(&p));
34 env::join_paths(paths)?
35 }
36 None => host_bin.as_os_str().into(),
37 };
38 Ok(new_path)
39 }
40
run_cargo_embargo(temporary_build_path: &RootedPath) -> Result<Output>41 pub fn run_cargo_embargo(temporary_build_path: &RootedPath) -> Result<Output> {
42 maybe_build_cargo_embargo(&temporary_build_path.root(), false)?;
43 let new_path = add_bpfmt_to_path(temporary_build_path.root())?;
44
45 let mut cmd = Command::new(
46 temporary_build_path.with_same_root("out/host/linux-x86/bin/cargo_embargo")?.abs(),
47 );
48 let output = cmd
49 .args(["generate", "cargo_embargo.json"])
50 .env("PATH", new_path)
51 .env("ANDROID_BUILD_TOP", temporary_build_path.root())
52 .env_remove("OUT_DIR")
53 .current_dir(temporary_build_path)
54 .output()
55 .context(format!("Failed to execute {:?}", cmd.get_program()))?;
56
57 Ok(output)
58 }
59
cargo_embargo_autoconfig(path: &RootedPath) -> Result<Output>60 pub fn cargo_embargo_autoconfig(path: &RootedPath) -> Result<Output> {
61 maybe_build_cargo_embargo(&path.root(), false)?;
62 let new_path = add_bpfmt_to_path(path.root())?;
63
64 let mut cmd = Command::new(path.with_same_root("out/host/linux-x86/bin/cargo_embargo")?.abs());
65 cmd.args(["autoconfig", "cargo_embargo.json"])
66 .env("PATH", new_path)
67 .env("ANDROID_BUILD_TOP", path.root())
68 .env_remove("OUT_DIR")
69 .current_dir(path)
70 .output()
71 .context(format!("Failed to execute {:?}", cmd.get_program()))
72 }
73
maybe_build_cargo_embargo(repo_root: &impl AsRef<Path>, force_rebuild: bool) -> Result<()>74 pub fn maybe_build_cargo_embargo(repo_root: &impl AsRef<Path>, force_rebuild: bool) -> Result<()> {
75 let cargo_embargo = repo_root.as_ref().join("out/host/linux-x86/bin/cargo_embargo");
76 if force_rebuild
77 || !cargo_embargo.exists()
78 || SystemTime::now().duration_since(cargo_embargo.metadata()?.modified()?)?
79 > Duration::from_secs(14 * 24 * 60 * 60)
80 {
81 println!("Rebuilding cargo_embargo");
82 return build_cargo_embargo(repo_root);
83 }
84 Ok(())
85 }
86
build_cargo_embargo(repo_root: &impl AsRef<Path>) -> Result<()>87 pub fn build_cargo_embargo(repo_root: &impl AsRef<Path>) -> Result<()> {
88 Command::new("/usr/bin/bash")
89 .args(["-c", "source build/envsetup.sh && lunch aosp_cf_x86_64_phone-trunk_staging-eng && m cargo_embargo"])
90 .env_remove("OUT_DIR")
91 .current_dir(repo_root)
92 .spawn().context("Failed to spawn build of cargo embargo")?
93 .wait().context("Failed to wait on child process building cargo embargo")?
94 .success_or_error().context("Failed to build_cargo_embargo")?;
95 Ok(())
96 }
97