Rust 交叉编译与条件编译总结

本文详细介绍了如何使用Rust进行交叉编译和条件编译,包括利用build.rs进行预编译操作,如拉取git submodule、调用clang和ndk-build,以及针对iOS/Android/macOS/Windows的跨平台编译示例。同时,文章还探讨了条件编译的使用,如mod级别的条件编译和特定CPU架构的编译,并提供了检查库导出符号的方法,确保C接口的正确导出。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

2019.2.2 改标题

文档列表见:Rust 移动端跨平台复杂图形渲染项目开发系列总结(目录)

主体项目编译前的操作(build.rs)

build.rs可实现本项目编译前的额外操作,比如代码生成、调用cmake/clang/gcc/ndk-build等编译所依赖的C/C++库、读取C/C++头文件生成FFI文件给Rust项目使用等等,相当于Rust写的shell脚本。 为了让编译过程更可控,通常输出日志表示通过了某一阶段,或遇到什么错误,Cargo支持build.rs编译时输出不同类型的语句,比如warning、error等,比如:

println!("cargo:warning=Error failed with {:?}.", some_reason);
复制代码

目前没找到输出info级别日志的办法,经实践println!("cargo:info={:?}, some_status);无法在控制台输出信息。

build.rs拉取git submodule

以下代码摘自glsl-to-spirv

use std::process::Command;

// Try to initialize submodules. Don't care if it fails, since this code also runs for
// the crates.io package.
let _ = Command::new("git")
    .arg("submodule")
    .arg("update")
    .arg("--init")
    .status();
复制代码

Cargo调用clang编译所依赖的第三方C/C++库

目前我看到比较完整的参考是官方的libstd/build.rs,编译我们业务所需的第三方库的命令几乎都可以从那找到“灵感”,下面贴出核心代码段镇宅,关键操作是build_libbacktrace(),通过cc::Build实例把需要编译的C/C++代码声明起来,理论上支持正则匹配文件名与路径

#![deny(warnings)]

extern crate build_helper;
extern crate cc;

use build_helper::native_lib_boilerplate;
use std::env;
use std::fs::File;

fn main() {
    let target = env::var("TARGET").expect("TARGET was not set");
    if cfg!(feature = "backtrace") &&
        !target.contains("cloudabi") 
        // ... 更多条件
    {
        let _ = build_libbacktrace(&target);
    }

    if target.contains("linux") {
        // ... 一系列操作系统判断及println!   
    }
}

fn build_libbacktrace(target: &str) -> Result<(), ()> {
    let native = native_lib_boilerplate("libbacktrace", "libbacktrace", "backtrace", "")?;

    let mut build = cc::Build::new();
    build
        .flag("-fvisibility=hidden")
        .include("../libbacktrace")
        .include(&native.out_dir)
        .out_dir(&native.out_dir)
        .warnings(false)
        .file("../libbacktrace/alloc.c")
        .file("../libbacktrace/backtrace.c")
        // ...一堆.c文件

    let any_debug = env::var("RUSTC_DEBUGINFO").unwrap_or_default() == "true" ||
        env::var("RUSTC_DEBUGINFO_LINES").unwrap_or_default() == "true";
    build.debug(any_debug);

    if target.contains("darwin") {
        build.file("../libbacktrace/macho.c");
    } else if target.contains("windows") {
        build.file("../libbacktrace/pecoff.c");
    } else {
        build.file("../libbacktrace/elf.c");

        let pointer_width = env::var("CARGO_CFG_TARGET_POINTER_WIDTH").unwrap();
        if pointer_width == "64" {
            build.define("BACKTRACE_ELF_SIZE", "64");
        } else {
            build.define("BACKTRACE_ELF_SIZE", "32");
        }
    }

    File::create(native.out_dir.join("backtrace-supported.h")).unwrap();
    build.define("BACKTRACE_SUPPORTED", "1");
    build.define("BACKTRACE_USES_MALLOC", "1");
    build.define("BACKTRACE_SUPPORTS_THREADS", "0");
    build.define("BACKTRACE_SUPPORTS_DATA", "0");

    File::create(native.out_dir.join("config.h")).unwrap();
    if !target.contains("apple-ios") &&
       !target.contains("solaris") &&
       !target.contains("redox") &&
       !target.contains("android") &&
       !target.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值