C++ ときどき ごはん、わりとてぃーぶれいく☆

Wonder Rabbit Projectのなかのひとのブログ。主にC++。

rust, windows: crate gdal を windows, vscode 環境で使用可能にするメモ

こんかい使えるようにする対象物

crate gdal は内部的に元のGDAL(の動的リンクライブラリー)を呼びつけて GeoJSON を読んだりできるラッパータイプのライブラリー。 extern crate gdal だけでは使えないので使える状態にするメモを残す。

extern crate gdal なプロジェクトをビルド・実行可能にする手順

1. myapp プロジェクトを用意、 crate gdal を取り込む

  1. cargo new myapp
  2. cd myapp
  3. cargo add gdal (note: https://github.com/killercup/cargo-edit )
  4. main.rs を↓のように gdalのdocs冒頭のサンプルなど参考に動作確認程度に用意します。
  5. cargo build を試す (この段階では失敗しますがエラーメッセージを読むとなんでかわかります。この後のメモで解決するための作業を記します。)
extern crate gdal;
use std::path::Path;
use gdal::vector::Dataset;

fn main()
{
  println!( "[start]" );
  let mut dataset = Dataset::open(Path::new( "sample1.geojson" ) ).unwrap();
  let layer = dataset.layer( 0 ).unwrap();
  for feature in layer.features()
  {
    let geometry = feature.geometry();
    println!( "{}", geometry.wkt().unwrap() );
  }
  println!( "[end]" );
}

2. vscode の Task として crate gdal をビルド可能にする

2.1. GDAL の動的リンクライブラリーを用意する

2.1.1. vcpkg を用意

いくつか方法があります。このメモでは vcpkg を使う方法を採用します。vcpkg はシステムレベルではなくユーザーディレクトリーレベルでの使用を前提に設計されているようです。適当な場所に用意します。

  1. Super(Win)+R -> powershell (note: mingw/mintty などから powershell を起動するとインストールスクリプトがまともに動作しない可能性があります。)
  2. cd %USERPROFILE%
  3. mkdir opt
  4. cd opt
  5. git clone https://github.com/Microsoft/vcpkg.git ( git が使えませんとかはこのメモでは解説の範囲外という事にします。必要ならぐぐってください。 )
  6. cd vcpkg
  7. .\bootstrap-vcpkg.bat
  8. Windows環境変数VCPKG_DEFAULT_TRIPLET=x64-windows を追加しておく。(x64にしたくない場合は設定しないとか、実行ごとにパラメーターを付ける方法とかもあります。必要なら適当に調べてください。参考)

これで vcpkg.exe が生成されるので、必要ならパスを通すとか、alias を用意して使いやすくするとかしておきます。また、 Visual StudioC++ プロジェクトから簡単に vcpkg を使用できるようにしたければ vcpkg integrate install などもREADME を参考にしておきますが、さしあたり今回メモの用途としてはどうでもいいです。

2.1.2. vcpkg で GDAL と依存ライブラリーを芋蔓に用意する

  1. vcpkg install gdal
  2. 最大で118個のパッケージをダウンロード、ビルドされるのを待つ。長い時間が必要なので1時間くらいゲームなどしてくるとよいかもしれない。

これで vcpkg を配置したディレクトリーへ installed\x64-windows ができて、その中に include lib bin などプログラマーならわかるな?的なディレクトリーも作られ、インストールを叩いたパッケージと芋蔓されたパッケージの全てのそんなようなものが入っています。

3. extern crate gdal している myapp プロジェクトをビルドできるようにする

  1. tasks.json を↓な具合に調整。大事なところは env で設定している crate gdal が内部的で依存している gdal-sys のビルド時に要求される GDAL_HOME GDAL_INCLUDE_DIR GDAL_LIB_DIR の3つの環境変数群です。%USERPROFILE%など環境変数の展開は機能しなかったので vcpkg のパスを地味に書きます。実際に入れたパスへ読み替えて下さい。
  2. vcpkg で生成した lib に入っている gdal.lib を gdal_i.lib としてコピーしておく。(crate gdal の中の gdal-sys のビルドの要求でそのようになっているので、こうしておくのが手っ取り早い。)
{ "version": "2.0.0"
, "tasks":
  [
  , { "label": "cargo build debug"
    , "type":"shell"
    , "command": "cargo"
    , "args": [ "build" ]
    , "group":
      { "kind": "build"
      , "isDefault": true
      }
    , "problemMatcher": "$rustc"
    , "presentation": { "panel": "new" }
    , "options":
      { "env":
        { "GDAL_HOME": "C:\\Users\\your_name\\opt\\vcpkg\\installed\\x64-windows"
        , "GDAL_INCLUDE_DIR": "C:\\Users\\your_name\\opt\\vcpkg\\installed\\x64-windows\\include"
        , "GDAL_LIB_DIR": "C:\\Users\\your_name\\opt\\vcpkg\\installed\\x64-windows\\lib"
        }
      }
    }
  ]
}

これで myapp のビルドは完了できるようになります。一応。しかしまだ、実行できません。

4. myapp を実行可能にする

  1. vcpkg の install で生成した bin の中には↓の実行時リンク用のライブラリーファイルが格納されているので、全て myapp の target/debug/myapp.exe と同じディレクトリーへコピーしましょう。なお、ライブラリーのファイル名は実行環境や実行時のパッケージに定義されているライブラリーのバージョン等により異なります。
boost_atomic-vc141-mt-x64-1_67.dll      boost_math_tr1l-vc141-mt-x64-1_67.dll            geos_c.dll      libpq.dll
boost_chrono-vc141-mt-x64-1_67.dll      boost_prg_exec_monitor-vc141-mt-x64-1_67.dll     icudt61.dll     libxml2.dll
boost_container-vc141-mt-x64-1_67.dll   boost_random-vc141-mt-x64-1_67.dll               icuin61.dll     lz4.dll
boost_date_time-vc141-mt-x64-1_67.dll   boost_regex-vc141-mt-x64-1_67.dll                icuio61.dll     lzma.dll
boost_filesystem-vc141-mt-x64-1_67.dll  boost_serialization-vc141-mt-x64-1_67.dll        icutu61.dll     openjp2.dll
boost_graph-vc141-mt-x64-1_67.dll       boost_system-vc141-mt-x64-1_67.dll               icuuc61.dll     proj_4_9.dll
boost_iostreams-vc141-mt-x32-1_67.dll   boost_thread-vc141-mt-x64-1_67.dll               libbz2.dll      sqlite3.dll
boost_locale-vc141-mt-x64-1_67.dll      boost_timer-vc141-mt-x64-1_67.dll                libcharset.dll  ssleay32.dll
boost_math_c99-vc141-mt-x64-1_67.dll    boost_unit_test_framework-vc141-mt-x64-1_67.dll  libcurl.dll     webp.dll
boost_math_c99f-vc141-mt-x64-1_67.dll   boost_wserialization-vc141-mt-x64-1_67.dll       libeay32.dll    webpdecoder.dll
boost_math_c99l-vc141-mt-x64-1_67.dll   expat.dll                                        libiconv.dll    webpdemux.dll
boost_math_tr1-vc141-mt-x64-1_67.dll    gdal203.dll                                      libmysql.dll    webpmux.dll
boost_math_tr1f-vc141-mt-x64-1_67.dll   geos.dll                                         libpng16.dll    zlib1.dll

これでビルドした myapp.exe は実行可能です。(データが無ければ panic して動作確認できませんが。)

5. 動作確認用の GeoJSON データを用意して動作確認する

  1. https://github.com/gsi-cyberjapan/geojson-with-style-spec/blob/gh-pages/sample1.geojson など適当に GeoJSON を入手するなり手書きするなりして myapp.exe と同じディレクトリーまたはソースコードでパスを指定した場所と併せて配置します。
  2. デバッグ実行なり、直接 myapp.exe を叩くなりして動作確認しましょう。

おつかれさまでした😃

だそく

もし、vcpkg による install や、それによって生成あるいは他の手法であれ確保した実行時ライブラリーファイル群のコピーを自動化したい場合には Cargo.toml には残念ながらそのような依存ファイルのコピー機能は無さそうなので、 vscode の tasks.json で制御すると良さそうです。

あんまり美しくないので積極的に使いたいライブラリーとは言い難いところはありますが、他の手段ではなく GDAL を rust から使いたい場合には有用かもしれません。