Skip to content

Commit 89b136d

Browse files
committed
cargo-optee: add build ca cmds and resolve issues
- enable build ca - add sub-command: ta and ca - revise param "arch" from string to enum - fix building error for 32bit TAs, related to optee-utee-build - fix license
1 parent 3e13542 commit 89b136d

File tree

5 files changed

+110
-106
lines changed

5 files changed

+110
-106
lines changed

.licenserc.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ header:
2929
- '**/Cargo.lock'
3030
- 'KEYS'
3131
- 'DISCLAIMER'
32-
- '*.json'
32+
- '**/*.json'
3333
- 'examples/tls_server-rs/ta/test-ca/**'
3434
- '**/uuid.txt'
3535
- '**/plugin_uuid.txt'

cargo-optee/Cargo.toml

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,20 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing,
12+
# software distributed under the License is distributed on an
13+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14+
# KIND, either express or implied. See the License for the
15+
# specific language governing permissions and limitations
16+
# under the License.
17+
118
[package]
219
name = "cargo-optee"
320
version = "0.1.0"

cargo-optee/src/main.rs

Lines changed: 74 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -15,14 +15,17 @@
1515
// specific language governing permissions and limitations
1616
// under the License.
1717

18-
use anyhow::bail;
1918
use clap::{Parser, Subcommand};
2019
use std::env;
2120
use std::path::PathBuf;
2221
use std::process::abort;
2322

23+
mod ca_builder;
24+
mod common;
2425
mod ta_builder;
2526

27+
use common::Arch;
28+
2629
#[derive(Debug, Parser)]
2730
#[clap(version = env!("CARGO_PKG_VERSION"))]
2831
#[clap(about = "Build tool for OP-TEE Rust projects")]
@@ -31,23 +34,29 @@ pub(crate) struct Cli {
3134
cmd: Command,
3235
}
3336

