Skip to content

Conversation

@DemesneGH
Copy link
Contributor

As discussed in #244, I'm trying to remove Makefiles and provide a Cargo-based tool for building OP-TEE apps.

This is an initial version of the cargo-optee tool which enables building TAs in no-std and std:

$ cargo-optee build -h
Build a Trusted Application (TA)

Usage: cargo-optee build [OPTIONS] --ta_dev_kit_dir <TA_DEV_KIT_DIR> <TYPE>

Arguments:
  <TYPE>  Type of build target (currently only 'ta' is supported)

Options:
      --path <PATH>
          Path to the TA directory (default: current directory) [default: .]
      --arch <ARCH>
          Target architecture: aarch64 or arm (default: aarch64) [default: aarch64]
      --std
          Enable std feature for the TA
      --ta_dev_kit_dir <TA_DEV_KIT_DIR>
          Path to the TA dev kit directory (mandatory)
      --signing_key <SIGNING_KEY>
          Path to the TA signing key (default: $(TA_DEV_KIT_DIR)/keys/default_ta.pem)
      --uuid_path <UUID_PATH>
          Path to the UUID file (default: ../uuid.txt) [default: ../uuid.txt]
      --debug
          Build in debug mode (default is release)
  -h, --help
          Print help

build the cargo-optee tool:

cd cargo-optee && cargo build --release

building no-std TA:

cargo-optee build ta --path /teaclave/examples/hello_world-rs/ta --ta_dev_kit_dir /teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64

building std TA:

cargo-optee build ta --path /teaclave/examples/hello_world-rs/ta --ta_dev_kit_dir /teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64 --std

The goal is to make TA building simple: once the environment has the Rust and GCC toolchains installed, developers can build a TA directly using this tool.
It does not rely on global environment variables, only reads parameters explicitly passed. This design makes it more flexible across different development environments and provides clearer control over variable usage. The only mandatory parameter is TA_DEV_KIT_DIR; all other parameters have default values.

However, TA_DEV_KIT_DIR is a low-level configuration detail. For our dev/emulation environments, we can provide a helper script in the future, to set up all required OP-TEE libraries and pass TA_DEV_KIT_DIR to the tool.

