[Rust] Compilación cruzada de programas de Linux y Windows en Mac (incluida la implementación de Docker)

1. Pasos básicos

  • Instale la biblioteca estándar del objetivo con rustup target add
  • lista de objetivos de rustup Ver la lista de objetivos admitidos
  • Instalar el enlazador de destino
  • Actualice cargo.toml para que rustc sepa qué enlazador usar
  • construcción de carga --liberación --objetivo TARGET_NAME

2. Prepárate

Es posible que todo el proceso deba descargar el paquete github en la línea de comando y configurar el proxy con anticipación (modificar según su propia situación):

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 el programa de linux en la mac

3.1 Preparación

  • Elija el destino correcto (biblioteca estándar con plataforma de destino)

Los objetivos comunes de Linux son x86_64-unknown-linux-gnu y x86_64-unknown-linux-musl

  • La característica de musl es liviana, no tiene dependencias y puede ejecutarse en cualquier sistema Linux. La desventaja es que el programa compilado es más lento que glibc.
  • La característica de gnu es que es más rápido, genera una biblioteca de enlaces dinámicos e instala glibc dependiendo de la plataforma.
  • A continuación se presentarán los pasos de instalación de ambos, elija uno para instalar primero (puede encontrar algunos problemas)
  • Vea la lista de objetivos compatibles con 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 objetivos 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 objetivo de instalación

Instalar musl: rustup target add x86_64-unknown-linux-musl
Instalar gnu:rustup target add x86_64-unknown-linux-gnu

3.3 Instalación del enlazador

Instale el enlazador musl: brew install filosottile/musl-cross/musl-cross
Instale el enlazador gnu:brew install SergioBenitez/osxct/x86_64-unknown-linux-gnu

3.3 Cambiar Cargo.toml

aumentar lo siguiente

[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 Empezar 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 Resolución de problemas

Problema: si los tiempos de compilación final: ld: opción desconocida: --según sea necesario
Solución: use otra herramienta auxiliar, cargo-zigbuild, para compilar (esta herramienta también está escrita en rust para facilitar la compilación cruzada y resolver algunos problemas extraños)

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. Compilar el programa de Windows en Mac

Registro simplificado:

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

Cambie Cargo.toml, agregue lo siguiente

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

Nota: para compilar programas de Windows basados ​​en x86_64-pc-windows-msvc en mac/linux, utilice otra herramienta auxiliar: cargo-xwin

4.1 Resolución de problemas

Problema: Al compilar msvc por fin: cargo xwin build --target x86_64-pc-windows-msvc, error:

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?

Es porque la biblioteca rust-cypto de la que depende el código internamente se basa en la versión anterior de la biblioteca gcc, y la nueva versión de clang-cl no la admite, por lo que la forma más fácil es reemplazar la biblioteca rust-crypto que no se ha actualizado durante más de 6 años para 2022 y utiliza la nueva biblioteca The RustCrypto .

El bloguero intentó instalar la versión anterior de gcc, pero se le indicó que la versión anterior de gcc había sido abandonada y no se podía instalar, por lo que no continuó intentándolo (a partir de la publicación, el bloguero ha estudiado Rust compilación cruzada durante más de 6 horas)

Solución: Modificar Cargo.toml

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

5. Manera más fácil: use Docker

Independientemente del idioma, si desea lograr una compilación cruzada amigable para los desarrolladores, debe entregar este trabajo a Docker, y Rust no es una excepción.
De esta forma, no hay necesidad de deshacerse del host del desarrollador, ni se necesita mucho tiempo para lidiar con varios problemas de dependencia.
Lo siguiente se refiere a rust-musl-cross

5.1 Tire de la imagen requerida

Como x86_64-musl, otros, busque en el enlace anterior

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

5.2 Modificar configuración

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

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

Tenga en cuenta que este paso es muy importante, porque cuando el blogger estaba operando, descubrió que la configuración de destino basada en Cargo.tom originalmente construida en el mac en el contenedor no surtió efecto. El resultado fue cc: error: unrecognized command-line option '-m64'que se informó un error durante la compilación. El ld: unknown option: --as-neededcompilador rust no puede encontrar el enlazador correcto a través de la configuración, así que recuerde.
Además, si desea saber cómo completar la información de otros objetivos, en el siguiente paso, elimine el mapeo .cargo/config y luego ejecute directamente rust_builder. Después de ingresar al contenedor, copie su contenido en su ~/ local cat ~/.cargo/config. .cargo/config Eso es todo.

5.3 Comando Construir ventana acoplable

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 Resolución de problemas

Al intentar compilar target= armv7-unknown-linux-musleabihf, se informa el siguiente error durante la compilación:

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

Entonces el blogger lo pensó, si sería diferente si entraba al contenedor y luego ejecutaba el comando, entonces quedan los siguientes pasos:

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# 

¡Guau! Como puede ver, esto está bien, y el blogger no sabe cuál es el problema. Si los lectores saben una o dos cosas, dejen un mensaje en el área de comentarios para obtener orientación ~

Resumir

Este artículo es un resumen de los bloggers que pasaron mucho tiempo pisando pozos (combinado con sitios como el sitio web oficial cnblog/zhihu/stackoverflow/github/rust).




otra información

Supongo que te gusta

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