You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@teaclave.apache.org by yu...@apache.org on 2025/01/02 03:44:35 UTC

(incubator-teaclave-trustzone-sdk) branch main updated: examples: use optee-utee-build to build TA

This is an automated email from the ASF dual-hosted git repository.

yuanz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/incubator-teaclave-trustzone-sdk.git


The following commit(s) were added to refs/heads/main by this push:
     new 8e8b8af  examples: use optee-utee-build to build TA
8e8b8af is described below

commit 8e8b8af28b8dae9673d69f76e352a4d2bcd0687f
Author: ivila <39...@qq.com>
AuthorDate: Tue Dec 31 14:13:18 2024 +0800

    examples: use optee-utee-build to build TA
    
    Signed-off-by: ivila <39...@qq.com>
    Reviewed-by: Sumit Garg <su...@linaro.org>
    Reviewed-by: Yuan Zhuang <yu...@apache.org>
---
 examples/acipher-rs/ta/Cargo.toml                  |   4 +-
 examples/acipher-rs/ta/Makefile                    |   3 +-
 examples/acipher-rs/ta/build.rs                    |  87 +-----------------
 examples/acipher-rs/ta/src/main.rs                 |  12 ---
 examples/acipher-rs/ta/ta_static.rs                | 102 ---------------------
 examples/aes-rs/ta/Cargo.toml                      |   4 +-
 examples/aes-rs/ta/Makefile                        |   3 +-
 examples/aes-rs/ta/build.rs                        |  87 +-----------------
 examples/aes-rs/ta/src/main.rs                     |  11 ---
 examples/aes-rs/ta/ta_static.rs                    | 102 ---------------------
 examples/authentication-rs/ta/Cargo.toml           |   4 +-
 examples/authentication-rs/ta/Makefile             |   3 +-
 examples/authentication-rs/ta/build.rs             |  87 +-----------------
 examples/authentication-rs/ta/src/main.rs          |  12 ---
 examples/authentication-rs/ta/ta_static.rs         | 102 ---------------------
 examples/big_int-rs/ta/Cargo.toml                  |   4 +-
 examples/big_int-rs/ta/Makefile                    |   3 +-
 examples/big_int-rs/ta/build.rs                    |  87 +-----------------
 examples/big_int-rs/ta/src/main.rs                 |  12 ---
 examples/big_int-rs/ta/ta_static.rs                | 102 ---------------------
 examples/diffie_hellman-rs/ta/Cargo.toml           |   4 +-
 examples/diffie_hellman-rs/ta/Makefile             |   3 +-
 examples/diffie_hellman-rs/ta/build.rs             |  87 +-----------------
 examples/diffie_hellman-rs/ta/src/main.rs          |  12 ---
 examples/diffie_hellman-rs/ta/ta_static.rs         | 102 ---------------------
 examples/digest-rs/ta/Cargo.toml                   |   4 +-
 examples/digest-rs/ta/Makefile                     |   3 +-
 examples/digest-rs/ta/build.rs                     |  87 +-----------------
 examples/digest-rs/ta/src/main.rs                  |  12 ---
 examples/digest-rs/ta/ta_static.rs                 | 102 ---------------------
 examples/error_handling-rs/ta/Cargo.toml           |   4 +-
 examples/error_handling-rs/ta/Makefile             |   3 +-
 examples/error_handling-rs/ta/build.rs             |  87 +-----------------
 examples/error_handling-rs/ta/src/main.rs          |  12 ---
 examples/error_handling-rs/ta/ta_static.rs         | 102 ---------------------
 examples/hotp-rs/ta/Cargo.toml                     |   4 +-
 examples/hotp-rs/ta/Makefile                       |   3 +-
 examples/hotp-rs/ta/build.rs                       |  87 +-----------------
 examples/hotp-rs/ta/src/main.rs                    |  12 ---
 examples/hotp-rs/ta/ta_static.rs                   | 102 ---------------------
 .../message_passing_interface-rs/ta/Cargo.toml     |   2 +-
 examples/message_passing_interface-rs/ta/Makefile  |   3 +-
 examples/message_passing_interface-rs/ta/build.rs  |  89 ++----------------
 .../message_passing_interface-rs/ta/src/main.rs    |  12 ---
 .../message_passing_interface-rs/ta/ta_static.rs   | 102 ---------------------
 examples/random-rs/ta/Cargo.toml                   |   4 +-
 examples/random-rs/ta/Makefile                     |   3 +-
 examples/random-rs/ta/build.rs                     |  87 +-----------------
 examples/random-rs/ta/src/main.rs                  |  12 ---
 examples/random-rs/ta/ta_static.rs                 | 102 ---------------------
 examples/secure_storage-rs/ta/Cargo.toml           |   4 +-
 examples/secure_storage-rs/ta/Makefile             |   3 +-
 examples/secure_storage-rs/ta/build.rs             |  87 +-----------------
 examples/secure_storage-rs/ta/src/main.rs          |  12 ---
 examples/secure_storage-rs/ta/ta_static.rs         | 102 ---------------------
 examples/serde-rs/ta/Cargo.toml                    |   4 +-
 examples/serde-rs/ta/Makefile                      |   3 +-
 examples/serde-rs/ta/build.rs                      |  89 ++----------------
 examples/serde-rs/ta/src/main.rs                   |  12 ---
 examples/serde-rs/ta/ta_static.rs                  | 102 ---------------------
 examples/signature_verification-rs/ta/Cargo.toml   |   4 +-
 examples/signature_verification-rs/ta/Makefile     |   3 +-
 examples/signature_verification-rs/ta/build.rs     |  87 +-----------------
 examples/signature_verification-rs/ta/src/main.rs  |  12 ---
 examples/signature_verification-rs/ta/ta_static.rs | 102 ---------------------
 examples/supp_plugin-rs/ta/Cargo.toml              |   4 +-
 examples/supp_plugin-rs/ta/Makefile                |   3 +-
 examples/supp_plugin-rs/ta/build.rs                |  87 +-----------------
 examples/supp_plugin-rs/ta/src/main.rs             |  12 ---
 examples/supp_plugin-rs/ta/ta_static.rs            | 102 ---------------------
 examples/tcp_client-rs/ta/Cargo.toml               |   2 +-
 examples/tcp_client-rs/ta/Makefile                 |   3 +-
 examples/tcp_client-rs/ta/build.rs                 |  89 ++----------------
 examples/tcp_client-rs/ta/src/main.rs              |  12 ---
 examples/tcp_client-rs/ta/ta_static.rs             | 102 ---------------------
 examples/time-rs/ta/Cargo.toml                     |   4 +-
 examples/time-rs/ta/Makefile                       |   3 +-
 examples/time-rs/ta/build.rs                       |  87 +-----------------
 examples/time-rs/ta/src/main.rs                    |  11 ---
 examples/time-rs/ta/ta_static.rs                   | 102 ---------------------
 examples/tls_client-rs/ta/Cargo.toml               |   4 +-
 examples/tls_client-rs/ta/Makefile                 |   3 +-
 examples/tls_client-rs/ta/build.rs                 |  89 ++----------------
 examples/tls_client-rs/ta/src/main.rs              |  12 ---
 examples/tls_client-rs/ta/ta_static.rs             | 102 ---------------------
 examples/tls_server-rs/ta/Cargo.toml               |   2 +-
 examples/tls_server-rs/ta/Makefile                 |   3 +-
 examples/tls_server-rs/ta/build.rs                 |  89 ++----------------
 examples/tls_server-rs/ta/src/main.rs              |  12 ---
 examples/tls_server-rs/ta/ta_static.rs             | 102 ---------------------
 examples/udp_socket-rs/ta/Cargo.toml               |   2 +-
 examples/udp_socket-rs/ta/Makefile                 |   3 +-
 examples/udp_socket-rs/ta/build.rs                 |  89 ++----------------
 examples/udp_socket-rs/ta/src/main.rs              |  12 ---
 examples/udp_socket-rs/ta/ta_static.rs             | 102 ---------------------
 95 files changed, 160 insertions(+), 3794 deletions(-)

