Windows 10 配置Rust交叉编译Linux应用程序-gnu

在Windows环境下交叉编译Linux程序使用musl与gnu 两种target方式的区别在Windows 10 配置Rust交叉编译Linux应用程序-musl这篇配置target=x86_64-unknown-linux-musl时已经解释了,gnu使用动态链接,目标服务器(部署或者执行目标代码的服务)需要包含依赖的相关用户共享库。

1. 添加需要的target

添加target x86_64-unknown-linux-musl

rustup target add  x86_64-unknown-linux-gnu

rustup target list
...                                   # 省略其他为安装target显示
x86_64-pc-windows-msvc (installed)    # 这个是windows环境下配置rust默认安装的
x86_64-unknown-linux-musl (installed) # 这个是之前记录文档里安装的 https://blog.csdn.net/oyym_mv/article/details/113843870
x86_64-unknown-linux-gnu (installed)  # 这个是本次文档安装的。

2. 安装cygwin

在之后配置编译链接程序时需要解压等工具,验证用windows下直接安装的解压工具操作会出问题(EOF format error)。

从cygwin.com下载cygwin安装工具setup-x86_64.exe,然后安装cygwin并选择一些需要的工具包进行安装,例如包括 tar, wget, binutils, unzip等等,可以直接通过setup-x86_64.exe进行图形化安装,也可以直接命令行安装

如下命令行安装的工具包是从参考文档(用来编译生成我们需要的交叉编译相关库)里面直接贴出来的,我们实际上使用参考文档里老外编译好的文件,所以不需要这么多工具包安装的。

setup-x86_64.exe -a x86_64 -d -q -P "tar,wget,unzip,gcc-core,gcc-g++,binutils,make,cmake,automake,autoconf,git,patch,flex,bison,gperf,help2man,libtool,gettext,libgmp10,libgmp-devel,libmpfr6,libmpfr-devel,libmpc3,libmpc-devel,libncurses-devel,libintl-devel"

备注

  1. 初次安装如果相关工具包没有选择安装全也没有关系,需要的时候可以再次运行setup-x86_64.exe进行补充安装
  2. 我这边选择的cygwin安装目录为:
    Windows 10 配置Rust交叉编译Linux应用程序-gnu_第1张图片
  3. 配置cygwin bin目录环境变量
    我的电脑,属性,高级系统设置,环境变量,系统变量,Path 增加一段新的配置:
    C:\Tools\cygwin64\bin
    

3. 配置交叉编译工具链

我们不自己编译生成交叉编译使用的工具库(编译很慢也很容易出问题要解决),我们这里使用别人已经编译好的工具库,如果你想自己编译可以参考这篇文档Building a linux cross-compile toolchain under Cygwin64 on Windows。我们选择的版本x86_64-unknown-linux-gnu-9.2.0.tar.gz

# step 1, 下载x86_64-unknown-linux-gnu-9.2.0.tar.gz
wget https://developer.moe/images/download/gcc/x86_64-unknown-linux-gnu-9.2.0.tar.gz

# step 2, 将x86_64-unknown-linux-gnu-9.2.0.tar.gz拷贝到C:\Tools\cygwin64\home\${自己windows用户名文件夹}\work目录,如果相关子目录没有需要自己创建。
cp x86_64-unknown-linux-gnu-9.2.0.tar.gz C:\Tools\cygwin64\home\oyym\work

# step 3, 在cygwin终端cd到C:\Tools\cygwin64\home\oyym\work目录,使用tar zxvf解压
$ pwd
/home/oyym
$ cd work
$ tar zxvf x86_64-unknown-linux-gnu-9.2.0.tar.gz
# 解压后的完整路径:C:\Tools\cygwin64\home\oyym\work\x86_64-unknown-linux-gnu

# step 4, 配置环境变量
我的电脑,属性,高级系统设置,环境变量,系统变量,Path 增加一段新的配置:
C:\Tools\cygwin64\home\oyym\work\x86_64-unknown-linux-gnu\bin

# step 5, 验证
x86_64-unknown-linux-gnu-gcc -v
... # 省略一堆输出
gcc version 9.2.0 (crosstool-NG UNKNOWN)

Windows 10 配置Rust交叉编译Linux应用程序-gnu_第2张图片

4. 配置cargo交叉编译target使用的链接程序

windows 10 通过rustup安装的rust环境,cargo家目录为 C:\Users\{具体的用户}\.cargo, 在该目录下编辑配置文件config [或者config.toml] ,没有就创建一个

# C:\Users\oyym\.cargo\config     其中oyym是我的用户名,每个用户都不同的

[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"

[target.x86_64-unknown-linux-gnu]
linker = "x86_64-unknown-linux-gnu-gcc"

提示:上述是全局配置,也可以在具体的项目跟目录创建 .cargo/config 文件进行针对具体项目的配置

5. 交叉编译hello项目,并在远程Linux服务器进行验证

5.1 创建,并交叉编译项目

# step 1, 创建项目,并交叉编译生成目标应用程序
cargo new hello
cd hello
cargo build --release --target=x86_64-unknown-linux-gnu

# step 2,将目标应用程序传输到目标服务器
cd target\x86_64-unknown-linux-gnu\release
scp hello [email protected]:/tmp/

5.2 因为缺少依赖共享库,运行程序失败

# step 1,在目标服务器运行目标应用程序
ssh [email protected]
cd /tmp
chmod +x hello

# step 2, 查看动态链接库依赖
ldd hello
./hello: /lib64/libc.so.6: version 'GLIBC_2.18' not found (required by ./hello)
        linux-vdso.so.1 =>  (0x00007fff8a793000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f5578def000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f5578bd3000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f55789cf000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f5578602000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f5579005000)

# step 3, 执行程序,缺少依赖(依赖版本不一致),运作该程序失败
./hello
./hello: /lib64/libc.so.6: version `GLIBC_2.18' not found (required by ./hello)  # 这个是输出结果


# step 4, 查看当前系统glibc版本
rpm -aq |grep glibc
glibc-devel-2.17-260.el7_6.4.x86_64
glibc-common-2.17-260.el7_6.4.x86_64
glibc-2.17-260.el7_6.4.i686
glibc-2.17-260.el7_6.4.x86_64
glibc-headers-2.17-260.el7_6.4.x86_64

可以看到hello需要依赖glibc 2.18 但是我的系统目前没有,所以运行失败,需要升级下glibc到2.18

升级glibc可以参考文档这里 或者 这里

5.3 升级glibc之后执行程序成功

# step 1, 查看动态链接库依赖
ldd hello 
        linux-vdso.so.1 (0x00007ffea91f1000)
        libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007f8fc6ac6000)
        libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f8fc68a8000)
        libdl.so.2 => /lib64/libdl.so.2 (0x00007f8fc66a4000)
        libc.so.6 => /lib64/libc.so.6 (0x00007f8fc62f7000)
        /lib64/ld-linux-x86-64.so.2 (0x00007f8fc6cdc000)

# step 2, 查看当前系统glibc版本
ll /lib64/libc.so.6
lrwxrwxrwx 1 root root 12 Dec 31 13:39 /lib64/libc.so.6 -> libc-2.18.so

# step 3, 运行程序
./hello 
Hello, world!

参考文档:

  1. Building a linux cross-compile toolchain under Cygwin64 on Windows
  2. window上交叉编译linux目标程序教程

你可能感兴趣的:(Rust,rust,交叉编译)