Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

Rust Linux上でWindows用のDLLを生成する

More than 1 year has passed since last update.

概要

RustでのLinux上でのWindowsへのクロスコンパイル

環境は以下

  • debian 10
  • Rust 1.21.1

TL;DR

https://github.com/jacob327/rust-debian2windows

用途

Windowsのバイナリを生成する場合、次の2つが主な用途になりそうです。

  • 実行ファイル (.exe)
  • 動的ライブラリ (.dll)

実行ファイルを新たに生成する場合は64bit環境一択で良いのですが、他のプログラムからdllとして呼び出す場合は32bit環境を考慮する必要がある場合があります。

Linux上にWindowsのコンパイル環境を作る

toolchainとtargetとmingwが必要です。

toolchain:

  • stable-i686-pc-windows-gnu
  • stable-x86_64-pc-windows-gnu

target:

  • i686-pc-windows-gnu
  • x86_64-pc-windows-gnu

つまり次のようにそれぞれインストールすれば良いです。

  • rustup toolchain install stable-i686-pc-windows-gnu stable-x86_64-pc-windows-gnu
  • rustup target add i686-pc-windows-gnu x86_64-pc-windows-gnu
  • sudo apt-get install -y mingw-w64

64bit環境でexeを生成する場合

この場合は比較的簡単でcargo.tomlがあるディレクトリに.cargoディレクトリとその中にconfigファイルを生成すれば良いです。

.cargo/config
[build]
target = "x86_64-pc-windows-gnu"

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"
terminal
$ cargo build
   Compiling mt4_dll v0.1.0 (/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL)
    Finished dev [unoptimized + debuginfo] target(s) in 0.34s

32bit環境でdllを生成する場合

この場合は32bit環境でのコンパイル自体の問題とdllの生成問題があります。

今回は呼び出す側と呼び出される側で次のような内容で実際に作ってみます。

呼び出す側;main.rs
mod lib;
use crate::lib::*;

fn main() {
    println!("{:?}", add(3.0, 2.0));
}
呼び出される側;lib.rs
#[no_mangle]
pub extern fn add(a: f64, b: f64) -> f64 {
    a + b
}

'1. 動的ライブラリにしたいのでcargo.tomldylibである旨を追記します。cdylibでもよいはずです。

cargo.toml
[lib]
crate-type = ["dylib"]

'2. .cargo/config は次のようにi386に変更します。

.cargo/config
[build]
# target = "x86_64-pc-windows-gnu"
target = "i686-pc-windows-gnu"

[target.x86_64-pc-windows-gnu]
linker = "x86_64-w64-mingw32-gcc"

[target.i686-pc-windows-gnu]
linker = "i686-w64-mingw32-gcc"
rustflags = "-C panic=abort"

'3. 使用するオブジェクトファイルを入れ替えます。

terminal
cd ~/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib

cp crt2.o crt2.o.bak
cp /usr/i686-w64-mingw32/lib/crt2.o crt2.o

cp dllcrt2.o dllcrt2.o.bak
cp /usr/i686-w64-mingw32/lib/dllcrt2.o dllcrt2.o

これで正常にコンパイルできるはずです。

terminal
$ cargo build
    Finished dev [unoptimized + debuginfo] target(s) in 0.00s

実行

実行するにはwineを入れましょう(mingwでやるのが王道ぽい気がしますが)。

temrinal
sudo dpkg --add-architecture i386
sudo apt-get update
sudo apt-get install -y wine32
terminal
$ wine ./target/i686-pc-windows-gnu/debug/mt4_dll.exe 
5.0

エラー内容

  • .cargo/configrustflags="-C panic=abort"がない場合は次のようなエラーがでます。
$ cargo build
   Compiling mt4_dll v0.1.0 (/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL)