diff --git a/examples/acipher-rs/ta/Cargo.toml b/examples/acipher-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/acipher-rs/ta/Cargo.toml
+++ b/examples/acipher-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/acipher-rs/ta/Makefile b/examples/acipher-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/acipher-rs/ta/Makefile
+++ b/examples/acipher-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/acipher-rs/ta/build.rs b/examples/acipher-rs/ta/build.rs
index fa0d195..971f3d5 100644
--- a/examples/acipher-rs/ta/build.rs
+++ b/examples/acipher-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/acipher-rs/ta/src/main.rs b/examples/acipher-rs/ta/src/main.rs
index 8418e07..1f26df0 100644
--- a/examples/acipher-rs/ta/src/main.rs
+++ b/examples/acipher-rs/ta/src/main.rs
@@ -137,16 +137,4 @@ fn invoke_command(sess_ctx: &mut RsaCipher, cmd_id: u32, params: &mut Parameters
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"Example of TA using asymmetric cipher.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Acipher TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/acipher-rs/ta/ta_static.rs b/examples/acipher-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/acipher-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/aes-rs/ta/Cargo.toml b/examples/aes-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/aes-rs/ta/Cargo.toml
+++ b/examples/aes-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/aes-rs/ta/Makefile b/examples/aes-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/aes-rs/ta/Makefile
+++ b/examples/aes-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/aes-rs/ta/build.rs b/examples/aes-rs/ta/build.rs
index fa0d195..be45a97 100644
--- a/examples/aes-rs/ta/build.rs
+++ b/examples/aes-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, config)
 }
diff --git a/examples/aes-rs/ta/src/main.rs b/examples/aes-rs/ta/src/main.rs
index 7161285..669863c 100644
--- a/examples/aes-rs/ta/src/main.rs
+++ b/examples/aes-rs/ta/src/main.rs
@@ -185,15 +185,4 @@ pub fn cipher_buffer(aes: &mut AesCipher, params: &mut Parameters) -> Result<()>
     Ok(())
 }
 
-const TA_FLAGS: u32 = 0;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_DATA_SIZE: u32 = 1 * 1024 * 1024;
-const TA_VERSION: &[u8] = b"Undefined version\0";
-const TA_DESCRIPTION: &[u8] = b"This is an AES example\0";
-const EXT_PROP_VALUE_1: &[u8] = b"AES TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/aes-rs/ta/ta_static.rs b/examples/aes-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/aes-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/authentication-rs/ta/Cargo.toml b/examples/authentication-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/authentication-rs/ta/Cargo.toml
+++ b/examples/authentication-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/authentication-rs/ta/Makefile b/examples/authentication-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/authentication-rs/ta/Makefile
+++ b/examples/authentication-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/authentication-rs/ta/build.rs b/examples/authentication-rs/ta/build.rs
index fa0d195..be45a97 100644
--- a/examples/authentication-rs/ta/build.rs
+++ b/examples/authentication-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, config)
 }
