在Windows环境下交叉编译Linux程序使用musl与gnu 两种target方式的区别在Windows 10 配置Rust交叉编译Linux应用程序-musl这篇配置target=x86_64-unknown-linux-musl时已经解释了,gnu使用动态链接,目标服务器(部署或者执行目标代码的服务)需要包含依赖的相关用户共享库。
添加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) # 这个是本次文档安装的。
在之后配置编译链接程序时需要解压等工具,验证用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"
备注
:
我的电脑,属性,高级系统设置,环境变量,系统变量,Path 增加一段新的配置:
C:\Tools\cygwin64\bin
我们不自己编译生成交叉编译使用的工具库(编译很慢也很容易出问题要解决),我们这里使用别人已经编译好的工具库,如果你想自己编译可以参考这篇文档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 通过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 文件进行针对具体项目的配置
# 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/
# 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可以参考文档这里 或者 这里
# 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!
参考文档: