[Rust] Mac 上で Linux および Windows プログラムをクロスコンパイル (Docker 実装を含む)

1. 基本的な手順

  • rusup target add を使用してターゲットの標準ライブラリをインストールします。
  • rusup ターゲット リスト サポートされているターゲットのリストを表示する
  • ターゲットリンカーをインストールする
  • 使用するリンカーを Rustc に知らせるために、cargo.toml を更新します。
  • カーゴ ビルド --release --target TARGET_NAME

2. 準備する

プロセス全体では、コマンド ラインで github パッケージをダウンロードし、事前にプロキシを設定する必要がある場合があります (状況に応じて変更してください)。

エクスポート https_proxy=http://127.0.0.1:7890 http_proxy=http://127.0.0.1:7890 all_proxy=socks5://127.0.0.1:7890


3. Mac 上で Linux プログラムをコンパイルします。

3.1 準備

  • 適切なターゲットを選択します (ターゲット プラットフォームを備えた標準ライブラリ)

Linux の一般的なターゲットは、x86_64-unknown-linux-gnu および x86_64-unknown-linux-musl です。

  • musl の機能は軽量で依存関係がなく、あらゆる Linux システム上で実行できます。欠点は、コンパイルされたプログラムが glibc よりも遅いことです。
  • gnu の特徴としては、高速であること、ダイナミックリンクライブラリの生成、プラットフォームに応じた glibc のインストールが挙げられます。
  • 以下に両方のインストール手順を紹介します。最初にインストールする方を選択してください (いくつかの問題が発生する可能性があります)。
  • Rust でサポートされているターゲットのリストを表示します。
lei@WilldeMacBook-Pro learn_rust % rustup target list |sort -R
i686-unknown-freebsd
aarch64-apple-ios
x86_64-unknown-linux-musl (installed)
armv5te-unknown-linux-musleabi
i586-unknown-linux-gnu
arm-linux-androideabi
x86_64-linux-android
...几十种
  • インストールされているターゲットを表示します。
lei@WilldeMacBook-Pro learn_rust % rustup target list |grep installed
aarch64-apple-darwin (installed)   -- 这个默认安装的,因为当前平台就是m1pro,下面是手动安装的
x86_64-pc-windows-gnu (installed)
x86_64-pc-windows-msvc (installed)
x86_64-unknown-linux-gnu (installed)
x86_64-unknown-linux-musl (installed)

3.2 インストール先

musl をインストールします。rustup target add x86_64-unknown-linux-musl
gnu をインストールします。rustup target add x86_64-unknown-linux-gnu

3.3 リンカのインストール

musl リンカーをインストールします。brew install filosottile/musl-cross/musl-cross
gnu リンカーをインストールします。brew install SergioBenitez/osxct/x86_64-unknown-linux-gnu

3.3 Cargo.tomlの変更

以下を増やす

[target.x86_64-unknown-linux-musl] # 也支持[build]节点 设置target=...
linker = "x86_64-linux-musl-gcc"
[target.x86_64-unknown-linux-gnu]
linker = "x86_64-unknown-linux-gnu-gcc"

3.3 コンパイルの開始

musl の使用: TARGET_CC=x86_64-linux-musl-gcc cargo build --release --target x86_64-unknown-linux-musl
GNU の使用:TARGET_CC=x86_64-unknown-linux-gnu cargo build --release --target x86_64-unknown-linux-gnu

3.4 トラブルシューティング

問題: 最終コンパイル時間: ld: 不明なオプション: --as-needed
解決策: 別の補助ツールCargo-zigbuildを使用してコンパイルします (このツールは、クロスコンパイルを容易にし、いくつかの奇妙な問題を解決するために Rust で書かれています)

cargo install cargo-zigbuild
brew install zig
cargo zigbuild --release --target x86_64-unknown-linux-musl
或
cargo zigbuild --release --target x86_64-unknown-linux-gnu

4. Mac上でWindowsプログラムをコンパイルする

簡略化されたロギング:

rustup target add x86_64-pc-windows-gnu
brew install mingw-w64   # 链接器

Cargo.toml を変更し、以下を追加します

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
# [target.x86_64-pc-windows-msvc]  不需要填写linker

