rust交叉編譯問題及報錯解析
rust交叉編譯
純粹的rust
代碼是很容易實現(xiàn)交叉編譯,但是使用到的庫中如果使用到C/C++
,編譯就會比較復雜,直接運行交叉編譯命令如下,可能直接報錯
$ cargo build -r --target aarch64-apple-darwin
交叉依賴于項目https://github.com/cross-rs/cross
利用docker
簡化了在x86_64
的linux
操作系統(tǒng)上進行交叉編譯時所需要的前置設(shè)置
安裝
$ cargo install cross
該項目需要依賴docker
或者podman
獲取鏡像的時候由于是直接拉ghcr.io/cross-rs/*
的鏡像,所以國內(nèi)配置的鏡像是無法使用的,這個時候需要配置docker
的代理服務才行
查看docker
服務配置文件位置
$ sudo systemctl status docker ● docker.service - Docker Application Container Engine Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
依據(jù)上面命令輸出,修改文件/lib/systemd/system/docker.service
配置HTTP
代理,代理的參數(shù)值需要依據(jù)自己代理而調(diào)整
[Service] Environment="HTTP_PROXY=http://127.0.0.1:20171" Environment="HTTPS_PROXY=http://127.0.0.1:20171"
重啟服務
$ sudo systemctl daemon-reload $ sudo systemctl restart docker
執(zhí)行交叉編譯
使用的時候需要把cargo
替換為cross
命令
$ cross build -r --target x86_64-pc-windows-gnu
執(zhí)行的時候會自動拉取一個鏡像ghcr.io/cross-rs/x86_64-pc-windows-gnu:{version}
,version
參數(shù)的值是默認依據(jù)cross
的版本號定的,比如執(zhí)行命令如下,發(fā)現(xiàn)版本號是0.2.5
,則對應的獲取鏡像是ghcr.io/cross-rs/x86_64-pc-windows-gnu:0.2.5
$ cross --version cross 0.2.5 [cross] note: Falling back to `cargo` on the host. cargo 1.68.0 (115f34552 2023-02-26)
編譯時候的報錯解決
該錯誤一般會出現(xiàn)在rust
以及第三方庫版本非常新,但是cross
的版本是比較久之前發(fā)布的
目前cross
的版本是0.2.5
,對應的tag
值也是一樣
編譯過程當中會出現(xiàn)如下錯誤,表示找不到某個GLIBC
版本
error: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.28' not found (required by /target/release/deps/libfutures_macro-7a167e0564403030.so)
查看容器基礎(chǔ)鏡像信息
$ docker run ghcr.io/cross-rs/x86_64-pc-windows-gnu:0.2.5 cat /etc/os-release NAME="Ubuntu" VERSION="18.04.6 LTS (Bionic Beaver)" ... VERSION_CODENAME=bionic UBUNTU_CODENAME=bionic
查看支持的GLIBC
版本信息
$ docker run ghcr.io/cross-rs/x86_64-pc-windows-gnu:0.2.5 strings /lib/x86_64-linux-gnu/libc.so.6|grep GLIBC GLIBC_2.2.5 .... GLIBC_2.24 GLIBC_2.25 GLIBC_2.26 GLIBC_2.27 GLIBC_PRIVATE GNU C Library (Ubuntu GLIBC 2.27-3ubuntu1.6) stable release version 2.27.
解決步驟
- 切換到項目
https://github.com/cross-rs/cross
的tag v0.2.5
查看文件cross/docker/Dockerfile.x86_64-pc-windows-gnu
發(fā)現(xiàn)第一行確實是FROM ubuntu:18.04
- 這個時候瀏覽器直接訪問地址
ghcr.io/cross-rs/x86_64-pc-windows-gnu
,會跳轉(zhuǎn)到https://github.com/cross-rs/cross/pkgs/container/x86_64-pc-windows-gnu
- 發(fā)現(xiàn)鏡像的
tag
列表當中存在edge
或者main
,鏡像很新,對應的是main
分支的鏡像,一般使用這種tag
的鏡像基本可以解決99%
的GLIBC
版本找不到的問題,雖然不是release
版本的tag
,但是rust
的程序只要可以成功編譯出來,就基本不用有什么執(zhí)行問題的,可以放心使用
在項目根目錄下面(與Cargo.toml
同級)創(chuàng)建一個文件Cross.toml
寫入如下
[target.x86_64-pc-windows-gnu] image = "ghcr.io/cross-rs/x86_64-pc-windows-gnu:edge"
之后再次執(zhí)行編譯就會使用最新的edge
鏡像了
$ cross build -r --target x86_64-pc-windows-gnu
交叉編譯蘋果系列
下面采用target aarch64-apple-darwin
作為示范
原因
出于版權(quán)原因,cross
項目未提供ios/darwin
相關(guān)的容器鏡像,所以需要自己構(gòu)建鏡像
版權(quán)說明查看地址https://github.com/cross-rs/cross-toolchains#apple-targets
cross
還是提供了部分macos/apple
相關(guān)的鏡像制作的代碼,后續(xù)所有操作版權(quán)問題要自己負責
clone
項目
$ git clone https://github.com/cross-rs/cross $ cd cross $ git submodule update --init --remote
其他依賴的倉庫
cross
的打包編譯蘋果的時候需要使用到如下倉庫,用來生成macos cross toolchain
和其他一些操作, 該倉庫僅作了解
https://github.com/tpoechtrager/osxcross
交叉編譯的時候需要傳遞docker build-arg
參數(shù),MACOS_SDK_DIR和MACOS_SDK_FILE
或者傳遞一個單獨的MACOS_SDK_URL
參數(shù),該參數(shù)是蘋果的構(gòu)建包數(shù)據(jù)信息,這個時候可以選擇自己整臺MACOS
去獲取MACOS_SDK
包,也可以通過第三方倉庫獲取Macos-sdk
https://github.com/phracker/MacOSX-SDKs
在倉庫的release
下查找打包好的sdk
,下面我會使用macos-11.1-sdk
作為MACOS_SDK_URL
的參數(shù)
https://github.com/phracker/MacOSX-SDKs/releases/download/11.0-11.1/MacOSX11.1.sdk.tar.xz
修改dockerfile
進入到剛剛的cross
倉庫下面,找到文件docker/cross-toolchains/docker/Dockerfile.x86_64-apple-darwin-cross
由于鏡像構(gòu)建過程中會有大量的git clone, curl
等網(wǎng)絡(luò)操作,國內(nèi)環(huán)境需要配置一下代理,在FROM
下面一行增加代理信息
ENV HTTP_PROXY=http://*****:** ENV HTTPS_PROXY=http://{IP}:{端口}
修改MACOS_SDK_URL
參數(shù)改為
ARG MACOS_SDK_URL="https://github.com/phracker/MacOSX-SDKs/releases/download/11.3/MacOSX11.3.sdk.tar.xz"
docker
組件依賴
交叉編譯需要使用到docker buildx
,這個非常重要,是能夠打包新cross docker
鏡像的關(guān)鍵,由于buildx
還處于實驗期,一直不是很穩(wěn)定,所以需要配置docker
開啟該功能
修改~/.docker/config.json
,增加一行
{ ... "experimental": "enabled" ... }
校驗是否啟用, 如下,Experimental: true
表示配置成功
$ docker version Client: Docker Engine - Community Version: 20.10.17 API version: 1.41 Go version: go1.17.11 Git commit: 100c701 Built: Mon Jun 6 23:02:57 2022 OS/Arch: linux/amd64 Context: default Experimental: true
檢查buildx
版本
$ docker buildx version github.com/docker/buildx v0.** ***********
開始構(gòu)建,構(gòu)建完成之后會生成一個鏡像aarch64-apple-darwin-cross:local
$ cargo build-docker-image aarch64-apple-darwin-cross --tag local
如果遇到報錯,如下,看提示和建議信息好像是說buildx
未被安裝,解決方案也是配置環(huán)境變量CROSS_CONTAINER_ENGINE_NO_BUILDKIT=1
不使用buildx
error: failed to solve: rpc error: code = Unknown desc = failed to solve with frontend dockerfile.v0: failed to create LLB definition: unexpected status code [manifests 20.04]: 403 Forbidden ...... Location: /rustc/90c541806f23a127002de5b4038be731ba1458ca/library/core/src/convert/mod.rs:727 Warning: call to docker failed Suggestion: is `buildx` available for the container engine? Note: disable the `buildkit` dependency optionally with `CROSS_CONTAINER_ENGINE_NO_BUILDKIT=1`
這個時候要淡定,不接受他的建議
先嘗試去訪問buildx
倉庫如下,獲取最新的一個release
版本
https://github.com/docker/buildx
比如現(xiàn)在獲取到的最新的buildx
的下載鏈接
https://github.com/docker/buildx/releases/download/v0.11.0/buildx-v0.11.0.linux-amd64
下載之后按照buildx
倉庫readme
的提示,替換原來的docker-buildx
linux
的docker plugin
的可能位置有
/usr/local/lib/docker/cli-plugins
OR/usr/local/libexec/docker/cli-plugins
/usr/lib/docker/cli-plugins
OR/usr/libexec/docker/cli-plugins
像我的Ubuntu22
機器就是執(zhí)行如下命令
$ sudo mv buildx-v0.11.0.linux-amd64 /usr/libexec/docker/cli-plugins/docker-buildx $ sudo chmod a+x /usr/libexec/docker/cli-plugins/docker-buildx
執(zhí)行完成之后再檢查buildx
版本,一般buildx
運行的時候是會遇到很多問題的,該工具也還在實驗中,也一直在不斷進行更新修復,所以使用最新版本大概率可以解決問題
$ docker buildx version github.com/docker/buildx v0.11.0 687feca9e8dcd1534ac4c026bc4db5a49de0dd6e
最后再次執(zhí)行鏡像構(gòu)建
$ cargo build-docker-image aarch64-apple-darwin-cross --tag local
如果還是報錯再接受建議,執(zhí)行命令如下,不使用buildx
$ CROSS_CONTAINER_ENGINE_NO_BUILDKIT=1 cargo build-docker-image aarch64-apple-darwin-cross --tag local
創(chuàng)建Cross.toml
[target.aarch64-apple-darwin] image = "ghcr.io/cross-rs/aarch64-apple-darwin-cross:local"
執(zhí)行命令如下就完成交叉編譯了
$ cross build --target aarch64-apple-darwin -r
參考閱讀
以上就是rust交叉編譯問題及報錯解析的詳細內(nèi)容,更多關(guān)于rust交叉編譯的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Rust可迭代類型迭代器正確創(chuàng)建自定義可迭代類型的方法
在 Rust 中, 如果一個類型實現(xiàn)了 Iterator, 那么它會被同時實現(xiàn) IntoIterator, 具體邏輯是返回自身, 因為自身就是迭代器,這篇文章主要介紹了Rust可迭代類型迭代器正確創(chuàng)建自定義可迭代類型的方法,需要的朋友可以參考下2023-12-12Rust-使用dotenvy加載和使用環(huán)境變量的過程詳解
系統(tǒng)的開發(fā),測試和部署離不開環(huán)境變量,今天分享在Rust的系統(tǒng)開發(fā)中,使用dotenvy來讀取和使用環(huán)境變量,感興趣的朋友跟隨小編一起看看吧2023-11-11前端基于Rust實現(xiàn)的Wasm進行圖片壓縮的技術(shù)文檔(實現(xiàn)方案)
在現(xiàn)代Web開發(fā)中,利用Rust編寫的圖片壓縮代碼可以編譯成WebAssembly(Wasm)模塊,Rust的內(nèi)存安全特性和Wasm的跨平臺能力,使得這種方案既高效又安全,對Rust?Wasm圖片壓縮實現(xiàn)方案感興趣的朋友一起看看吧2024-09-09如何使用bindgen將C語言頭文件轉(zhuǎn)換為Rust接口代碼
這篇文章主要介紹了使用bindgen將C語言頭文件轉(zhuǎn)換為Rust接口代碼,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-01-01