34-
#[derive(Debug, Subcommand)]
35-
enum Command {
36-
/// Build a Trusted Application (TA)
37-
#[clap(name = "build")]
38-
Build {
39-
/// Type of build target (currently only 'ta' is supported)
40-
#[arg(value_name = "TYPE")]
41-
build_type: String,
42-
43-
/// Path to the TA directory (default: current directory)
44-
#[arg(long = "path", default_value = ".")]
45-
path: PathBuf,
46-
47-
/// Target architecture: aarch64 or arm (default: aarch64)
48-
#[arg(long = "arch", default_value = "aarch64")]
49-
arch: String,
37+
#[derive(Debug, Parser)]
38+
struct BuildTypeCommonOptions {
39+
/// Path to the app directory (default: current directory)
40+
#[arg(long = "path", default_value = ".")]
41+
path: PathBuf,
42+
43+
/// Target architecture: aarch64 or arm (default: aarch64)
44+
#[arg(long = "arch", default_value = "aarch64")]
45+
arch: Arch,
46+
47+
/// Path to the UUID file (default: ../uuid.txt)
48+
#[arg(long = "uuid_path", default_value = "../uuid.txt")]
49+
uuid_path: PathBuf,
50+
51+
/// Build in debug mode (default is release)
52+
#[arg(long = "debug")]
53+
debug: bool,
54+
}
5055

56+
#[derive(Debug, Subcommand)]
57+
enum BuildCommand {
58+
/// Build a Trusted Application
59+
TA {
5160
/// Enable std feature for the TA
5261
#[arg(long = "std")]
5362
std: bool,
@@ -60,16 +69,28 @@ enum Command {
6069
#[arg(long = "signing_key")]
6170
signing_key: Option<PathBuf>,
6271

63-
/// Path to the UUID file (default: ../uuid.txt)
64-
#[arg(long = "uuid_path", default_value = "../uuid.txt")]
65-
uuid_path: PathBuf,
66-
67-
/// Build in debug mode (default is release)
68-
#[arg(long = "debug")]
69-
debug: bool,
72+
#[command(flatten)]
73+
common: BuildTypeCommonOptions,
74+
},
75+
/// Build a Client Application (Host)
76+
CA {
77+
/// Path to the OP-TEE client export directory (mandatory)
78+
#[arg(long = "optee_client_export", required = true)]
79+
optee_client_export: PathBuf,
80+
81+
#[command(flatten)]
82+
common: BuildTypeCommonOptions,
7083
},
7184
}
7285

86+
#[derive(Debug, Subcommand)]
87+
enum Command {
88+
/// Build OP-TEE components
89+
#[clap(name = "build")]
90+
#[command(subcommand)]
91+
Build(BuildCommand),
92+
}
93+
7394
fn main() {
7495
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
7596
.format_timestamp_millis()
@@ -102,37 +123,36 @@ fn main() {
102123

103124
fn execute_command(cmd: Command) -> anyhow::Result<()> {
104125
match cmd {
105-
Command::Build {
106-
build_type,
107-
path,
108-
arch,
109-
std,
110-
ta_dev_kit_dir,
111-
signing_key,
112-
uuid_path,
113-
debug,
114-
} => {
115-
// Validate build type
116-
if build_type != "ta" {
117-
bail!(
118-
"Invalid build type '{}'. Only 'ta' is supported.",
119-
build_type
120-
);
121-
}
122-
123-
// Determine signing key path
124-
let signing_key_path =
125-
signing_key.unwrap_or_else(|| ta_dev_kit_dir.join("keys").join("default_ta.pem"));
126-
127-
ta_builder::build_ta(ta_builder::TaBuildConfig {
128-
arch,
126+
Command::Build(build_cmd) => match build_cmd {
127+
BuildCommand::TA {
129128
std,
130129
ta_dev_kit_dir,
131-
signing_key: signing_key_path,
132-
uuid_path,
133-
debug,
134-
path,
135-
})
136-
}
130+
signing_key,
131+
common,
132+
} => {
133+
// Determine signing key path
134+
let signing_key_path = signing_key
135+
.unwrap_or_else(|| ta_dev_kit_dir.join("keys").join("default_ta.pem"));
136+
137+
ta_builder::build_ta(ta_builder::TaBuildConfig {
138+
arch: common.arch,
139+
std,
140+
ta_dev_kit_dir,
141+
signing_key: signing_key_path,
142+
uuid_path: common.uuid_path,
143+
debug: common.debug,
144+
path: common.path,
145+
})
146+
}
147+
BuildCommand::CA {
148+
optee_client_export,
149+
common,
150+
} => ca_builder::build_ca(ca_builder::CaBuildConfig {
151+
arch: common.arch,
152+
optee_client_export,
153+
debug: common.debug,
154+
path: common.path,
155+
}),
156+
},
137157
}
138158
}

cargo-optee/src/ta_builder.rs

Lines changed: 14 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -18,35 +18,19 @@
1818
use anyhow::{bail, Result};
1919
use std::env;
2020
use std::fs;
21-
use std::path::{Path, PathBuf};
22-
use std::process::{Command, Output};
21+
use std::path::Path;
22+
use std::path::PathBuf;
23+
use std::process::Command;
2324
use tempfile::TempDir;
2425

26+
use crate::common::{print_output_and_bail, Arch, ChangeDirectoryGuard};
27+
2528
// Embed the target JSON files at compile time
2629
const AARCH64_TARGET_JSON: &str = include_str!("../aarch64-unknown-optee.json");
2730
const ARM_TARGET_JSON: &str = include_str!("../arm-unknown-optee.json");
2831

29-
// Helper function to print command output and return error
30-
fn print_output_and_bail(cmd_name: &str, output: &Output) -> Result<()> {
31-
eprintln!(
32-
"{} stdout: {}",
33-
cmd_name,
34-
String::from_utf8_lossy(&output.stdout)
35-
);
36-
eprintln!(
37-
"{} stderr: {}",
38-
cmd_name,
39-
String::from_utf8_lossy(&output.stderr)
40-
);
41-
bail!(
42-
"{} failed with exit code: {:?}",
43-
cmd_name,
44-
output.status.code()
45-
)
46-
}
47-
4832
pub struct TaBuildConfig {
49-
pub arch: String, // "aarch64" or "arm"
33+
pub arch: Arch, // Architecture
5034
pub std: bool, // Enable std feature
5135
pub ta_dev_kit_dir: PathBuf, // Path to TA dev kit
5236
pub signing_key: PathBuf, // Path to signing key
@@ -56,9 +40,9 @@ pub struct TaBuildConfig {
5640
}
5741

5842
// Helper function to derive target and cross-compile from arch and std
59-
fn get_target_and_cross_compile(arch: &str, std: bool) -> (String, String) {
43+
fn get_target_and_cross_compile(arch: Arch, std: bool) -> (String, String) {
6044
match arch {
61-
"arm" => {
45+
Arch::Arm => {
6246
if std {
6347
(
6448
"arm-unknown-optee".to_string(),
@@ -71,7 +55,7 @@ fn get_target_and_cross_compile(arch: &str, std: bool) -> (String, String) {
7155
)
7256
}
7357
}
74-
_ => {
58+
Arch::Aarch64 => {
7559
if std {
7660
(
7761
"aarch64-unknown-optee".to_string(),
@@ -108,7 +92,7 @@ fn setup_build_command(
10892
command: &str,
10993
) -> Result<(Command, Option<TempDir>)> {
11094
// Determine target and cross-compile based on arch
111-
let (target, _cross_compile) = get_target_and_cross_compile(&config.arch, config.std);
95+
let (target, _cross_compile) = get_target_and_cross_compile(config.arch, config.std);
11296

11397
// Determine builder (cargo or xargo)
11498
let builder = if config.std { "xargo" } else { "cargo" };
@@ -151,14 +135,7 @@ fn setup_build_command(
151135
// Main function to build the TA
152136
pub fn build_ta(config: TaBuildConfig) -> Result<()> {
153137
// Change to the TA directory
154-
let original_dir = env::current_dir()?;
155-
156-
env::set_current_dir(&config.path)?;
157-
158-
// Ensure we return to the original directory when done
159-
let _guard = ChangeDirectoryGuard {
160-
original: original_dir.clone(),
161-
};
138+
let _guard = ChangeDirectoryGuard::new(&config.path)?;
162139

163140
println!("Building TA in directory: {:?}", config.path);
164141

@@ -211,7 +188,7 @@ fn build_binary(config: &TaBuildConfig) -> Result<()> {
211188
println!("Building TA binary...");
212189

213190
// Determine target and cross-compile based on arch
214-
let (target, cross_compile) = get_target_and_cross_compile(&config.arch, config.std);
191+
let (target, cross_compile) = get_target_and_cross_compile(config.arch, config.std);
215192

216193
// Setup build command with common environment
217194
let (mut build_cmd, _temp_dir) = setup_build_command(config, "build")?;
@@ -238,7 +215,7 @@ fn strip_binary(config: &TaBuildConfig) -> Result<PathBuf> {
238215
println!("Stripping binary...");
239216

240217
// Determine target based on arch
241-
let (target, cross_compile) = get_target_and_cross_compile(&config.arch, config.std);
218+
let (target, cross_compile) = get_target_and_cross_compile(config.arch, config.std);
242219

243220
let profile = if config.debug { "debug" } else { "release" };
244221
let target_dir = PathBuf::from("target").join(target).join(profile);
@@ -286,7 +263,7 @@ fn sign_ta(config: &TaBuildConfig, stripped_path: &Path) -> Result<()> {
286263
}
287264

288265
// Determine target based on arch
289-
let (target, _) = get_target_and_cross_compile(&config.arch, config.std);
266+
let (target, _) = get_target_and_cross_compile(config.arch, config.std);
290267

291268
// Output path
292269
let profile = if config.debug { "debug" } else { "release" };
@@ -316,14 +293,3 @@ fn sign_ta(config: &TaBuildConfig, stripped_path: &Path) -> Result<()> {
316293

317294
Ok(())
318295
}
319-
320-
// Guard to ensure we return to the original directory
321-
struct ChangeDirectoryGuard {
322-
original: PathBuf,
323-
}
324-
325-
impl Drop for ChangeDirectoryGuard {
326-
fn drop(&mut self) {
327-
let _ = env::set_current_dir(&self.original);
328-
}
329-
}

optee-utee-build/src/linker.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,10 +126,11 @@ impl Linker {
126126
out_dir: PathBuf,
127127
ta_dev_kit_dir: PathBuf,
128128
) -> Result<(), Error> {
129-
const ENV_TARGET_TA: &str = "TARGET_TA";
130-
println!("cargo:rerun-if-env-changed={}", ENV_TARGET_TA);
129+
// cargo passes TARGET as env to the build scripts
130+
const ENV_TARGET: &str = "TARGET";
131+
println!("cargo:rerun-if-env-changed={}", ENV_TARGET);
131132
let mut aarch64_flag = true;
132-
match env::var(ENV_TARGET_TA) {
133+
match env::var(ENV_TARGET) {
133134
Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
134135
match self.linker_type {
135136
LinkerType::Cc => println!("cargo:rustc-link-arg=-Wl,--no-warn-mismatch"),

0 commit comments

Comments
 (0)