注: x86_64-pc-windows-msvc に基づいて Windows プログラムを Mac/Linux 上でコンパイルするには、別の補助ツールCargo-xwinを使用してください。

4.1 トラブルシューティング

問題: 最後に msvc をコンパイルするとcargo xwin build --target x86_64-pc-windows-msvc、エラー:

error: failed to run custom build command for `rust-crypto v0.2.36`

Caused by:
  process didn't exit successfully: `/Users/lei/Desktop/Rust/learn_rust/target/debug/build/rust-crypto-a19246e40d1c0ac5/build-script-build` (exit status: 101)
  --- stdout
  TARGET = Some("x86_64-pc-windows-msvc")
  OPT_LEVEL = Some("0")
  TARGET = Some("x86_64-pc-windows-msvc")
  HOST = Some("aarch64-apple-darwin")
  TARGET = Some("x86_64-pc-windows-msvc")
  TARGET = Some("x86_64-pc-windows-msvc")
  HOST = Some("aarch64-apple-darwin")
  CC_x86_64-pc-windows-msvc = None
  CC_x86_64_pc_windows_msvc = Some("clang-cl --target=x86_64-pc-windows-msvc")
  TARGET = Some("x86_64-pc-windows-msvc")
  HOST = Some("aarch64-apple-darwin")
  CFLAGS_x86_64-pc-windows-msvc = None
  CFLAGS_x86_64_pc_windows_msvc = Some("-Wno-unused-command-line-argument -fuse-ld=lld-link /imsvc/Users/lei/Library/Caches/cargo-xwin/xwin/crt/include /imsvc/Users/lei/Library/Caches/cargo-xwin/xwin/sdk/include/ucrt /imsvc/Users/lei/Library/Caches/cargo-xwin/xwin/sdk/include/um /imsvc/Users/lei/Library/Caches/cargo-xwin/xwin/sdk/include/shared")
  DEBUG = Some("true")
  running: "clang-cl --target=x86_64-pc-windows-msvc" "-O0" "-ffunction-sections" "-fdata-sections" "-fPIC" "-Wno-unused-command-line-argument" "-fuse-ld=lld-link" "/imsvc/Users/lei/Library/Caches/cargo-xwin/xwin/crt/include" "/imsvc/Users/lei/Library/Caches/cargo-xwin/xwin/sdk/include/ucrt" "/imsvc/Users/lei/Library/Caches/cargo-xwin/xwin/sdk/include/um" "/imsvc/Users/lei/Library/Caches/cargo-xwin/xwin/sdk/include/shared" "-g" "--target=x86_64-pc-windows-msvc" "-Wall" "-Wextra" "/Fo/Users/lei/Desktop/Rust/learn_rust/target/x86_64-pc-windows-msvc/debug/build/rust-crypto-21fe17a56301ca99/out/src/util_helpers.o" "/c" "src/util_helpers.c"

  --- stderr
  thread 'main' panicked at '

  Internal error occurred: Failed to find tool. Is `clang-cl --target=x86_64-pc-windows-msvc` installed?

これは、コードが依存するrust-cryptoライブラリが内部的に古いバージョンのgccライブラリに依存しており、新しいバージョンのclang-clがそれをサポートしていないためです。そのため、最も簡単な方法は、次のrust-cryptoライブラリを置き換えることです。 2022 年までに 6 年以上更新されていないため、新しいRustCryptoライブラリを使用します。

ブロガーは古いバージョンの gcc をインストールするために brew しようとしましたが、上流バージョンの gcc は放棄されておりインストールできないというメッセージが表示されたため、試行を続行しませんでした (投稿の時点で、ブロガーは Rust を学習しています) 6 時間以上のクロスコンパイル)

解決策: Cargo.toml を変更する

[dependencies] 
# rust-crypto = "0.2.36"
sha2 = "0.10.6"
sha3 = "0.10.6"

5. より簡単な方法 - Docker を使用する

言語に関係なく、開発者にとって使いやすいクロスコンパイルを実現したい場合は、この作業を Docker に引き渡す必要があり、Rust も例外ではありません。
この方法では、開発者のホストを放棄する必要はなく、さまざまな依存関係の問題に対処するために多くの時間を費やす必要もありません。
以下は、rust-musl-crossを指します。

