Skip to content

Commit 3e13542

Browse files
committed
experimental: add cargo-optee
1 parent f237f2c commit 3e13542

File tree

5 files changed

+531
-0
lines changed

5 files changed

+531
-0
lines changed

cargo-optee/Cargo.toml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
[package]
2+
name = "cargo-optee"
3+
version = "0.1.0"
4+
authors = ["Teaclave Contributors <dev@teaclave.apache.org>"]
5+
license = "Apache-2.0"
6+
repository = "https://github.com/apache/teaclave-trustzone-sdk.git"
7+
description = "A cargo subcommand for building OP-TEE Trusted Applications"
8+
edition = "2021"
9+
10+
[[bin]]
11+
name = "cargo-optee"
12+
path = "src/main.rs"
13+
14+
[dependencies]
15+
clap = { version = "4.5", features = ["derive"] }
16+
anyhow = "1.0"
17+
serde = { version = "1.0", features = ["derive"] }
18+
toml = "0.8"
19+
indexmap = "=2.11.4"
20+
env_logger = "0.11"
21+
log = "0.4"
22+
tempfile = "3.8"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"arch": "aarch64",
3+
"data-layout": "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128",
4+
"features": "+strict-align",
5+
"dynamic-linking": false,
6+
"executables": true,
7+
"has-rpath": true,
8+
"linker-flavor": "ld",
9+
"linker-is-gnu": true,
10+
"llvm-target": "aarch64-unknown-linux-gnu",
11+
"max-atomic-width": 128,
12+
"os": "optee",
13+
"position-independent-executables": true,
14+
"relro-level": "full",
15+
"target-c-int-width": "32",
16+
"target-endian": "little",
17+
"target-pointer-width": "64",
18+
"vendor": "unknown",
19+
"panic-strategy": "abort"
20+
}
21+

cargo-optee/arm-unknown-optee.json

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
{
2+
"arch": "arm",
3+
"data-layout": "e-m:e-p:32:32-Fi8-i64:64-v128:64:128-a:0:32-n32-S64",
4+
"dynamic-linking": false,
5+
"executables": true,
6+
"features": "+strict-align,+v6,+vfp2",
7+
"has-rpath": true,
8+
"linker-flavor": "ld",
9+
"linker-is-gnu": true,
10+
"llvm-target": "arm-unknown-linux-gnueabihf",
11+
"max-atomic-width": 64,
12+
"os": "optee",
13+
"position-independent-executables": true,
14+
"relro-level": "full",
15+
"target-c-int-width": "32",
16+
"target-endian": "little",
17+
"target-pointer-width": "32",
18+
"vendor": "unknown",
19+
"panic-strategy": "abort",
20+
"singlethread": true
21+
}

cargo-optee/src/main.rs

Lines changed: 138 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,138 @@
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+
18+
use anyhow::bail;
19+
use clap::{Parser, Subcommand};
20+
use std::env;
21+
use std::path::PathBuf;
22+
use std::process::abort;
23+
24+
mod ta_builder;
25+
26+
#[derive(Debug, Parser)]
27+
#[clap(version = env!("CARGO_PKG_VERSION"))]
28+
#[clap(about = "Build tool for OP-TEE Rust projects")]
29+
pub(crate) struct Cli {
30+
#[clap(subcommand)]
31+
cmd: Command,
32+
}
33+
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,
50+
51+
/// Enable std feature for the TA
52+
#[arg(long = "std")]
53+
std: bool,
54+
55+
/// Path to the TA dev kit directory (mandatory)
56+
#[arg(long = "ta_dev_kit_dir", required = true)]
57+
ta_dev_kit_dir: PathBuf,
58+
59+
/// Path to the TA signing key (default: $(TA_DEV_KIT_DIR)/keys/default_ta.pem)
60+
#[arg(long = "signing_key")]
61+
signing_key: Option<PathBuf>,
62+
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,
70+
},
71+
}
72+
73+
fn main() {
74+
env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
75+
.format_timestamp_millis()
76+
.init();
77+
78+
// Setup cargo environment if needed
79+
if let Ok(home) = env::var("HOME") {
80+
let cargo_env = format!("{}/.cargo/env", home);
81+
if std::path::Path::new(&cargo_env).exists() {
82+
// Add cargo bin to PATH
83+
let cargo_bin = format!("{}/.cargo/bin", home);
84+
if let Ok(current_path) = env::var("PATH") {
85+
let new_path = format!("{}:{}", cargo_bin, current_path);
86+
env::set_var("PATH", new_path);
87+
}
88+
} else {
89+
eprintln!("Error: Cargo environment file not found at: {}. Please ensure Rust and Cargo are installed.", cargo_env);
90+
abort();
91+
}
92+
}
93+
94+
let cli = Cli::parse();
95+
let result = execute_command(cli.cmd);
96+
97+
if let Err(e) = result {
98+
eprintln!("Error: {}", e);
99+
abort();
100+
}
101+
}
102+
103+
fn execute_command(cmd: Command) -> anyhow::Result<()> {
104+
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,
129+
std,
130+
ta_dev_kit_dir,
131+
signing_key: signing_key_path,
132+
uuid_path,
133+
debug,
134+
path,
135+
})
136+
}
137+
}
138+
}

0 commit comments

Comments
 (0)