diff --git a/examples/authentication-rs/ta/src/main.rs b/examples/authentication-rs/ta/src/main.rs
index 247aa6b..d05b5e8 100644
--- a/examples/authentication-rs/ta/src/main.rs
+++ b/examples/authentication-rs/ta/src/main.rs
@@ -176,16 +176,4 @@ pub fn decrypt_final(digest: &mut AEOp, params: &mut Parameters) -> Result<()> {
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is an authentication encryption example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"AE TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/authentication-rs/ta/ta_static.rs b/examples/authentication-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/authentication-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/big_int-rs/ta/Cargo.toml b/examples/big_int-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/big_int-rs/ta/Cargo.toml
+++ b/examples/big_int-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/big_int-rs/ta/Makefile b/examples/big_int-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/big_int-rs/ta/Makefile
+++ b/examples/big_int-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/big_int-rs/ta/build.rs b/examples/big_int-rs/ta/build.rs
index fa0d195..be45a97 100644
--- a/examples/big_int-rs/ta/build.rs
+++ b/examples/big_int-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, config)
 }
diff --git a/examples/big_int-rs/ta/src/main.rs b/examples/big_int-rs/ta/src/main.rs
index 01ae6f0..4c9b4a3 100644
--- a/examples/big_int-rs/ta/src/main.rs
+++ b/examples/big_int-rs/ta/src/main.rs
@@ -120,16 +120,4 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"Example of TA using arithmeitcal APIs.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Big int TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/big_int-rs/ta/ta_static.rs b/examples/big_int-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/big_int-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/diffie_hellman-rs/ta/Cargo.toml b/examples/diffie_hellman-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/diffie_hellman-rs/ta/Cargo.toml
+++ b/examples/diffie_hellman-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/diffie_hellman-rs/ta/Makefile b/examples/diffie_hellman-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/diffie_hellman-rs/ta/Makefile
+++ b/examples/diffie_hellman-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/diffie_hellman-rs/ta/build.rs b/examples/diffie_hellman-rs/ta/build.rs
index fa0d195..be45a97 100644
--- a/examples/diffie_hellman-rs/ta/build.rs
+++ b/examples/diffie_hellman-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, config)
 }
diff --git a/examples/diffie_hellman-rs/ta/src/main.rs b/examples/diffie_hellman-rs/ta/src/main.rs
index 7a08abc..87c7139 100644
--- a/examples/diffie_hellman-rs/ta/src/main.rs
+++ b/examples/diffie_hellman-rs/ta/src/main.rs
@@ -138,16 +138,4 @@ fn invoke_command(
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is an example which serves DH related functions.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"DH TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/diffie_hellman-rs/ta/ta_static.rs b/examples/diffie_hellman-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/diffie_hellman-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/digest-rs/ta/Cargo.toml b/examples/digest-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/digest-rs/ta/Cargo.toml
+++ b/examples/digest-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/digest-rs/ta/Makefile b/examples/digest-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/digest-rs/ta/Makefile
+++ b/examples/digest-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/digest-rs/ta/build.rs b/examples/digest-rs/ta/build.rs
index fa0d195..be45a97 100644
--- a/examples/digest-rs/ta/build.rs
+++ b/examples/digest-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, config)
 }
diff --git a/examples/digest-rs/ta/src/main.rs b/examples/digest-rs/ta/src/main.rs
index 1cc159e..abd9b56 100644
--- a/examples/digest-rs/ta/src/main.rs
+++ b/examples/digest-rs/ta/src/main.rs
@@ -100,16 +100,4 @@ pub fn do_final(digest: &mut DigestOp, params: &mut Parameters) -> Result<()> {
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is a message digest example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Digest TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/digest-rs/ta/ta_static.rs b/examples/digest-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/digest-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/error_handling-rs/ta/Cargo.toml b/examples/error_handling-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/error_handling-rs/ta/Cargo.toml
+++ b/examples/error_handling-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/error_handling-rs/ta/Makefile b/examples/error_handling-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/error_handling-rs/ta/Makefile
+++ b/examples/error_handling-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/error_handling-rs/ta/build.rs b/examples/error_handling-rs/ta/build.rs
index fa0d195..be45a97 100644
--- a/examples/error_handling-rs/ta/build.rs
+++ b/examples/error_handling-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, config)
 }
diff --git a/examples/error_handling-rs/ta/src/main.rs b/examples/error_handling-rs/ta/src/main.rs
index 755e5af..ed32513 100644
--- a/examples/error_handling-rs/ta/src/main.rs
+++ b/examples/error_handling-rs/ta/src/main.rs
@@ -78,16 +78,4 @@ fn invoke_command(
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is a TA for error handling tests.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Error handling TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/error_handling-rs/ta/ta_static.rs b/examples/error_handling-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/error_handling-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/hotp-rs/ta/Cargo.toml b/examples/hotp-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/hotp-rs/ta/Cargo.toml
+++ b/examples/hotp-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/hotp-rs/ta/Makefile b/examples/hotp-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/hotp-rs/ta/Makefile
+++ b/examples/hotp-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/hotp-rs/ta/build.rs b/examples/hotp-rs/ta/build.rs
index fa0d195..be45a97 100644
--- a/examples/hotp-rs/ta/build.rs
+++ b/examples/hotp-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, config)
 }
diff --git a/examples/hotp-rs/ta/src/main.rs b/examples/hotp-rs/ta/src/main.rs
index 2d20f72..c8792fb 100644
--- a/examples/hotp-rs/ta/src/main.rs
+++ b/examples/hotp-rs/ta/src/main.rs
@@ -155,16 +155,4 @@ pub fn truncate(hmac_result: &mut [u8]) -> u32 {
     return bin_code;
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is an HOTP example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"HOTP TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/hotp-rs/ta/ta_static.rs b/examples/hotp-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/hotp-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/message_passing_interface-rs/ta/Cargo.toml b/examples/message_passing_interface-rs/ta/Cargo.toml
index bc84153..fce4cb4 100644
--- a/examples/message_passing_interface-rs/ta/Cargo.toml
+++ b/examples/message_passing_interface-rs/ta/Cargo.toml
@@ -30,8 +30,8 @@ optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
 [build-dependencies]
-uuid = { version = "1.8", default-features = false }
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/message_passing_interface-rs/ta/Makefile b/examples/message_passing_interface-rs/ta/Makefile
index 7e826ed..42d9236 100644
--- a/examples/message_passing_interface-rs/ta/Makefile
+++ b/examples/message_passing_interface-rs/ta/Makefile
@@ -22,7 +22,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/message_passing_interface-rs/ta/build.rs b/examples/message_passing_interface-rs/ta/build.rs
index fa0d195..8f3b407 100644
--- a/examples/message_passing_interface-rs/ta/build.rs
+++ b/examples/message_passing_interface-rs/ta/build.rs
@@ -16,88 +16,11 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let config = TaConfig::new_default_with_cargo_env(proto::UUID)?
+        .ta_data_size(64 * 1024)
+        .ta_stack_size(4 * 1024);
+    optee_utee_build::build(RustEdition::Before2024, config)
 }