error: linking with `i686-w64-mingw32-gcc` failed: exit code: 1
  |
  = note: "i686-w64-mingw32-gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-nostdlib" "-Wl,--large-address-aware" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/dllcrt2.o" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/rsbegin.o" "-L" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll.4jj8cggy17wroq5l.rcgu.o" "-o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll.dll" "-Wl,--version-script=/tmp/rustc6GNGJA/list" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll.5e7u1yd21s9rzl5z.rcgu.o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll.1osk0zeab4eylqmu.rcgu.o" "-nodefaultlibs" "-L" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps" "-L" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/debug/deps" "-L" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib" "-Wl,--start-group" "-Wl,-Bstatic" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/libstd-9d01ece378a391cf.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/libpanic_unwind-0c029c00da54fbf5.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/libhashbrown-88fcc0245bd24629.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/librustc_std_workspace_alloc-f12aad15d8a75f72.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/libbacktrace-55381df32023f6e1.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/libbacktrace_sys-8dfa5f2af7948d79.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/librustc_demangle-3c26c70d611bf813.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/libunwind-a515e8a3aaec53f5.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/libcfg_if-ea28d0cc615ab33b.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/liblibc-397d570cca7da304.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/liballoc-6c3a8a4f0068446e.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/librustc_std_workspace_core-067eca854694af12.rlib" "-Wl,--no-whole-archive" "-Wl,--whole-archive" "/tmp/rustc6GNGJA/libcore-82b4242551359f3e.rlib" "-Wl,--no-whole-archive" "-Wl,--end-group" "/tmp/rustc6GNGJA/libcompiler_builtins-22c0c99dab989005.rlib" "-Wl,-Bdynamic" "-ladvapi32" "-lws2_32" "-luserenv" "-Wl,-Bstatic" "-lgcc_eh" "-lpthread" "-shared" "-Wl,--out-implib,/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll.dll.lib" "-Wl,-Bdynamic" "-lmingwex" "-lmingw32" "-lgcc" "-lmsvcrt" "-lmsvcrt" "-luser32" "-lkernel32" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/rsend.o"
  = note: /usr/bin/i686-w64-mingw32-ld: /tmp/rustc6GNGJA/libpanic_unwind-0c029c00da54fbf5.rlib(panic_unwind-0c029c00da54fbf5.panic_unwind.2hgzd7yq-cgu.0.rcgu.o): in function `ZN12panic_unwind3imp5panic17h03027a0e504502cdE':
          /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14\/src\libpanic_unwind/gcc.rs:73: undefined reference to `_Unwind_RaiseException'
          /usr/bin/i686-w64-mingw32-ld: /tmp/rustc6GNGJA/libpanic_unwind-0c029c00da54fbf5.rlib(panic_unwind-0c029c00da54fbf5.panic_unwind.2hgzd7yq-cgu.0.rcgu.o): in function `rust_eh_unwind_resume':
          /rustc/73528e339aae0f17a15ffa49a8ac608f50c6cf14\/src\libpanic_unwind/gcc.rs:327: undefined reference to `_Unwind_Resume'
          collect2: error: ld returned 1 exit status
  • オブジェクトファイルが古い場合のエラーは次のようなエラーがでます。
$ cargo build
   Compiling mt4_dll v0.1.0 (/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL)
error: linking with `i686-w64-mingw32-gcc` failed: exit code: 1
  |
  = note: "i686-w64-mingw32-gcc" "-Wl,--enable-long-section-names" "-fno-use-linker-plugin" "-Wl,--nxcompat" "-nostdlib" "-Wl,--large-address-aware" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/crt2.o" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/rsbegin.o" "-L" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.12x1c16zdc8jvebv.rcgu.o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.17z2r1etgfgqhz1e.rcgu.o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.1oq40yr5ubbihise.rcgu.o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.215db9r17sgnchnc.rcgu.o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.25ql4imwrk7n0w5l.rcgu.o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.2d0k8096jfym2til.rcgu.o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.4ge0fd26jn5tl9xo.rcgu.o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.9hr4z7rhdfhbgr7.rcgu.o" "-o" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.exe" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps/mt4_dll-300ee3bf26711df8.2tnyezrpsl3lelsr.rcgu.o" "-Wl,--gc-sections" "-nodefaultlibs" "-L" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/i686-pc-windows-gnu/debug/deps" "-L" "/home/jacob/Documents/copyTradeMt4/dev/client/MT4DLL/target/debug/deps" "-L" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib" "-Wl,--start-group" "-Wl,-Bstatic" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libstd-9d01ece378a391cf.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libpanic_abort-989d5d635b77fed7.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libhashbrown-88fcc0245bd24629.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/librustc_std_workspace_alloc-f12aad15d8a75f72.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libbacktrace-55381df32023f6e1.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libbacktrace_sys-8dfa5f2af7948d79.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/librustc_demangle-3c26c70d611bf813.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libunwind-a515e8a3aaec53f5.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libcfg_if-ea28d0cc615ab33b.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/liblibc-397d570cca7da304.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/liballoc-6c3a8a4f0068446e.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/librustc_std_workspace_core-067eca854694af12.rlib" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libcore-82b4242551359f3e.rlib" "-Wl,--end-group" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/libcompiler_builtins-22c0c99dab989005.rlib" "-Wl,-Bdynamic" "-ladvapi32" "-lws2_32" "-luserenv" "-Wl,-Bstatic" "-lgcc_eh" "-lpthread" "-Wl,-Bdynamic" "-lmingwex" "-lmingw32" "-lgcc" "-lmsvcrt" "-lmsvcrt" "-luser32" "-lkernel32" "/home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/rsend.o"
  = note: /usr/bin/i686-w64-mingw32-ld: /home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/crt2.o:crtexe.c:(.text+0x75): undefined reference to `__onexitend'
          /usr/bin/i686-w64-mingw32-ld: /home/jacob/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/i686-pc-windows-gnu/lib/crt2.o:crtexe.c:(.text+0x7a): undefined reference to `__onexitbegin'
          collect2: error: ld returned 1 exit status

jacob_327
Pythonerです。たまにMQL4とかC++も。 Rustが最強すぎる
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away