There are still several areas that can be further refined:

  • Remove all Xargo.toml files from the TA source code.
  • Automatically download std dependencies when the std feature is enabled.
  • Enable building of CAs.
  • Improve UUID location. It’s shared between the host and TA, so it may make sense to define it under proto/. The host can read it from the source code, and cargo-optee can use it when building the TA. For now, it remains as the original uuid.txt.
  • Consider adding configurable metadata in the TA’s Cargo.toml (similar to what [cargo-sgx](https://github.com/automata-network/automata-sgx-sdk) does with [package.metadata.sgx]).
  • Provide a new setup script for the dev/emulation environments.

I’ll move this forward. Please feel free to try out the tool and share any feedback about this, thanks!

@DemesneGH
Copy link
Contributor Author

new commit:

  • enable build ca
  • add sub-command: ta and ca
  • revise param "arch" from string to enum
  • fix building error for 32bit TAs, modified optee-utee-build/src/linker.rs
  • fix license

@DemesneGH DemesneGH force-pushed the experimental-cargo-build branch from 89b136d to 84a9673 Compare October 24, 2025 12:47
}

#[derive(Debug, Subcommand)]
enum Command {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we have a high level design about the cargo-optee?

What is the convention | requirement between different roles?

  • cargo-optee and underlining build system
  • cargo-optee and TA developer

Please refer to the following link as a reference.
https://github.com/automata-network/automata-sgx-sdk?tab=readme-ov-file#getting-started

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated in the new commit and cargo-optee/README.md

Copy link
Contributor

@m4sterchain m4sterchain Oct 29, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the effort for showing the current design.

cargo-optee build ta \
  --ta_dev_kit_dir <PATH> \
  [--path <PATH>] \
  [--arch aarch64|arm] \
  [--std] \
  [--signing_key <PATH>] \
  [--uuid_path <PATH>] \
  [--debug]

However, I don’t think this should be the ideal interface for TA developers.
I suggest we align and compare the design with existing cargo-based workflows such as cargo and cargo-sgx to ensure consistency and ease of use.

Project-related configurations (for both TA and CA) should remain in Cargo.toml.

  1. For example, cargo-trustzone should automatically infer whether to build with std based on the std feature declared in Cargo.toml, as you have proposed using the std feature for the std build in previous PR.
  2. For other project-specific parameters, we can follow the convention used by cargo-sgx, which leverages [package.metadata] as the bridge between developers and the custom cargo toolchain.

Toolchain configurations & Zero-argument usability

By default, running cargo-trustzone build should work without requiring additional parameters.
Since project-specific configurations are defined in Cargo.toml, the toolchain should have clear default discovery rules for common paths (e.g., how ta_dev_kit_dir is located, instead of a required parameter for each invocation of the build cli).
For example, the standard cargo toolchain automatically discovers the Rust sysroot and standard library paths by resolving from rustc --print sysroot, without needing users to specify them manually. Its behavior might also be influenced by environment variables such as RUSTUP_HOME and CARGO_HOME, which allow users to override toolchain locations in a standardized way.
Similarly, cargo-trustzone should support automatic discovery of the default ta_dev_kit_dir (e.g., from an environment variable, configuration file, or standard installation path) to provide a smooth and familiar developer experience consistent with the normal cargo workflow.

Learn from Existing Design

Lastly, as I have suggested multiple times, please take a deeper look at the cargo-sgx tool and compare our current design against it. Many of the challenges we are encountering have already been addressed there — such as providing a developer-friendly interface, automatic build support for customized std environments, and seamless integration of loadable trusted components with untrusted applications. There may be additional insights and techniques we can learn from those design patterns. I strongly recommend gaining a solid understanding of what is already available before reinventing the wheel.

Copy link
Contributor Author

@DemesneGH DemesneGH Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've reviewed the cargo-sgx code snippet — although it reads metadata, it still accepts parameters via command line with default values. I assume you're suggesting we should move some params to [package.metadata] in Cargo.toml instead of passing them as command-line arguments?

I actually mentioned the idea in the initial message of this PR, but there are a few considerations. Let's go through each:

arch / std

We should allow building the same app for different arch and modes.
If these values are hardcoded in Cargo.toml, we lose the flexibility. For example, in CI:

cargo-trustzone should automatically infer whether to build with std based on the feature declared in Cargo.toml.

But what should we write in the common examples’ Cargo.toml?
If we set "no-std", how would we build it in std mode for CI? by modifying Cargo.toml each time? I don't have the answer.

Therefore, I believe arch and std should remain as command-line parameters, each with default values.

ta_dev_kit_dir

Seems this might suitable for Cargo.toml, but it’s different for arch — for example:

optee_os/out/arm-plat-vexpress/export-ta_arm64
optee_os/out/arm-plat-vexpress/export-ta_arm32

If we put it in Cargo.toml, we’d have to edit that file each time we change the build architecture.
Maybe try this?

[metadata]
ta_dev_kit.64 = "xxxx_export-ta_arm64"
ta_dev_kit.32 = "xxxx_export-ta_arm32"

use the different entry decided by cmd param arch.

uuid_path (or uuid)

Instead of storing a uuid_path, it may make more sense to store a uuid string directly in the metadata. Since uuid.txt is both used by TA build tools and read by the proto (and imported by the CA when invoking the TA). We could try to write into the Cargo.toml, but to which Cargo.toml? Maybe we should have a workspace?
I’m still thinking about it.

signing_key

It makes sense to write into the Cargo.toml.


and seamless integration of loadable trusted components with untrusted applications

Does it mean the plugin if in optee? I don't really get the point.

Similarly, cargo-trustzone should support automatic discovery of the default ta_dev_kit_dir (e.g., from an environment variable, configuration file, or standard installation path) to provide a smooth and familiar developer experience consistent with the normal cargo workflow.

Consider the scenario:

  • OP-TEE OS developers export the ta_dev_kit, and send it to the TA developer
  • TA developer receives it and build the TA

For this tool, I want it less dependent with the environment, for production use cases or experienced developers, the TA developers typically only need a toolchain setup and already know the location of their ta_dev_kit; with those information they can build the TA directly.

Additionally, I plan to provide a helper script for the dev/emulation env for easy use on qemuv8, together with preparing the OP-TEE libraries.


Please feel free to share your suggestions, thanks!

Copy link
Contributor

@m4sterchain m4sterchain Oct 30, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before we move further, could you clarify what kind of user experience you envision for TA developers using the cargo-optee toolchain?

From my perspective, the cargo-optee build command should provide a seamless interface aligned with the existing cargo build workflow, either through transparent parameter passing or through complementary extensions. The key principle is to stay consistent with Cargo’s CLI conventions and user expectations.
It’s perfectly fine for the internal implementation to have a different interface, but here I’m mainly referring to the user-facing design.

Here I just expand one point for illustration.
Q: “But what should we write in the common examples’ Cargo.toml? If we set no-std, how would we build it in std mode for CI? By modifying Cargo.toml each time? I don't have the answer.”

My view: when designing the interface, we should ask — how do Rust developers normally address this problem (e.g., switching between no_std and std, or specifying architectures)? We should adopt the same mechanism.

For std / no_std switching, Rust developers use Cargo features declared in Cargo.toml, together with --no-default-features or --features xxx or nothing for cargo build. This convention can also be applied for our customized tooling.

The underlying build logic can follow Cargo’s native feature resolution model (via cargo_metadata), for example:

cargo (optee) build
cargo (optee) build --no-default-features
cargo (optee) build --no-default-features --features no_std // or std

The key concept here is transparent delegation to Cargo, cargo-optee does not need to reimplement or reinterpret feature logic, or use a reinvented --std parameter, but instead query and respect Cargo’s native feature resolution. This ensures consistent developer experience and predictable build behavior.

A similar comparison and concept mapping approach to existing Cargo mechanisms can be applied to other aspects as well, such as toolchain conventions and project conventions, to achieve a more consistent and intuitive CLI experience.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think cargo-optee provides the convenience for building TAs, not mandatory to keep consistency with the original cargo cmd parameters.

For example, the cargo-optee cmd:

cargo-optee build ta \
  --ta_dev_kit_dir /opt/optee/export-ta_arm64 \
  --path ./ta \
  --arch aarch64

will be converted to:

TA_DEV_KIT_DIR=/opt/optee/export-ta_arm64 \
RUSTFLAGS="-C panic=abort" \
cargo build --target aarch64-unknown-linux-gnu --release \
  --config target.aarch64-unknown-linux-gnu.linker="aarch64-linux-gnu-gcc"

for build.

--arch is not consistent with cargo's cmdline but it will configure the target for developer's convenience. Do you mean we should use the --target in cargo-optee?
If so, why not directly use cargo command, we don't need a wrapper.

feature std is similar. It's not only converted to the cargo build --features std, but also decide the target and whether we use xargo. I can follow the cargo's cmd format, like cargo-optee build ta --features std, but it doesn't mean the same as in cargo.

From my perspective, the cargo-optee build command should provide a seamless interface aligned with the existing cargo build workflow,

I've checked other tools cargo-sgx cargo-near which also defines their cmd lines different with original cargo. Any reasons on why we should follow seamless interface principle?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

cargo_metadata retrieves meta info based on cargo.toml and command-line options in a programatic way, which does not mean convert to cargo build --features std. It is designated to used from within a cargo-* executable. https://crates.io/crates/cargo_metadata

Here is a more concrete example to illustrate the difference.

  • cargo-optee build ta --std means no matter what default feature developer defines in the Cargo.toml, the customized toolchain will build in using std library (new convention is introduced by cargo-optee).
  • cargo optee build (with other cargo compatible flags) means the the customized toolchain will respect what feature the developer enables in the Cargo.toml (std/no-std) and automatically handles internally (select xargo to build stdlib or not) based on the active feature.

Any reasons on why we should follow seamless interface principle?
There’s no strict requirement to maintain full consistency with Cargo’s original command-line parameters. However, I am just wondering if our goal should be to make OP-TEE development feel like a natural extension of the standard Cargo experience — a design I believe is achievable for our current use cases. To realize this, we can learn from existing customized toolchains, e.g. both tools you mentioned also leverage cargo_metadata to retrieve project setup information.

I will end this conversation here, as I believe I’ve explained my points clearly and don’t want to spend more time on further debate.

@DemesneGH
Copy link
Contributor Author

Summary of the new commit:

Users & Scenarios

For developers (dev/emulation environments):
They only need to build and run a few examples or their own projects. After installing the toolchain, they can simply use cargo-optee to build CA, TA and Plugins with the source code.

For CI:
We need to build all examples. The workflow is:

  1. Setup toolchains and OP-TEE libraries
  2. Run: TA_DEV_KIT_DIR=xxx OPTEE_CLIENT_EXPORT=xxx ./ci/build.sh to build all examples using cargo-optee, the script reads examples/metadata.json to get info of each example

I've tested the build.sh and all examples build passed for aarch64 TA and aarch64 CA:

  • No-std mode: source ~/.cargo/env && TA_DEV_KIT_DIR=/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64 OPTEE_CLIENT_EXPORT=/teaclave/optee/optee_client/export_arm64 ./ci/build.sh
  • Std mode: source ~/.cargo/env && TA_DEV_KIT_DIR=/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64 OPTEE_CLIENT_EXPORT=/teaclave/optee/optee_client/export_arm64 ./ci/build.sh --std

We can remove all Makefiles from the SDK now.
For design, user interface and other details, please refer to cargo-optee/README.md.


Changes

  • cargo-optee:

    • Add build plugin support
    • Add README.md
  • examples: Add metadata.json for recording all application info

  • ci: Add build.sh for building all examples defined in metadata.json

  • Fix special cases:

    • mnist-rs: Move -Z build-std parameters into .cargo/config.toml for self-maintenance
    • mnist-rs: cargo-optee now searches workspace Cargo.toml (needs polish)
    • std-only TAs (message_passing_interface, serde, secure_db_abstraction, tls_client, tls_server): Require mandatory std feature for consistency. After this change: common TAs and std-only TAs explicitly require --std flag for build with std. This ensures cargo-optee handles std feature in a unified manner for all examples.

Notes

  • For building CAs, proto includes relative UUID path ../../uuid.txt, should be revised
  • CI: requires apt-get install jq for json parsing in ci/build.sh

Next steps

  • remove all Makefiles
  • enable the Github Action CI
  • remove all Xargo.toml from ta
  • polish the code

@DemesneGH
Copy link
Contributor Author

Refer to the OP-TEE issue: OP-TEE/build#849
Adding install and clean subcmds helps us to cleanup the large building artifacts which save the disk space, it's useful for CI and production build. This also mentioned in cargo-optee/README.md

@DemesneGH
Copy link
Contributor Author

DemesneGH commented Nov 5, 2025

The new commit:

  1. Read from Cargo.toml metadata:

    • Enable reading build parameters from [package.metadata.optee.*] sections
    • Implement priority-based configuration: CLI arguments > metadata > default value
    • Update supp_plugin-rs/*/Cargo.toml files for demonstration
    • See updated cargo-optee/README.md for detailed usage instructions
  2. Custom build env var and features:

    • Allow users to specify custom environment variables and features
    • These options are automatically appended to cargo build commands

The CI build script (ci/build.sh) passes successfully for the default aarch64 no-std configuration.


How to use this tool:

  1. clone the code;
  2. build the cargo-optee:
(cd cargo-optee && cargo build --release)
# Optional: add to PATH for easier usage
export PATH=/path/to/cargo-optee/target/release:$PATH
  1. run cargo-optee --help to show the help messages
  2. build the app: e.g.
# with metadata the app can be built without params
cd examples/supp_plugin-rs/plugin && cargo-optee build plugin
# without metadata, (if you don't want to change the directory, you can specify `--manifest-path` like the original cargo)
cargo-optee build ta --manifest-path /teaclave/examples/hello_world-rs/ta/Cargo.toml  --ta-dev-kit-dir /path/to/optee_os/out/arm-plat-vexpress/export-ta_arm64

example log:

Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  TA dev kit dir: "/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64"
  UUID path: "/teaclave/examples/hello_world-rs/uuid.txt"
Building TA in directory: /teaclave/examples/hello_world-rs/ta
Running cargo fmt and clippy...
Building TA binary...
  Environment: RUSTFLAGS=-C panic=abort TA_DEV_KIT_DIR=/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64
  Command: cargo build --target aarch64-unknown-linux-gnu --release --config target.aarch64-unknown-linux-gnu.linker="aarch64-linux-gnu-gcc"
Stripping binary...
Signing TA...
SIGN => 133af0ca-bdab-11eb-9130-43bf7873bf67
TA signed and saved to: "/teaclave/examples/hello_world-rs/ta/target/aarch64-unknown-linux-gnu/release/133af0ca-bdab-11eb-9130-43bf7873bf67.ta"
TA build successfully!

At this stage, we’ll focus on user-facing functionality and bug fixes. Please feel free to try out the tool and share your feedback, thanks!

@DemesneGH DemesneGH force-pushed the experimental-cargo-build branch 3 times, most recently from de40647 to fa5661b Compare November 13, 2025 13:03
- 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
@DemesneGH DemesneGH force-pushed the experimental-cargo-build branch from fa5661b to 383ef85 Compare November 14, 2025 06:47
@DemesneGH DemesneGH force-pushed the experimental-cargo-build branch from 383ef85 to b48f1cc Compare November 14, 2025 08:51
@DemesneGH
Copy link
Contributor Author

Updates:
The build and runtime tests now pass in the OP-TEE repo. The OP-TEE/build project requires the changes in this commit:
DemesneGH/build@806fafd
This confirms that the tool can be integrated into OP-TEE. I will open PRs in the OP-TEE repositories after our tool is merged.

Todos:

  • CI: add tests on ARM host
  • Documentation
  • Code review for inner logic
  • Functional testing and bug fixes

Pending:
*std: cargo-optee sets up the std environments and remove the Xargo.toml files from each example. This is not urgent and can likely be addressed in the next stage.

--
Planned to merge the initial version within the next two weeks.

@DemesneGH
Copy link
Contributor Author

@asir66 Could you help to try out the tool and share your feedback? Thanks!

@asir66
Copy link
Contributor

asir66 commented Nov 21, 2025

@asir66 Could you help to try out the tool and share your feedback? Thanks!

It's my pleasure. I'll test it and share my feedback.

@asir66
Copy link
Contributor

asir66 commented Nov 27, 2025

cargo-optee Testing Report and Findings

Below is a consolidated report of issues, observations, and suggestions identified during testing of cargo-optee in PR #245. I include reproducible examples, analysis, and potential directions for improvement.

1. Issue: std Flag Logic Bug

Description

The CLI parameter --std is parsed as a bool, and later converted into Option<bool> (cmd_std). However, the current logic contains an unintended behavior:

  • When the user does not pass --std, the default value std = false becomes Some(false)
  • As a result, cmd_std never becomes None
  • Therefore, BuildConfig::resolve() never falls back to the configuration defined in Cargo.toml

This causes the std parameter to never fall back to the configuration provided in Cargo.toml.

Quick Fix (tested and working)

Changing the following argument inside BuildConfig::resolve():

# cargo-optee/main.rs:79 
if std { Some(true) } else { None }

This restores correct fallback behavior, but it is only a temporary workaround.

Suggested Solutions

  1. Introduce explicit CLI flags:
    --std
    --no-std

  2. Or, treat std/no-std as features selection:
    --features std
    --features no-std

Feedback from maintainers would be appreciated; I am willing to contribute a proper solution.

2. Issue: --manifest-path Relative Path Resolution in mnist-rs

Description

I encountered an issue related to path resolution in cargo-optee. The behavior is inconsistent between mnist-rs and other examples such as hello_world-rs and acipher-rs. Since the root cause is not yet clear to me, I would like to ask for guidance or insights from the community.

Below are the reproducible cases.

  1. Case 1 — Running inside the Cargo.toml directory (hello_world-rs)

Cargo.toml is

...
[package.metadata.optee.ta]
arch = "arm"
std = true
uuid-path = "../uuid.txt"
ta-dev-kit-dir = { aarch64 = "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64", arm = "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm32" }

In hello_world-rs/ta/, running with:

root@05d55135aefe:~/teaclave_sdk_src/examples/hello_world-rs/ta# cargo-optee build ta --manifest-path ./Cargo.toml 
Building TA with:
  Arch: Arm
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm32"
  UUID path: "/root/teaclave_sdk_src/examples/hello_world-rs/uuid.txt"
Building TA in directory: /root/teaclave_sdk_src/examples/hello_world-rs/ta
Running cargo fmt and clippy...
^C
root@05d55135aefe:~/teaclave_sdk_src/examples/hello_world-rs/ta# cargo-optee build ta --manifest-path Cargo.toml 
Building TA with:
  Arch: Arm
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm32"
  UUID path: "/root/teaclave_sdk_src/examples/hello_world-rs/uuid.txt"
Building TA in directory: 
Running cargo fmt and clippy...
Error: No such file or directory (os error 2)

The metadata in Cargo.toml is parsed correctly (TA dev kit dir, UUID path are correct). But there is Error with No such file or directory (os error 2)

  1. There is diffierent between mnist-rs and hello_world-rs.

When ta-dev-kit-dir is correctly configured in the corresponding Cargo.toml, running the following command under mnist-rs produces the expected output:

root@05d55135aefe:~/teaclave_sdk_src/examples# cargo-optee build ta \
> --manifest-path mnist-rs/ta/train/Cargo.toml 
Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64"
  UUID path: "/root/teaclave_sdk_src/examples/mnist-rs/ta/train/uuid.txt"
Building TA in directory: /root/teaclave_sdk_src/examples/mnist-rs/ta/train
Running cargo fmt and clippy...
^C
root@05d55135aefe:~/teaclave_sdk_src/examples# cargo-optee build ta --manifest-path ./mnist-rs/ta/train/Cargo.toml            
Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  UUID path: "./mnist-rs/ta/train/../uuid.txt"
Error: ta-dev-kit-dir is MANDATORY but not configured.
Please set it via:
1. Command line: --ta-dev-kit-dir <path>
4. Cargo.toml metadata: [package.metadata.optee.ta] section

Example Cargo.toml:
[package.metadata.optee.ta]
ta-dev-kit-dir = { aarch64 = "/path/to/optee_os/out/arm-plat-vexpress/export-ta_arm64" }
# arm architecture omitted (defaults to null)

For help with available options, run: cargo-optee build ta --help

However, the same commands run correctly in hello_world-rs, as shown below:

root@05d55135aefe:~/teaclave_sdk_src/examples# cargo-optee build ta --manifest-path hello_world-rs/ta/Cargo.toml  
Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64"
  UUID path: "/root/teaclave_sdk_src/examples/hello_world-rs/uuid.txt"
Building TA in directory: /root/teaclave_sdk_src/examples/hello_world-rs/ta
Running cargo fmt and clippy...
^C
root@05d55135aefe:~/teaclave_sdk_src/examples# cargo-optee build ta --manifest-path ./hello_world-rs/ta/Cargo.toml 
Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64"
  UUID path: "/root/teaclave_sdk_src/examples/hello_world-rs/uuid.txt"
Building TA in directory: /root/teaclave_sdk_src/examples/hello_world-rs/ta
Running cargo fmt and clippy...

Initially, I suspected that this issue was related to how cargo-optee handles paths beginning with ./. However, since the same ./ usage works correctly in hello_world-rs, this no longer seems to be the case. I am therefore seeking help from the community to better understand the underlying cause.

3. TOML Metadata Formatting Issue

TOML does not support multiline inline tables, so we should change our README.md to:

ta-dev-kit-dir = { aarch64 = "...", arm = "..." }

4. Naming Consistency Suggestion

The project currently uses:

  1. host in examples, directory names and sync_to_emulator
  2. ca (“client application”) in cargo-optee

To improve clarity, it may be beneficial to standardize on a single naming convention across

This will help reduce confusion for new contributors.

5. Deprecation Suggestion for switch_config

Since cargo-optee now provides a unified and structured workflow for building and running components, the old switch_config flow may no longer be necessary.

Removing it could simplify the overall toolchain and documentation.

6. Test Results Summary

I tested all examples included in the repository:

  • All TAs build successfully with cargo-optee
  • All CA/host applications targeting aarch64 run correctly in QEMUv8
  • Aside from the issues mentioned above, I did not encounter additional problems

This suggests that the new cargo-optee integration is generally robust across the example suite. I think it's a good tool.

I would like to ask whether the project would benefit from having a Makefile under the examples/ directory to manage or build all examples together. Is this something we might need? Like examples/Makefile

pub struct BuildConfig {
pub arch: Arch,
pub debug: bool,
pub std: bool,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is an issue here: when --std is not provided, std defaults to false, so cmd_std becomes Some(false) instead of None.

@DemesneGH
Copy link
Contributor Author

DemesneGH commented Nov 27, 2025

@asir66 Thanks for your detailed and careful testing!

I encountered an issue related to path resolution in cargo-optee. The behavior is inconsistent between mnist-rs and other examples such as hello_world-rs and acipher-rs. Since the root cause is not yet clear to me, I would like to ask for guidance or insights from the community.

The mnist-rs have the workspace in mnist/ta/Cargo.toml, could you help to check if the issue related with this?

I would like to ask whether the project would benefit from having a Makefile under the examples/ directory to manage or build all examples together. Is this something we might need? Like examples/Makefile

The ci/build.sh performs as what original Makefile does, it reads the examples/metadata.json to get all app path of examples and build. Please also help to check if it enough for our use case?


For other recommendations:

  1. I'd prefer:
    Introduce explicit CLI flags:
    --std
    --no-std

3 and 4: LGTM.
Please help to fix the 1. 3. 4. thanks.

  1. The cargo-optee tool isn’t tied to the dev Docker image, so we can keep the current dev image unchanged and consider optimizing it later.
    However, if we merge this PR, our documentation and CI will need a full update.
    How about we add cargo-optee in this PR while keeping both the old Makefile system and the new tool? After this merged, we can update the docs and CI step by step, and remove the Makefiles once the new tool is stable and widely used. What do you think?

@m4sterchain
Copy link
Contributor

cargo-optee Testing Report and Findings

Below is a consolidated report of issues, observations, and suggestions identified during testing of cargo-optee in PR #245. I include reproducible examples, analysis, and potential directions for improvement.

1. Issue: std Flag Logic Bug

Description

The CLI parameter --std is parsed as a bool, and later converted into Option<bool> (cmd_std). However, the current logic contains an unintended behavior:

  • When the user does not pass --std, the default value std = false becomes Some(false)
  • As a result, cmd_std never becomes None
  • Therefore, BuildConfig::resolve() never falls back to the configuration defined in Cargo.toml

This causes the std parameter to never fall back to the configuration provided in Cargo.toml.

Quick Fix (tested and working)

Changing the following argument inside BuildConfig::resolve():

# cargo-optee/main.rs:79 
if std { Some(true) } else { None }

This restores correct fallback behavior, but it is only a temporary workaround.

Suggested Solutions

  1. Introduce explicit CLI flags:
    --std
    --no-std
  2. Or, treat std/no-std as features selection:
    --features std
    --features no-std

Feedback from maintainers would be appreciated; I am willing to contribute a proper solution.

2. Issue: --manifest-path Relative Path Resolution in mnist-rs

Description

I encountered an issue related to path resolution in cargo-optee. The behavior is inconsistent between mnist-rs and other examples such as hello_world-rs and acipher-rs. Since the root cause is not yet clear to me, I would like to ask for guidance or insights from the community.

Below are the reproducible cases.

  1. Case 1 — Running inside the Cargo.toml directory (hello_world-rs)

Cargo.toml is

...
[package.metadata.optee.ta]
arch = "arm"
std = true
uuid-path = "../uuid.txt"
ta-dev-kit-dir = { aarch64 = "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64", arm = "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm32" }

In hello_world-rs/ta/, running with:

root@05d55135aefe:~/teaclave_sdk_src/examples/hello_world-rs/ta# cargo-optee build ta --manifest-path ./Cargo.toml 
Building TA with:
  Arch: Arm
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm32"
  UUID path: "/root/teaclave_sdk_src/examples/hello_world-rs/uuid.txt"
Building TA in directory: /root/teaclave_sdk_src/examples/hello_world-rs/ta
Running cargo fmt and clippy...
^C
root@05d55135aefe:~/teaclave_sdk_src/examples/hello_world-rs/ta# cargo-optee build ta --manifest-path Cargo.toml 
Building TA with:
  Arch: Arm
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm32"
  UUID path: "/root/teaclave_sdk_src/examples/hello_world-rs/uuid.txt"
Building TA in directory: 
Running cargo fmt and clippy...
Error: No such file or directory (os error 2)

The metadata in Cargo.toml is parsed correctly (TA dev kit dir, UUID path are correct). But there is Error with No such file or directory (os error 2)

  1. There is diffierent between mnist-rs and hello_world-rs.

When ta-dev-kit-dir is correctly configured in the corresponding Cargo.toml, running the following command under mnist-rs produces the expected output:

root@05d55135aefe:~/teaclave_sdk_src/examples# cargo-optee build ta \
> --manifest-path mnist-rs/ta/train/Cargo.toml 
Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64"
  UUID path: "/root/teaclave_sdk_src/examples/mnist-rs/ta/train/uuid.txt"
Building TA in directory: /root/teaclave_sdk_src/examples/mnist-rs/ta/train
Running cargo fmt and clippy...
^C
root@05d55135aefe:~/teaclave_sdk_src/examples# cargo-optee build ta --manifest-path ./mnist-rs/ta/train/Cargo.toml            
Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  UUID path: "./mnist-rs/ta/train/../uuid.txt"
Error: ta-dev-kit-dir is MANDATORY but not configured.
Please set it via:
1. Command line: --ta-dev-kit-dir <path>
4. Cargo.toml metadata: [package.metadata.optee.ta] section

Example Cargo.toml:
[package.metadata.optee.ta]
ta-dev-kit-dir = { aarch64 = "/path/to/optee_os/out/arm-plat-vexpress/export-ta_arm64" }
# arm architecture omitted (defaults to null)

For help with available options, run: cargo-optee build ta --help

However, the same commands run correctly in hello_world-rs, as shown below:

root@05d55135aefe:~/teaclave_sdk_src/examples# cargo-optee build ta --manifest-path hello_world-rs/ta/Cargo.toml  
Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64"
  UUID path: "/root/teaclave_sdk_src/examples/hello_world-rs/uuid.txt"
Building TA in directory: /root/teaclave_sdk_src/examples/hello_world-rs/ta
Running cargo fmt and clippy...
^C
root@05d55135aefe:~/teaclave_sdk_src/examples# cargo-optee build ta --manifest-path ./hello_world-rs/ta/Cargo.toml 
Building TA with:
  Arch: Aarch64
  Debug: false
  Std: false
  TA dev kit dir: "/opt/teaclave/optee/optee_os/out/arm-plat-vexpress/export-ta_arm64"
  UUID path: "/root/teaclave_sdk_src/examples/hello_world-rs/uuid.txt"
Building TA in directory: /root/teaclave_sdk_src/examples/hello_world-rs/ta
Running cargo fmt and clippy...

Initially, I suspected that this issue was related to how cargo-optee handles paths beginning with ./. However, since the same ./ usage works correctly in hello_world-rs, this no longer seems to be the case. I am therefore seeking help from the community to better understand the underlying cause.

3. TOML Metadata Formatting Issue

TOML does not support multiline inline tables, so we should change our README.md to:

ta-dev-kit-dir = { aarch64 = "...", arm = "..." }

4. Naming Consistency Suggestion

The project currently uses:

  1. host in examples, directory names and sync_to_emulator
  2. ca (“client application”) in cargo-optee

To improve clarity, it may be beneficial to standardize on a single naming convention across

This will help reduce confusion for new contributors.

5. Deprecation Suggestion for switch_config

Since cargo-optee now provides a unified and structured workflow for building and running components, the old switch_config flow may no longer be necessary.

Removing it could simplify the overall toolchain and documentation.

6. Test Results Summary

I tested all examples included in the repository:

  • All TAs build successfully with cargo-optee
  • All CA/host applications targeting aarch64 run correctly in QEMUv8
  • Aside from the issues mentioned above, I did not encounter additional problems

This suggests that the new cargo-optee integration is generally robust across the example suite. I think it's a good tool.

I would like to ask whether the project would benefit from having a Makefile under the examples/ directory to manage or build all examples together. Is this something we might need? Like examples/Makefile

Hi @asir66 thanks for the effort. Please take my previous comment (#245 (comment) compare the current cargo optee subcommand with existing cargo conventions.
If possible, could you help list all the areas where the current implementation violates or diverges from standard cargo behavior? Once we have this list, we can decide whether to fix them within this PR or address them in a series of follow-up PRs before publishing to crates.io.

A few highlights from my earlier comment for reference:

  • Project configuration should stay in each project’s Cargo.toml. Toolchain configuration (e.g., ta-dev-kit-dir) should be managed by a dedicated subcommand such as cargo optee setup, instead of being mixed into project config.
  • std / no_std selection should be inferred automatically from the active feature set, consistent with how existing cargo workflows behave.

Thanks in advance.

@asir66
Copy link
Contributor

asir66 commented Nov 27, 2025

@asir66 Thanks for your detailed and careful testing!

I encountered an issue related to path resolution in cargo-optee. The behavior is inconsistent between mnist-rs and other examples such as hello_world-rs and acipher-rs. Since the root cause is not yet clear to me, I would like to ask for guidance or insights from the community.

The mnist-rs have the workspace in mnist/ta/Cargo.toml, could you help to check if the issue related with this?

I would like to ask whether the project would benefit from having a Makefile under the examples/ directory to manage or build all examples together. Is this something we might need? Like examples/Makefile

The ci/build.sh performs as what original Makefile does, it reads the examples/metadata.json to get all app path of examples and build. Please also help to check if it enough for our use case?

For other recommendations:

  1. I'd prefer:
    Introduce explicit CLI flags:
    --std
    --no-std

3 and 4: LGTM. Please help to fix the 1. 3. 4. thanks.

It’s my pleasure — I’d be glad to work on that.
By the way, could you clarify whether we should use host or ca in this project?

  1. The cargo-optee tool isn’t tied to the dev Docker image, so we can keep the current dev image unchanged and consider optimizing it later.
    However, if we merge this PR, our documentation and CI will need a full update.
    How about we add cargo-optee in this PR while keeping both the old Makefile system and the new tool? After this merged, we can update the docs and CI step by step, and remove the Makefiles once the new tool is stable and widely used. What do you think?

LGTM! I think this approach is great — it allows users to transition smoothly from the old Makefile workflow to the new tool.

@asir66
Copy link
Contributor

asir66 commented Nov 27, 2025

Hi @asir66 thanks for the effort. Please take my previous comment (#245 (comment) compare the current cargo optee subcommand with existing cargo conventions. If possible, could you help list all the areas where the current implementation violates or diverges from standard cargo behavior? Once we have this list, we can decide whether to fix them within this PR or address them in a series of follow-up PRs before publishing to crates.io.

A few highlights from my earlier comment for reference:

  • Project configuration should stay in each project’s Cargo.toml. Toolchain configuration (e.g., ta-dev-kit-dir) should be managed by a dedicated subcommand such as cargo optee setup, instead of being mixed into project config.
  • std / no_std selection should be inferred automatically from the active feature set, consistent with how existing cargo workflows behave.

Thanks in advance.

I’ll do my best to review these areas and put together a comprehensive list of the differences from standard cargo conventions.

@DemesneGH
Copy link
Contributor Author

could you clarify whether we should use host or ca in this project?

@asir66 Let's use host which also aligns with optee C examples https://github.com/linaro-swg/optee_examples/tree/master/acipher

@DemesneGH
Copy link
Contributor Author

Closing this draft PR and continuing the work in #263

@DemesneGH DemesneGH closed this Dec 19, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants