总流程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
def 移植(self):
if self支持 no_std then
不用修改,直接在依赖处配置好 no_std 的 features
return
# 移植依赖项 (忽略dev-dependencies)
for each dep of self.dependencies
移植 dep
# 移植自身
(1) wget 库代码 && tar xzf
(2) 编辑 Cargo.toml 修改每个依赖项为移植后的依赖项
(3) 编辑 src/lib.rs 添加特定header(见后文)
(4) 编辑每个源文件 添加 use std::prelude::v1::*;
(5) 仔细review每个使用 fs/path/net/time/env 等不可信输入的地方,修正那里的逻辑
(6) 检查每个 platform dependent 的 feature,将其固定为只适用于 linux-x86_64 的逻辑(因为 linux-SGX 就只有这个环境)
(7) 测试 `cargo build` 是否通过
return

下载crate

1
2
3
4
5
6
https://crates.io/api/v1/crates/<库名>/<版本号>/download

https://crates.io/api/v1/crates/iter-enum/1.0.1/download
https://crates.io/api/v1/crates/pin-project/1.0.8/download
https://crates.io/api/v1/crates/strum_macros/0.21.1/download
https://crates.io/api/v1/crates/thiserror/1.0.30/download

查看依赖

1
cargo tree

检查依赖关系

1
grep -R <lib>

cargo.toml

1
2
3
4
5
[target.'cfg(not(target_env = "sgx"))'.dependencies]
sgx_tstd = { rev = "v1.1.3", git = "https://github.com/apache/teaclave-sgx-sdk.git" }

# 引用已移植的crate
byteorder = { git = "https://github.com/mesalock-linux/byteorder-sgx" }

lib.rs

1
2
3
4
5
6
#![cfg_attr(all(feature = "mesalock_sgx", not(target_env = "sgx")), no_std)]
#![cfg_attr(all(target_env = "sgx", target_vendor = "mesalock"), feature(rustc_private))]

#[cfg(all(feature = "mesalock_sgx", not(target_env = "sgx")))]
#[macro_use]
extern crate sgx_tstd as std;

每一个.rs文件添加 (包括lib.rs),若编译时报Warning再对照着删除

1
use std::prelude::v1::*;

常见错误

  • 编译时出现:

    1
    2
    3
    4
    5
    6
    7
    error[E0432]: unresolved import `core::alloc::AllocRef`
    --> /home/schenk/.cargo/git/checkouts/teaclave-sgx-sdk-be25c2ad2f03718d/a6a172e/sgx_alloc/src/system.rs:26:17
    |
    26 | AllocError, AllocRef, GlobalAlloc, Layout,
    | ^^^^^^^^ no `AllocRef` in `alloc`

    error: aborting due to previous error

    说明rustup toolchain选择有问题,使用命令修改toolchain能通过编译:

    1
    rustup override set nightly-2020-10-25-x86_64-unknown-linux-gnu
  • 编译时出现:

    1
    2
    3
    4
    5
    error: duplicate lang item in crate `std`: `f32_runtime`.
    |
    = note: the lang item is first defined in crate `sgx_tstd` (which `helloworldsampleenclave` depends on)
    = note: first definition in `sgx_tstd` loaded from /home/schenk/sgx/workspace/sgx-test/enclave/target/release/deps/libsgx_tstd-c10171ffd7c558b5.rlib
    = note: second definition in `std` loaded from /home/schenk/.rustup/toolchains/nightly-2020-10-25-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-3010daceac92f8fa.so, /home/schenk/.rustup/toolchains/nightly-2020-10-25-x86_64-unknown-linux-gnu/lib/rustlib/x86_64-unknown-linux-gnu/lib/libstd-3010daceac92f8fa.rlib

    很有可能是因为在这个错误之前出现了其他错误,例如变量未定义等:

    1
    2
    3
    4
    5
    6
    error[E0425]: cannot find value `sealed_log` in this scope
    --> src/lib.rs:143:14
    |
    143 | &sealed_log,
    | ^^^^^^^^^^ not found in this scope

    应当先修复其他的错误

notes

  • cfg

    1
    2
    // 条件编译,如果同时满足feature是"mesalock_sgx" 和 target_env不是"sgx",则编译
    #[cfg(all(feature = "mesalock_sgx", not(target_env = "sgx")))]
  • cfg_attr

    1
    2
    // 如果满足all(feature = "mesalock_sgx", not(target_env = "sgx")),则相当于 ![cfg(no_std)]
    #![cfg_attr(all(feature = "mesalock_sgx", not(target_env = "sgx")), no_std)]
  • .toml

    • features

      1
      2
      3
      4
      5
      6
      # crate本来就没有features的话不用改
      # 否则在default中加入"mesalock_sgx",并添加feature mesalock_sgx,在其中加入在crate中引入的"sgx_*"
      [features]
      default = ["linkage", "mesalock_sgx"]
      linkage = ["sqlite3-src"]
      mesalock_sgx = ["sgx_tstd", "sgx_libc"]
    • target.xxx.dependencies:满足xxx条件时的依赖