5.1 必要なイメージをプルする

x86_64-musl など、その他は上記のリンクから見つけてください

$ docker pull messense/rust-musl-cross:x86_64-musl

5.2 設定の変更

cd PROJECT/src/   # 进入项目的src目录
vi ~/.cargo/config    添加target部分(与Cargo.toml的target一致)如下

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

この手順は非常に重要であることに注意してください。ブロガーが操作しているときに、最初にコンテナ内の Mac 上にビルドされた Cargo.tom に基づくターゲット設定が有効になっていないことがわかり、その結果、ビルド中にエラーが報告されたcc: error: unrecognized command-line option '-m64'からld: unknown option: --as-neededです。 Rust コンパイラは設定を通じて正しいリンカを見つけることができないので、覚えておいてください
さらに、他のターゲットの情報を入力する方法を知りたい場合は、次のステップで .cargo/config マッピングを削除し、rust_builder を直接実行し、コンテナに入った後、その内容をローカルの ~/ にコピーしますcat ~/.cargo/config。 .cargo/config 以上です。

5.3 ビルド docker コマンド

alias rust_builder='docker run -it --rm -v "$(pwd)":/home/rust/src \
                -v "/Users/lei/.cargo/config:/root/.cargo/config" \
                -v "/Users/lei/.cargo/registry:/root/.cargo/registry" \
                -v "/Users/lei/.cargo/git:/root/.cargo/git" \
            messense/rust-musl-cross:x86_64-musl'
# 注意替换上面-v选项后面的路径为你本地路径,它们主要提供构建的缓存功能,以实现下次构建的加速,避免重复工作

# nightly构建
rust_builder rustup default nightly && rustup target add x86_64-unknown-linux-musl && cargo build --target x86_64-unknown-linux-musl --release
# stable构建
rust_builder cargo build --target x86_64-unknown-linux-musl --release

5.4 トラブルシューティング

target= をビルドしようとするとarmv7-unknown-linux-musleabihf、ビルド中に次のエラーが報告されます。

error: linker `armv7-unknown-linux-musleabihf-gcc` not found
  |
  = note: No such file or directory (os error 2)

そこでブロガーはコンテナに入ってコマンドを実行したら違うのではないかと考え、次のような手順にしました。

lei@WilldeMacBook-Pro learn_rust % alias rust_builder='docker run -it --rm -v "$(pwd)":/home/rust/src \                                                                                
                -v "/Users/lei/.cargo/config:/root/.cargo/config" \
                -v "/Users/lei/.cargo/registry:/root/.cargo/registry" \
                -v "/Users/lei/.cargo/git:/root/.cargo/git" \
            messense/rust-musl-cross:armv7-musleabihf'
lei@WilldeMacBook-Pro learn_rust % rust_builder
root@2fb71f01c5f4:/home/rust/src# rustup default nightly && rustup target add armv7-unknown-linux-musleabihf && cargo build --target armv7-unknown-linux-musleabihf
info: syncing channel updates for 'nightly-aarch64-unknown-linux-gnu'
info: latest update on 2022-10-23, rust version 1.66.0-nightly (6e95b6da8 2022-10-22)
info: downloading component 'cargo'
info: downloading component 'rust-std'
...

    Building [=========================> ] 94/95: learn_rust(bin)                                                                                                                                                                                                                                                     
warning: `learn_rust` (bin "learn_rust") generated 151 warnings (1 duplicate)
    Finished dev [unoptimized + debuginfo] target(s) in 2m 11s
root@2fb71f01c5f4:/home/rust/src# 

おお!ご覧のとおり、これは実際には問題ありませんが、ブロガーには何が問題なのかわかりません。読者の皆様が 1 つか 2 つご存知の場合は、アドバイスのためにコメント エリアにメッセージを残してください~

要約する

この記事は、ピットを踏むのに多くの時間を費やしたブロガーの概要です (cnblog/zhihu/stackoverflow/github/Rust 公式 Web サイトなどのサイトを組み合わせたもの)。




その他の情報

おすすめ

転載: blog.csdn.net/sc_lilei/article/details/127460105