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 fs::{remove_file, rename},
19 path::Path,
20 process::{Command, Output},
21 time::{Duration, SystemTime},
22 };
23
24 use anyhow::{Context, Result};
25 use rooted_path::RootedPath;
26
27 use crate::SuccessOrError;
28
add_bpfmt_to_path(repo_root: impl AsRef<Path>) -> Result<OsString>29 fn add_bpfmt_to_path(repo_root: impl AsRef<Path>) -> Result<OsString> {
30 let host_bin = repo_root.as_ref().join("prebuilts/build-tools/linux-x86/bin");
31 let new_path = match env::var_os("PATH") {
32 Some(p) => {
33 let mut paths = vec![host_bin];
34 paths.extend(env::split_paths(&p));
35 env::join_paths(paths)?
36 }
37 None => host_bin.as_os_str().into(),
38 };
39 Ok(new_path)
40 }
41
run_cargo_embargo(staging_path: &RootedPath) -> Result<Output>42 pub fn run_cargo_embargo(staging_path: &RootedPath) -> Result<Output> {
43 maybe_build_cargo_embargo(&staging_path.root(), false)?;
44 let new_path = add_bpfmt_to_path(staging_path.root())?;
45
46 let cargo_lock = staging_path.join("Cargo.lock")?;
47 let saved_cargo_lock = staging_path.join("Cargo.lock.saved")?;
48 if cargo_lock.abs().exists() {
49 rename(&cargo_lock, &saved_cargo_lock)?;
50 }
51
52 let mut cmd =
53 Command::new(staging_path.with_same_root("out/host/linux-x86/bin/cargo_embargo")?.abs());
54 let output = cmd
55 .args(["generate", "cargo_embargo.json"])
56 .env("PATH", new_path)
57 .env("ANDROID_BUILD_TOP", staging_path.root())
58 .env_remove("OUT_DIR")
59 .current_dir(staging_path)
60 .output()
61 .context(format!("Failed to execute {:?}", cmd.get_program()))?;
62
63 if cargo_lock.abs().exists() {
64 remove_file(&cargo_lock)?;
65 }
66 if saved_cargo_lock.abs().exists() {
67 rename(saved_cargo_lock, cargo_lock)?;
68 }
69
70 Ok(output)
71 }
72
cargo_embargo_autoconfig(path: &RootedPath) -> Result<Output>73 pub fn cargo_embargo_autoconfig(path: &RootedPath) -> Result<Output> {
74 maybe_build_cargo_embargo(&path.root(), false)?;
75 let new_path = add_bpfmt_to_path(path.root())?;
76
77 let mut cmd = Command::new(path.with_same_root("out/host/linux-x86/bin/cargo_embargo")?.abs());
78 cmd.args(["autoconfig", "cargo_embargo.json"])
79 .env("PATH", new_path)
80 .env("ANDROID_BUILD_TOP", path.root())
81 .env_remove("OUT_DIR")
82 .current_dir(path)
83 .output()
84 .context(format!("Failed to execute {:?}", cmd.get_program()))
85 }
86
maybe_build_cargo_embargo(repo_root: &impl AsRef<Path>, force_rebuild: bool) -> Result<()>87 pub fn maybe_build_cargo_embargo(repo_root: &impl AsRef<Path>, force_rebuild: bool) -> Result<()> {
88 let cargo_embargo = repo_root.as_ref().join("out/host/linux-x86/bin/cargo_embargo");
89 if force_rebuild
90 || !cargo_embargo.exists()
91 || SystemTime::now().duration_since(cargo_embargo.metadata()?.modified()?)?
92 > Duration::from_secs(14 * 24 * 60 * 60)
93 {
94 println!("Rebuilding cargo_embargo");
95 return build_cargo_embargo(repo_root);
96 }
97 Ok(())
98 }
99
build_cargo_embargo(repo_root: &impl AsRef<Path>) -> Result<()>100 pub fn build_cargo_embargo(repo_root: &impl AsRef<Path>) -> Result<()> {
101 Command::new("/usr/bin/bash")
102 .args(["-c", "source build/envsetup.sh && lunch aosp_cf_x86_64_phone-trunk_staging-eng && m cargo_embargo"])
103 .env_remove("OUT_DIR")
104 .current_dir(repo_root)
105 .spawn().context("Failed to spawn build of cargo embargo")?
106 .wait().context("Failed to wait on child process building cargo embargo")?
107 .success_or_error().context("Failed to build_cargo_embargo")?;
108 Ok(())
109 }
110