1. Etapas básicas
- Instale a biblioteca padrão do destino com adição de destino de ferrugem
- lista de alvos rustup Veja a lista de alvos suportados
- Instalar o vinculador de destino
- Atualize o cargo.toml para permitir que o rustc saiba qual vinculador usar
- construção de carga --release --target TARGET_NAME
2. Prepare-se
Todo o processo pode precisar baixar o pacote github na linha de comando e definir o proxy com antecedência (modifique de acordo com sua própria situação):
exportar 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. Compile o programa linux no mac
3.1 Preparação
- Escolha o alvo certo (biblioteca padrão com plataforma alvo)
Os alvos comuns do Linux são x86_64-unknown-linux-gnu e x86_64-unknown-linux-musl
- O recurso do musl é leve, sem dependências e pode ser executado em qualquer sistema Linux. A desvantagem é que o programa compilado é mais lento que o glibc.
- A característica do gnu é que ele é mais rápido, gera uma biblioteca de links dinâmicos e instala glibc dependendo da plataforma.
- A seguir apresentará as etapas de instalação de ambos, escolha uma para instalar primeiro (você pode encontrar alguns problemas)
- Veja a lista de alvos suportados pelo 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
...几十种
- Ver alvos instalados:
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 alvo de instalação
Instalar musl: rustup target add x86_64-unknown-linux-musl
Instalar gnu:rustup target add x86_64-unknown-linux-gnu
3.3 Instalando o vinculador
Instale o linker musl: brew install filosottile/musl-cross/musl-cross
Instale o linker gnu:brew install SergioBenitez/osxct/x86_64-unknown-linux-gnu
3.3 Alterar Cargo.toml
aumentar o seguinte
[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 Comece a compilar
Usando musl: TARGET_CC=x86_64-linux-musl-gcc cargo build --release --target x86_64-unknown-linux-musl
usando gnu:TARGET_CC=x86_64-unknown-linux-gnu cargo build --release --target x86_64-unknown-linux-gnu
3.4 Solução de problemas
Problema: Se os tempos de compilação final: ld: opção desconhecida: --conforme necessário
Solução: Use outra ferramenta auxiliar cargo-zigbuild para compilar (esta ferramenta também é escrita em ferrugem para facilitar a compilação cruzada e resolver alguns problemas estranhos)
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. Compile o programa Windows no mac
Log simplificado:
rustup target add x86_64-pc-windows-gnu
brew install mingw-w64 # 链接器
Altere Cargo.toml, adicione o seguinte
[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
# [target.x86_64-pc-windows-msvc] 不需要填写linker
Nota: Para compilar programas Windows baseados em x86_64-pc-windows-msvc no mac/linux, use outra ferramenta auxiliar: cargo-xwin
4.1 Solução de problemas
Problema: Ao compilar o msvc no último: cargo xwin build --target x86_64-pc-windows-msvc
, erro:
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?
É porque a biblioteca rust-cypto da qual o código depende internamente depende da versão antiga da biblioteca gcc, e a nova versão do clang-cl não a suporta, então a maneira mais fácil é substituir a biblioteca rust-crypto que não foi atualizado por mais de 6 anos até 2022 e use a nova biblioteca The RustCrypto .
O blogueiro tentou preparar para instalar a versão antiga do gcc, mas foi avisado que a versão upstream do gcc havia sido abandonada e não podia ser instalada; então ele não continuou a tentar (a partir do post, o blogueiro estudou Rust compilação cruzada por mais de 6 horas)
Solução: Modifique Cargo.toml
[dependencies]
# rust-crypto = "0.2.36"
sha2 = "0.10.6"
sha3 = "0.10.6"
5. Maneira mais fácil - use o Docker
Independentemente do idioma, se você deseja obter uma compilação cruzada amigável ao desenvolvedor, deve entregar esse trabalho ao Docker, e o Rust não é exceção.
Dessa forma, não há necessidade de descartar o host do desenvolvedor, nem muito tempo para lidar com vários problemas de dependência.
O seguinte refere-se a ferrugem-musl-cruz
5.1 Puxe a imagem necessária
Como x86_64-musl, outros podem ser encontrados no link acima
$ docker pull messense/rust-musl-cross:x86_64-musl
5.2 Modificar configuração
cd PROJECT/src/ # 进入项目的src目录
vi ~/.cargo/config 添加target部分(与Cargo.toml的target一致)如下
[target.x86_64-unknown-linux-musl]
linker = "x86_64-linux-musl-gcc"
Observe que esta etapa é muito importante, pois quando o blogueiro estava operando, ele descobriu que a configuração de destino baseada em Cargo.tom originalmente construída no mac no contêiner não fazia efeito. O resultado foi cc: error: unrecognized command-line option '-m64'
que um erro foi relatado durante a compilação O ld: unknown option: --as-needed
compilador de ferrugem não pode encontrar o vinculador correto por meio da configuração, portanto, lembre-se.
Além disso, se você quiser saber como preencher as informações de outros destinos, na próxima etapa, remova o mapeamento .cargo/config e execute o rust_builder diretamente. Após entrar no contêiner, copie seu conteúdo para o seu ~/ cat ~/.cargo/config
local .cargo/config É isso.
5.3 Construir comando 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 Solução de problemas
Ao tentar construir target= armv7-unknown-linux-musleabihf
, o seguinte erro é relatado durante a construção:
error: linker `armv7-unknown-linux-musleabihf-gcc` not found
|
= note: No such file or directory (os error 2)
Aí o blogueiro pensou nisso, se seria diferente se ele entrasse no container e depois executasse o comando, então seguem os seguintes passos:
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#
Uau! Como você pode ver, está tudo bem, e o blogueiro não sabe qual é o problema. Se os leitores souberem de uma ou duas coisas, deixe uma mensagem na área de comentários para orientação ~
Resumir
Este artigo é um resumo de blogueiros que passaram muito tempo pisando em poços (combinado com sites como o site oficial cnblog/zhihu/stackoverflow/github/rust).