diff --git a/examples/message_passing_interface-rs/ta/src/main.rs b/examples/message_passing_interface-rs/ta/src/main.rs
index 5b9f361..d31db04 100644
--- a/examples/message_passing_interface-rs/ta/src/main.rs
+++ b/examples/message_passing_interface-rs/ta/src/main.rs
@@ -81,16 +81,4 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
     Ok(())
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 64 * 1024;
-const TA_STACK_SIZE: u32 = 4 * 1024;
-const TA_VERSION: &[u8] = b"0.3\0";
-const TA_DESCRIPTION: &[u8] = b"This is a message passing example using json.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Hello World TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/message_passing_interface-rs/ta/ta_static.rs b/examples/message_passing_interface-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/message_passing_interface-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/random-rs/ta/Cargo.toml b/examples/random-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/random-rs/ta/Cargo.toml
+++ b/examples/random-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/random-rs/ta/Makefile b/examples/random-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/random-rs/ta/Makefile
+++ b/examples/random-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/random-rs/ta/build.rs b/examples/random-rs/ta/build.rs
index fa0d195..971f3d5 100644
--- a/examples/random-rs/ta/build.rs
+++ b/examples/random-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/random-rs/ta/src/main.rs b/examples/random-rs/ta/src/main.rs
index b419b28..cffdb77 100644
--- a/examples/random-rs/ta/src/main.rs
+++ b/examples/random-rs/ta/src/main.rs
@@ -74,16 +74,4 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is a random generator example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Random TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/random-rs/ta/ta_static.rs b/examples/random-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/random-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/secure_storage-rs/ta/Cargo.toml b/examples/secure_storage-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/secure_storage-rs/ta/Cargo.toml
+++ b/examples/secure_storage-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/secure_storage-rs/ta/Makefile b/examples/secure_storage-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/secure_storage-rs/ta/Makefile
+++ b/examples/secure_storage-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/secure_storage-rs/ta/build.rs b/examples/secure_storage-rs/ta/build.rs
index fa0d195..971f3d5 100644
--- a/examples/secure_storage-rs/ta/build.rs
+++ b/examples/secure_storage-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/secure_storage-rs/ta/src/main.rs b/examples/secure_storage-rs/ta/src/main.rs
index f1bc47f..4ca534f 100644
--- a/examples/secure_storage-rs/ta/src/main.rs
+++ b/examples/secure_storage-rs/ta/src/main.rs
@@ -168,16 +168,4 @@ pub fn read_raw_object(params: &mut Parameters) -> Result<()> {
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is a secure storage example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Secure Storage TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/secure_storage-rs/ta/ta_static.rs b/examples/secure_storage-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/secure_storage-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/serde-rs/ta/Cargo.toml b/examples/serde-rs/ta/Cargo.toml
index be7cea8..3167041 100644
--- a/examples/serde-rs/ta/Cargo.toml
+++ b/examples/serde-rs/ta/Cargo.toml
@@ -31,9 +31,9 @@ optee-utee = { path = "../../../optee-utee" }
 serde = { version = "1.0", features = ["derive"] }
 serde_json = "1.0"
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/serde-rs/ta/Makefile b/examples/serde-rs/ta/Makefile
index 7e826ed..42d9236 100644
--- a/examples/serde-rs/ta/Makefile
+++ b/examples/serde-rs/ta/Makefile
@@ -22,7 +22,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/serde-rs/ta/build.rs b/examples/serde-rs/ta/build.rs
index fa0d195..cab18cc 100644
--- a/examples/serde-rs/ta/build.rs
+++ b/examples/serde-rs/ta/build.rs
@@ -16,88 +16,11 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?
+        .ta_stack_size(4 * 1024)
+        .ta_data_size(64 * 1024);
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/serde-rs/ta/src/main.rs b/examples/serde-rs/ta/src/main.rs
index 19ed02e..9a796d8 100644
--- a/examples/serde-rs/ta/src/main.rs
+++ b/examples/serde-rs/ta/src/main.rs
@@ -84,16 +84,4 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 64 * 1024;
-const TA_STACK_SIZE: u32 = 4 * 1024;
-const TA_VERSION: &[u8] = b"0.3\0";
-const TA_DESCRIPTION: &[u8] = b"This is a serde example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Serde TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/serde-rs/ta/ta_static.rs b/examples/serde-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/serde-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/signature_verification-rs/ta/Cargo.toml b/examples/signature_verification-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/signature_verification-rs/ta/Cargo.toml
+++ b/examples/signature_verification-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/signature_verification-rs/ta/Makefile b/examples/signature_verification-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/signature_verification-rs/ta/Makefile
+++ b/examples/signature_verification-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/signature_verification-rs/ta/build.rs b/examples/signature_verification-rs/ta/build.rs
index fa0d195..971f3d5 100644
--- a/examples/signature_verification-rs/ta/build.rs
+++ b/examples/signature_verification-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/signature_verification-rs/ta/src/main.rs b/examples/signature_verification-rs/ta/src/main.rs
index cc03b89..d2bd115 100644
--- a/examples/signature_verification-rs/ta/src/main.rs
+++ b/examples/signature_verification-rs/ta/src/main.rs
@@ -177,16 +177,4 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 4 * 1024 * 1024;
-const TA_STACK_SIZE: u32 = 4 * 1024;
-const TA_VERSION: &[u8] = b"0.2\0";
-const TA_DESCRIPTION: &[u8] = b"This is a signature verification example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Signature Verification TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/signature_verification-rs/ta/ta_static.rs b/examples/signature_verification-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/signature_verification-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/supp_plugin-rs/ta/Cargo.toml b/examples/supp_plugin-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/supp_plugin-rs/ta/Cargo.toml
+++ b/examples/supp_plugin-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/supp_plugin-rs/ta/Makefile b/examples/supp_plugin-rs/ta/Makefile
index 640450d..1b16c21 100644
--- a/examples/supp_plugin-rs/ta/Makefile
+++ b/examples/supp_plugin-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../ta_uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/supp_plugin-rs/ta/build.rs b/examples/supp_plugin-rs/ta/build.rs
index 7d43891..9bc612a 100644
--- a/examples/supp_plugin-rs/ta/build.rs
+++ b/examples/supp_plugin-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::TA_UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::TA_UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/supp_plugin-rs/ta/src/main.rs b/examples/supp_plugin-rs/ta/src/main.rs
index c1b4a79..7ae4853 100644
--- a/examples/supp_plugin-rs/ta/src/main.rs
+++ b/examples/supp_plugin-rs/ta/src/main.rs
@@ -75,16 +75,4 @@ fn invoke_command(cmd_id: u32, params: &mut Parameters) -> Result<()> {
     }
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is a plugin example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Plugin TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/supp_plugin-rs/ta/ta_static.rs b/examples/supp_plugin-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/supp_plugin-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/tcp_client-rs/ta/Cargo.toml b/examples/tcp_client-rs/ta/Cargo.toml
index bc84153..fce4cb4 100644
--- a/examples/tcp_client-rs/ta/Cargo.toml
+++ b/examples/tcp_client-rs/ta/Cargo.toml
@@ -30,8 +30,8 @@ optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
 [build-dependencies]
-uuid = { version = "1.8", default-features = false }
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/tcp_client-rs/ta/Makefile b/examples/tcp_client-rs/ta/Makefile
index 7e826ed..42d9236 100644
--- a/examples/tcp_client-rs/ta/Makefile
+++ b/examples/tcp_client-rs/ta/Makefile
@@ -22,7 +22,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/tcp_client-rs/ta/build.rs b/examples/tcp_client-rs/ta/build.rs
index fa0d195..3f1e2a7 100644
--- a/examples/tcp_client-rs/ta/build.rs
+++ b/examples/tcp_client-rs/ta/build.rs
@@ -16,88 +16,11 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?
+        .ta_data_size(1 * 1024 * 1024)
+        .ta_stack_size(2 * 1024 * 1024);
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/tcp_client-rs/ta/src/main.rs b/examples/tcp_client-rs/ta/src/main.rs
index e871224..bc3a2b8 100644
--- a/examples/tcp_client-rs/ta/src/main.rs
+++ b/examples/tcp_client-rs/ta/src/main.rs
@@ -80,16 +80,4 @@ fn tcp_client() {
     trace_println!("{}", String::from_utf8_lossy(&response));
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 1 * 1024 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
-const TA_VERSION: &[u8] = b"0.3\0";
-const TA_DESCRIPTION: &[u8] = b"This is a tcp client example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Hello World TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/tcp_client-rs/ta/ta_static.rs b/examples/tcp_client-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/tcp_client-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/time-rs/ta/Cargo.toml b/examples/time-rs/ta/Cargo.toml
index badab89..d272b6f 100644
--- a/examples/time-rs/ta/Cargo.toml
+++ b/examples/time-rs/ta/Cargo.toml
@@ -29,9 +29,9 @@ proto = { path = "../proto" }
 optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
-[build_dependencies]
-uuid = { version = "1.6.1", default-features = false }
+[build-dependencies]
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/time-rs/ta/Makefile b/examples/time-rs/ta/Makefile
index 72a9cb3..029e66d 100644
--- a/examples/time-rs/ta/Makefile
+++ b/examples/time-rs/ta/Makefile
@@ -20,7 +20,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/time-rs/ta/build.rs b/examples/time-rs/ta/build.rs
index fa0d195..971f3d5 100644
--- a/examples/time-rs/ta/build.rs
+++ b/examples/time-rs/ta/build.rs
@@ -16,88 +16,9 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?;
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/time-rs/ta/src/main.rs b/examples/time-rs/ta/src/main.rs
index 9ec91da..8fa6db7 100644
--- a/examples/time-rs/ta/src/main.rs
+++ b/examples/time-rs/ta/src/main.rs
@@ -74,16 +74,5 @@ fn time() -> Result<()> {
     trace_println!("[+] After set the TA time 5 seconds ahead of system time, new TA time {}.", time2);
     Ok(())
 }
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 32 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024;
-const TA_VERSION: &[u8] = b"0.1\0";
-const TA_DESCRIPTION: &[u8] = b"This is a time API example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Time TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
 
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/time-rs/ta/ta_static.rs b/examples/time-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/time-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/tls_client-rs/ta/Cargo.toml b/examples/tls_client-rs/ta/Cargo.toml
index 353b704..3740901 100644
--- a/examples/tls_client-rs/ta/Cargo.toml
+++ b/examples/tls_client-rs/ta/Cargo.toml
@@ -38,8 +38,8 @@ webpki = "=0.21.0"
 sct = "=0.7.0"
 
 [build-dependencies]
-uuid = { version = "1.8", default-features = false }
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
@@ -51,4 +51,4 @@ ring = { git = "https://github.com/DemesneGH/ring-optee.git", branch = "0.16.20-
 
 # Patch optee-utee for rustls
 [patch."https://github.com/apache/incubator-teaclave-trustzone-sdk.git"]
-optee-utee = { path = "../../../optee-utee" }
\ No newline at end of file
+optee-utee = { path = "../../../optee-utee" }
diff --git a/examples/tls_client-rs/ta/Makefile b/examples/tls_client-rs/ta/Makefile
index 7e826ed..42d9236 100644
--- a/examples/tls_client-rs/ta/Makefile
+++ b/examples/tls_client-rs/ta/Makefile
@@ -22,7 +22,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/tls_client-rs/ta/build.rs b/examples/tls_client-rs/ta/build.rs
index fa0d195..781fe90 100644
--- a/examples/tls_client-rs/ta/build.rs
+++ b/examples/tls_client-rs/ta/build.rs
@@ -16,88 +16,11 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?
+        .ta_data_size(18 * 1024 * 1024)
+        .ta_stack_size(2 * 1024 * 1024);
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/tls_client-rs/ta/src/main.rs b/examples/tls_client-rs/ta/src/main.rs
index fb64c4b..3065e11 100644
--- a/examples/tls_client-rs/ta/src/main.rs
+++ b/examples/tls_client-rs/ta/src/main.rs
@@ -103,16 +103,4 @@ fn tls_client() {
     trace_println!("{}", String::from_utf8_lossy(&plaintext));
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 18 * 1024 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
-const TA_VERSION: &[u8] = b"0.3\0";
-const TA_DESCRIPTION: &[u8] = b"This is a tls client example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"TLS Client TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/tls_client-rs/ta/ta_static.rs b/examples/tls_client-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/tls_client-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/tls_server-rs/ta/Cargo.toml b/examples/tls_server-rs/ta/Cargo.toml
index b1ccecf..5c5f13e 100644
--- a/examples/tls_server-rs/ta/Cargo.toml
+++ b/examples/tls_server-rs/ta/Cargo.toml
@@ -40,8 +40,8 @@ sct = "=0.7.0"
 lazy_static = { version = "1.4.0", features=["spin_no_std"] }
 
 [build-dependencies]
-uuid = { version = "1.8", default-features = false }
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/tls_server-rs/ta/Makefile b/examples/tls_server-rs/ta/Makefile
index 7e826ed..42d9236 100644
--- a/examples/tls_server-rs/ta/Makefile
+++ b/examples/tls_server-rs/ta/Makefile
@@ -22,7 +22,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/tls_server-rs/ta/build.rs b/examples/tls_server-rs/ta/build.rs
index fa0d195..781fe90 100644
--- a/examples/tls_server-rs/ta/build.rs
+++ b/examples/tls_server-rs/ta/build.rs
@@ -16,88 +16,11 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?
+        .ta_data_size(18 * 1024 * 1024)
+        .ta_stack_size(2 * 1024 * 1024);
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/tls_server-rs/ta/src/main.rs b/examples/tls_server-rs/ta/src/main.rs
index 2b4ebb7..8363437 100644
--- a/examples/tls_server-rs/ta/src/main.rs
+++ b/examples/tls_server-rs/ta/src/main.rs
@@ -163,16 +163,4 @@ fn load_private_key() -> rustls::PrivateKey {
     rustls::PrivateKey(keys[0].clone())
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 18 * 1024 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
-const TA_VERSION: &[u8] = b"0.3\0";
-const TA_DESCRIPTION: &[u8] = b"This is a tls server example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"TLS Server TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/tls_server-rs/ta/ta_static.rs b/examples/tls_server-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/tls_server-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}
diff --git a/examples/udp_socket-rs/ta/Cargo.toml b/examples/udp_socket-rs/ta/Cargo.toml
index 6f83a03..ba7d6d4 100644
--- a/examples/udp_socket-rs/ta/Cargo.toml
+++ b/examples/udp_socket-rs/ta/Cargo.toml
@@ -31,8 +31,8 @@ optee-utee-sys = { path = "../../../optee-utee/optee-utee-sys" }
 optee-utee = { path = "../../../optee-utee" }
 
 [build-dependencies]
-uuid = { version = "1.8", default-features = false }
 proto = { path = "../proto" }
+optee-utee-build = { path = "../../../optee-utee-build" }
 
 [profile.release]
 panic = "abort"
diff --git a/examples/udp_socket-rs/ta/Makefile b/examples/udp_socket-rs/ta/Makefile
index 7e826ed..42d9236 100644
--- a/examples/udp_socket-rs/ta/Makefile
+++ b/examples/udp_socket-rs/ta/Makefile
@@ -22,7 +22,8 @@ UUID ?= $(shell cat "../uuid.txt")
 TARGET ?= aarch64-unknown-linux-gnu
 CROSS_COMPILE ?= aarch64-linux-gnu-
 OBJCOPY := $(CROSS_COMPILE)objcopy
-LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)ld.bfd\"
+# Configure the linker to use GCC, which works on both cross-compilation and ARM machines
+LINKER_CFG := target.$(TARGET).linker=\"$(CROSS_COMPILE)gcc\"
 
 TA_SIGN_KEY ?= $(TA_DEV_KIT_DIR)/keys/default_ta.pem
 SIGN := $(TA_DEV_KIT_DIR)/scripts/sign_encrypt.py
diff --git a/examples/udp_socket-rs/ta/build.rs b/examples/udp_socket-rs/ta/build.rs
index fa0d195..3f1e2a7 100644
--- a/examples/udp_socket-rs/ta/build.rs
+++ b/examples/udp_socket-rs/ta/build.rs
@@ -16,88 +16,11 @@
 // under the License.
 
 use proto;
-use std::env;
-use std::fs::File;
-use std::io::{BufRead, BufReader, Write};
-use std::path::{Path, PathBuf};
-use uuid::Uuid;
+use optee_utee_build::{TaConfig, RustEdition, Error};
 
-fn main() -> std::io::Result<()> {
-    let out = &PathBuf::from(env::var_os("OUT_DIR").unwrap());
-
-    let mut buffer = File::create(out.join("user_ta_header.rs"))?;
-    buffer.write_all(include_bytes!("ta_static.rs"))?;
-
-    let tee_uuid = Uuid::parse_str(proto::UUID).unwrap();
-    let (time_low, time_mid, time_hi_and_version, clock_seq_and_node) = tee_uuid.as_fields();
-
-    write!(buffer, "\n")?;
-    write!(
-        buffer,
-        "const TA_UUID: optee_utee_sys::TEE_UUID = optee_utee_sys::TEE_UUID {{
-    timeLow: {:#x},
-    timeMid: {:#x},
-    timeHiAndVersion: {:#x},
-    clockSeqAndNode: {:#x?},
-}};",
-        time_low, time_mid, time_hi_and_version, clock_seq_and_node
-    )?;
-
-    let mut aarch64_flag = true;
-    match env::var("TARGET_TA") {
-        Ok(ref v) if v == "arm-unknown-linux-gnueabihf" || v == "arm-unknown-optee" => {
-            println!("cargo:rustc-link-arg=--no-warn-mismatch");
-            aarch64_flag = false;
-        },
-        _ => {}
-    };
-
-    let optee_os_dir = env::var("TA_DEV_KIT_DIR").unwrap();
-    let search_path = Path::new(&optee_os_dir).join("lib");
-
-    let optee_os_path = &PathBuf::from(optee_os_dir.clone());
-    let mut ta_lds = File::create(out.join("ta.lds"))?;
-    let f = File::open(optee_os_path.join("src/ta.ld.S"))?;
-    let f = BufReader::new(f);
-
-    for line in f.lines() {
-        let l = line?;
-
-        if aarch64_flag {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf32-littlearm\")" ||
-                l == "OUTPUT_ARCH(arm)" {
-                continue;
-            }
-        } else {
-            if l.starts_with('#') ||
-                l == "OUTPUT_FORMAT(\"elf64-littleaarch64\")" ||
-                l == "OUTPUT_ARCH(aarch64)" {
-                continue;
-            }
-        }
-
-        if l == "\t. = ALIGN(4096);" {
-            write!(ta_lds, "\t. = ALIGN(65536);\n")?;
-        } else {
-            write!(ta_lds, "{}\n", l)?;
-        }
-    }
-
-    println!("cargo:rustc-link-search={}", out.display());
-    println!("cargo:rerun-if-changed=ta.lds");
-
-    println!("cargo:rustc-link-search={}", search_path.display());
-    println!("cargo:rustc-link-lib=static=utee");
-    println!("cargo:rustc-link-lib=static=utils");
-    println!("cargo:rustc-link-arg=-Tta.lds");
-    println!("cargo:rustc-link-arg=-e__ta_entry");
-    println!("cargo:rustc-link-arg=-pie");
-    println!("cargo:rustc-link-arg=-Os");
-    println!("cargo:rustc-link-arg=--sort-section=alignment");
-
-    let mut dyn_list = File::create(out.join("dyn_list"))?;
-    write!(dyn_list, "{{ __elf_phdr_info; trace_ext_prefix; trace_level; ta_head; }};\n")?;
-    println!("cargo:rustc-link-arg=--dynamic-list=dyn_list");
-    Ok(())
+fn main() -> Result<(), Error> {
+    let ta_config = TaConfig::new_default_with_cargo_env(proto::UUID)?
+        .ta_data_size(1 * 1024 * 1024)
+        .ta_stack_size(2 * 1024 * 1024);
+    optee_utee_build::build(RustEdition::Before2024, ta_config)
 }
diff --git a/examples/udp_socket-rs/ta/src/main.rs b/examples/udp_socket-rs/ta/src/main.rs
index 812f418..867c9d8 100644
--- a/examples/udp_socket-rs/ta/src/main.rs
+++ b/examples/udp_socket-rs/ta/src/main.rs
@@ -83,16 +83,4 @@ fn udp_socket() {
     trace_println!("{}", String::from_utf8_lossy(&response));
 }
 
-// TA configurations
-const TA_FLAGS: u32 = 0;
-const TA_DATA_SIZE: u32 = 1 * 1024 * 1024;
-const TA_STACK_SIZE: u32 = 2 * 1024 * 1024;
-const TA_VERSION: &[u8] = b"0.3\0";
-const TA_DESCRIPTION: &[u8] = b"This is a udp socket example.\0";
-const EXT_PROP_VALUE_1: &[u8] = b"Hello World TA\0";
-const EXT_PROP_VALUE_2: u32 = 0x0010;
-const TRACE_LEVEL: i32 = 4;
-const TRACE_EXT_PREFIX: &[u8] = b"TA\0";
-const TA_FRAMEWORK_STACK_SIZE: u32 = 2048;
-
 include!(concat!(env!("OUT_DIR"), "/user_ta_header.rs"));
diff --git a/examples/udp_socket-rs/ta/ta_static.rs b/examples/udp_socket-rs/ta/ta_static.rs
deleted file mode 100644
index 20e1d97..0000000
--- a/examples/udp_socket-rs/ta/ta_static.rs
+++ /dev/null
@@ -1,102 +0,0 @@
-// Licensed to the Apache Software Foundation (ASF) under one
-// or more contributor license agreements.  See the NOTICE file
-// distributed with this work for additional information
-// regarding copyright ownership.  The ASF licenses this file
-// to you under the Apache License, Version 2.0 (the
-// "License"); you may not use this file except in compliance
-// with the License.  You may obtain a copy of the License at
-//
-//   http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing,
-// software distributed under the License is distributed on an
-// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
-// KIND, either express or implied.  See the License for the
-// specific language governing permissions and limitations
-// under the License.
-
-use core::ffi::{c_int, c_void};
-use core::mem;
-use core::primitive::u64;
-
-#[no_mangle]
-pub static mut trace_level: c_int = TRACE_LEVEL;
-
-#[no_mangle]
-pub static trace_ext_prefix: &[u8] = TRACE_EXT_PREFIX;
-
-#[no_mangle]
-#[link_section = ".ta_head"]
-pub static ta_head: optee_utee_sys::ta_head = optee_utee_sys::ta_head {
-    uuid: TA_UUID,
-    stack_size: TA_STACK_SIZE + TA_FRAMEWORK_STACK_SIZE,
-    flags: TA_FLAGS,
-    depr_entry: u64::MAX,
-};
-
-#[no_mangle]
-#[link_section = ".bss"]
-pub static ta_heap: [u8; TA_DATA_SIZE as usize] = [0; TA_DATA_SIZE as usize];
-
-#[no_mangle]
-pub static ta_heap_size: usize = mem::size_of::<u8>() * TA_DATA_SIZE as usize;
-static FLAG_BOOL: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_SINGLE_INSTANCE) != 0;
-static FLAG_MULTI: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_MULTI_SESSION) != 0;
-static FLAG_INSTANCE: bool = (TA_FLAGS & optee_utee_sys::TA_FLAG_INSTANCE_KEEP_ALIVE) != 0;
-
-#[no_mangle]
-pub static ta_num_props: usize = 9;
-
-#[no_mangle]
-pub static ta_props: [optee_utee_sys::user_ta_property; 9] = [
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_SINGLE_INSTANCE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_BOOL as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_MULTI_SESSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_MULTI as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_KEEP_ALIVE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_BOOL,
-        value: &FLAG_INSTANCE as *const bool as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DATA_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_DATA_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_STACK_SIZE,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &TA_STACK_SIZE as *const u32 as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_VERSION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_VERSION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: optee_utee_sys::TA_PROP_STR_DESCRIPTION,
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: TA_DESCRIPTION as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.description\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_STRING,
-        value: EXT_PROP_VALUE_1 as *const [u8] as *mut _,
-    },
-    optee_utee_sys::user_ta_property {
-        name: "gp.ta.version\0".as_ptr(),
-        prop_type: optee_utee_sys::user_ta_prop_type::USER_TA_PROP_TYPE_U32,
-        value: &EXT_PROP_VALUE_2 as *const u32 as *mut _,
-    },
-];
-
-#[no_mangle]
-pub unsafe extern "C" fn tahead_get_trace_level() -> c_int {
-    return trace_level;
-}


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@teaclave.apache.org
For additional commands, e-mail: commits-help@teaclave.apache.org