rust 交叉编译,吐血整理

这两天一直在搞rust的交叉编译,大概花了1天半时间才搞明白。官方的文档说的很简单,始终不起作用,直到看了下面的文章才醍醐灌顶。从原理到详细步骤都有了。

原文链接

RISC-V Bytes: Rust Cross-Compilation · Daniel Mangum

感谢Daniel

我自己也总结了一下,如果有朋友需要的话可以参考

简洁版

在工程目录下建立文件夹和配置文件

mkdir .cargo && cd .cargo && touch config.toml

然后运行即可

cargo build

详解版

原理

以前用过C语言的交叉编译,需要注意的是两个,一个是编译链工具,另一个是sysroot。

主要步骤有两个

  1. 利用编译链工具中的编译器编译c文件,这一步一般没有问题
  2. 利用编译链工具中的链接器将.o文件和从其他系统中拷贝过来的sysroot中的库文件链接到一起

rust的交叉编译似乎更简单一点。

首先rust的编译链工具是跨平台的,不需要重新下载。比如你已经有一个编译链工具,使用如下命令显示

rustup show

在我的电脑上得到

Default host: x86_64-unknown-linux-gnu
rustup home: /home/ubuntu/.rustup

installed toolchains

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

active toolchain

stable-aarch64-unknown-linux-gnu (default)
(error reading rustc version)

说明我拥有两个工具链。但是上述的配置是错误的,应该使用的工具链为stable-x86_64-unknown-linux-gnu(我使用的是ubuntu22, 虚拟机,x86)。

stable-x86_64-unknown-linux-gnu 这个工具链(toolchain)可以再我这个主机(host)上编任何目标(target)平台的程序,而不用像c语言一样,切换一个平台就需要重新下载一次新的toolchain。

其次虽然工具链是单一的,但是target库跟c语言一样,需要链接,所以每一个target都需要下载自己的库文件。比较好的地方是c语言的库文件和头文件需要自己手动从其他系统拷贝过来,但是rust的库文件只需要命令行下载即可!非常方便。

记住这两点,工具链和库,那么交叉编译就基本没问题了。

步骤

说一下环境,vmware下跑的ubuntu22虚拟机,输入

uname -a

Linux ubuntu-virtual-machine 5.15.0-27-generic #28-Ubuntu SMP Thu Apr 14 04:55:28 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

初始状态下已经安装rustup,如果没有的话,可以访问网站

https://www.rust-lang.org/tools/install

或者输入命令(linux系统有效)安装一下即可

curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
  1. 确认目标机器。我需要在x86下编译,然后在arm64上跑程序。所以使用的是 aarch64-unknown-linux-gnu 。输入命令即可查看

    rustup target list
    

    此时确认一下自己的工具链

    rustup show
    

    Default host: x86_64-unknown-linux-gnu
    rustup home: /home/ubuntu/.rustup

    stable-x86_64-unknown-linux-gnu (default)
    rustc 1.60.0 (7737e0b5c 2022-04-04)

    可以看到目前只有一个工具链,没有target(其实有target,但是target是本机,所以不显示)。所以此时编译出来的程序可以在本地跑起来

    cargo new hello
    cd hello
    cargo run
    

    Compiling hello v0.1.0 (/home/ubuntu/test/hello)
    Finished dev [unoptimized + debuginfo] target(s) in 4.94s
    Running target/debug/hello
    Hello, world!

  2. 下载arm库

    rustup target add aarch64-unknown-linux-gnu
    

    运行命令确认

    rustup show
    

    Default host: x86_64-unknown-linux-gnu
    rustup home: /home/ubuntu/.rustup

    installed targets for active toolchain

    aarch64-unknown-linux-gnu
    x86_64-unknown-linux-gnu

    active toolchain

    stable-x86_64-unknown-linux-gnu (default)
    rustc 1.60.0 (7737e0b5c 2022-04-04)

    此时有一个toolchain,两个target;其中aarch64-unknown-linux-gnu就是我需要的

  3. 下载目标平台gcc,配置target和链接器
    这一步非常关键,而且让人迷惑。rust编译程序的过程需要用到自己的工具链,同时还需要用到gcc的链接工具!但是他们的名字非常接近但是又不完全一样。
    还有一个我之前屡次失败的原因是:rust安装方式有问题!!!!!!!!!!我之前用的是

    sudo apt install cargo
    

    这样会导致rustup的路径出现问题,千万要注意如果想正确编译的话必须用官网推荐的安装方法,也就是

    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    

    首先安装gcc

    sudo apt-get install -qq gcc-aarch64-linux-gnu
    

    安装完成后如果输入以下命令有结果的话说明安装成功

    aarch64-linux-gnu-gcc -v
    

    然后添加配置文件。在刚才建立的工程目录 hello 下

    mkdir .cargo && cd .cargo && touch config.toml
    

    将以下内容复制入config.toml内即可

    [build]
    target = “aarch64-unknown-linux-gnu”

    [target.aarch64-unknown-linux-gnu]
    linker = “aarch64-linux-gnu-gcc”

  4. 编译并运行

    cargo clean
    cargo build
    cargo run
    

    如果输出以下信息,表示编译成功

    Finished dev [unoptimized + debuginfo] target(s) in 0.00s
     Running `target/aarch64-unknown-linux-gnu/debug/hello`
    

    target/aarch64-unknown-linux-gnu/debug/hello: 1: cannot open @8: No such file
    target/aarch64-unknown-linux-gnu/debug/hello: 1: ELF��g@�:: not found
    target/aarch64-unknown-linux-gnu/debug/hello: 2: @+*@@@0ppp
    �D��������+�-�: not found
    target/aarch64-unknown-linux-gnu/debug/hello: 3: �: not found
    target/aarch64-unknown-linux-gnu/debug/hello: 4: �: not found
    target/aarch64-unknown-linux-gnu/debug/hello: 5: Syntax error: “(” unexpected

    注意将hello程序拷贝出来后放入目标系统

    chmod +x hello 
    ./hello
    

    会产生如下信息

    ./hello: /lib/aarch64-linux-gnu/libc.so.6: version `GLIBC_2.28’ not found (required by ./hello)

    说明目标系统的ubuntu版本过低。。。。

    两种选择,目标系统升级系统到ubuntu22,或者host系统降级到ubuntu18即可。

你可能感兴趣的:(rust,开发语言,后端)