xref: /aosp_15_r20/development/tools/external_crates/crate_tool/src/android_bp.rs (revision 90c8c64db3049935a07c6143d7fd006e26f8ecca)
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