rust windows 交叉编译_交叉编译和静态链接 RUST 库

本文介绍了如何在 Rust 中创建库,并从 C/C++ 应用程序进行调用,重点讨论了在 Windows 和 Linux 平台上进行交叉编译和静态链接的步骤,包括设置目标、修改 Cargo 配置以及编译链接过程。
摘要由CSDN通过智能技术生成

在 CSIS 中,我们过去使用 Python 编写后端,同时为 Incident Response Toolkit 编写一些 C/C++ 代码。

几年前,主要是由于性能原因,我们开始用 Rust 替换 Python 重写了一些特定的后端服务,并取得了巨大的成功。现在,为了便于开发和测试,我们正在探索将 C/C++ 代码库的某些部分也迁移到 Rust 的方法。

为了做到这一点,我们决定尝试将Rust集成到现有的代码库中,而不是一次重写所有内容。

下面是我们实验的摘要,以及编写一个Rust库并从 C/C++ 应用程序调用它的框架。

TARGETS

为了能够交叉编译代码,我们需要确保安装了相应的 target。可用的targets可以用过 rustc --print target-list 或 rustup target list 查看,可以通过 rustup target add 安装新的 target。

查看已经安装的 targets 可以用 rustup show:

$ rustup show

Default host: x86_64-unknown-linux-gnu

installed toolchains

--------------------

stable-x86_64-unknown-linux-gnu (default)

nightly-x86_64-unknown-linux-gnu

installed targets for active toolchain

--------------------------------------

i686-pc-windows-gnu

i686-pc-windows-msvc

i686-unknown-linux-gnu

i686-unknown-linux-musl

x86_64-pc-windows-gnu

x86_64-pc-windows-msvc

x86_64-unknown-linux-gnu

x86_64-unknown-linux-musl

active toolchain

----------------

stable-x86_64-unknown-linux-gnu (default)

rustc 1.31.0 (abe02cefd 2018-12-04)

项目设置

target 正确设置好后,我们需要设置项目,从 Cargo.toml 开始 :

[package]

name = "mylib"

version = "0.1.0"

authors = ["john doe"]

[dependencies]

libc = "*"

[lib]

crate-type = ["staticlib"]

现在我们的库的源代码src/lib.rs :

extern crate libc;

use libc::uint32_t;

#[no_mangle]

pub extern "C" fn addition(a: uint32_t, b: uint32_t) -> uint32_t {

a + b

}

以及应用程序调用者的源代码 caller.cpp:

#include

#include

extern "C" {

uint32_t

addition(uint32_t, uint32_t);

}

int main(void) {

uint32_t sum = addition(1, 2);

printf("%u\n", sum);

}

如果这是个 C 应用,只需要删除extern "C" 。

接下来,我们需要指定我们想要的 target, 这是在.cargo/config 中完成的, 比如:

[build]

target="i686-pc-windows-gnu"

LINUX 二进制文件

为了静态链接 Linux 二进制文件,我们需要将 target 设置为 -linux-musl。.cargo/config

或者,对于 64 位 二进制文件,我们可以选择 x86_64-unknown-linux-musl。

[build]

target="i686-unknown-linux-musl"build

$ g++ -m32 -c -o linux_cpp_caller.o caller.cpp

$ g++ -static -m32 linux_cpp_caller.o -o linux_cpp_caller \

-L./target/i686-unknown-linux-musl/debug/ -lmylib

如果我们的目标是 64 位,我们需要删除 -m32选项,并相应的调整 -L 标志。

WINDOWS 二进制文件

为了静态链接 Windows 二进制文件,我们需要将 target 设置为 -pc-windows-gnu。对于 32 位二进制文件,需要特别注明异常处理模型。可以在 “rust-lang” Github repository 和 stack overflow 找到一个很好的摘要。.cargo/config

[build]

target="i686-pc-windows-gnu"

rustflags = "-C panic=abort"

或者,对于 64 位二进制文件,我们可以选择 x86_64-pc-windows-gnu。如果是这种情况,可以删除 rustflags 选项。build

$ i686-w64-mingw32-g++ -c -o win_cpp_caller.o caller.cpp

$ i686-w64-mingw32-g++ -static win_cpp_caller.o -o win_cpp_caller \

-L./target/i686-pc-windows-gnu/debug/ \

-lmylib \

-ladvapi32 \

-lws2_32 \

-luserenv

如果是 64 位环境,用该使用 x86_64-w64-mingw32-g++,并相应调整 -L 标志。

结论

通过这篇文章,我们希望提供一个简单的工作示例,说明 Rust 和 C / C++ 如何相互操作,这可以作为一个起点。

我们要感谢以下链接资源的贡献者。

资源

这篇文章总结了以下链接中的信息:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值