状況
UbuntuからWin64向けにDLLを作成しようとcrossでコンパイルしてみたが、相対パスで指定したローカル上のクレートが見つからないと怒られた。
注意
この記事の内容はしょうもないミスを繰り返さないための備忘録です。内容もしょうもないです。
解法
crossには指定したイメージを用いてコンパイルする機能があるため、必要なクレートを含んだイメージを作成し、そのイメージを使ってコンパイルする。
イメージの準備
Win64へクロスコンパイルするときは次のようになる。
FROM rustembedded/cross:x86_64-pc-windows-gnu
COPY ./クレートA /project/クレートA
COPY /home/develop/libs/クレートB /project/クレートB
コピー先のprojectとはcrossがコンパイル対象を設置するフォルダである。crossはこの中であんなことやこんなことをしてるのだ。
もちろんFROM
はコンパイル先に合わせて適宜変更すること。コロン(:)以下をtargetと一致させればよい。(と経験則から思ってるだけ。要確認)
あとはdocker build
してイメージを作る。ここではイメージ名をsaikyou-img
とする。
Cross.tomlを作成
Cargo.tomlではない。そして**.cargo/config**でもない。
私はCross.tomlだと気がつかず、ずっとCargo.tomlを変更して数時間ほど悩んでいた。
ということで、Cargo.tomlと同じ場所にCross.tomlを作成する。内容は次の通り。
[target.x86_64-pc-windows-gnu]
image = "saikyou-img"
これでcrossのコンパイルにsaikyou-img
が用いられるようになる。
それでもクレートが見つからないと言われる
まず、私のようにCargo.tomlを書き換えていないか確認しよう。イメージの指定はCargo.tomlではなく
Cross.toml
だからな?
それでも違ったら、コンパイル時に吐かれるエラーから、コンパイラが参照しているパスに本当にクレートがあるかを確認してほしい。
これはイメージからコンテナを作成し、lsして確認するとわかりやすい。
どうして、そんなパスの食い違いが起こるかは、例えば
[dependant.クレートA]
path = "../../../../../my-libs/クレートA"
なんてあったら、実際にコンテナ内で参照されるのは/my-libs/クレートA
だ。projectディレクトリから4回上にあがってもルートディレクトリで止まりっぱなしだからだ。
ということで、クレートのコピー先はCargo.toml
の内容も吟味して設置しなくてはならない。
あとは、わからん。自力でガンバ!頑張る君はかっこいいぞ!
最後に
誰かが、こんなしょうもないミスを避けられたり、何時間もかけずに解決できたのなら幸いです。
どうか私みたいに、こんなしょうもないミスで何時間も消費しませんように。