[Rust] Compilação cruzada de programas linux e windows no mac (incluindo implementação do Docker)

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-neededcompilador 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/configlocal .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).




outra informação

Acho que você gosta

Origin blog.csdn.net/sc_lilei/article/details/127460105
Recomendado
Clasificación