pygrib が Microsoft Visual Studio でビルド出来るようになる話

GPVで沸点予報(誰得?)」で誤魔化した pygrib の MSVS 対応の話。

pygrib が Microsoft Visual Studio でビルド出来るようになる話

2015年10月23日に書いた内容

気象屋さん以外でこれを必要とする人は稀だろうなぁ、とは思うけれど。まぁだからこそこの情報を供給する人も少ないだろうからな。

今週対応するってさ。

なお、Microsoft Visual C++ Compiler for Python 2.7では、この対応でもちょいとツラいとこは残るよ:

  1. Microsoft Visual C++ Compiler for Python 2.7 だけではソリューションファイル・プロジェクトファイルを扱えないので、ECMWF GRIB-API Microsoft Windows (experimental)のほうのビルドが手間。
  2. Microsoft Visual C++ Compiler for Python 2.7、というか VC9 には inttypes.h がないので、pygrib ではエラーになる(はず)。Jeff Whitaker の作業次第、かな。

それと実行環境もひと手間必要。Unix 系だと GRIB-API の「make install」(だっけ?)で definitions が適切な場所に置かれるけど、ECMWF GRIB-API Microsoft Windows (experimental)はなんにもしてくんないので、自分で「置いて」、自分で「環境変数設定」しないといけない。

まぁこんな状態なんで、「出来る人だけやれば?」てのは「GPVで沸点予報(誰得?)」での状態とあんまし変わんない。単に「ずっと楽になる」だけ。












なんというかさ、こういうのをね、例えば業務で必要とするとするじゃない? でターゲットが Unix 系なら、「Unixでだけ動けばいいじゃん」はもちろん正論だし、ワタシも別に大抵はそれでいいと思うんだけれども、たださ、「Windows でも動かせる」と、やっぱりとっても便利なんだよねぇ。

なんでかってぇと、だいたいの企業ってこうだからなのよ:

  • 日常作業に与えられる PC は全て Windows
  • 「開発機」として数少ないサーバ機が、「検証フェーズ」時に導入される(なかなか不自由な、リモートログイン)
  • 「開発フェーズ」直前に、「Unix がインストールされた開発機が開発者に貸与される」、もしくは、「Windows だが VirtualBox などの仮想化で Unix が使える開発機が別途貸与される」、あるいは「VirtualBox などの仮想化で Unix 仮想マシンが配られる」

デスクトップ機として Unix を使うような企業って、今や相当限られてるんじゃないかね。とにかくなかなか Unix を自由に使える状態にならんのよ。こんな状態のときって、「Windows でも検証出来る」って、とってもありがたいことなのね。

まぁ cygwin が許されるようなとこならこれまでも Windows で使えたんだけれどさ…。












2015-10-24 追記
see bump version number, add Changelog entry for pull request #18.

inttypes.h の問題はそのままにしたみたい。ので、MSVC9 の場合(つまり CPython2.7 の場合)は、g2clib.pyx を一箇所変更必要。この部分:

122 cdef extern from "stdlib.h":
123     void free(void *ptr)
124 
125 # get 32 bit integer type
126 cdef extern from "inttypes.h":
127     ctypedef long int32_t

これを例えばこう:

122 cdef extern from "stdlib.h":
123     void free(void *ptr)
124 
125 # get 32 bit integer type
126 #cdef extern from "inttypes.h":
127 ctypedef long int32_t

ChangeLog とコミットログからわかる通り 2.0.1 としてリリースするつもりみたい。だいたいのプロジェクトでは「Bump version number」はリリースを決断してるときなんで、数日中に 2.0.1 入手可能かもしれないね。

2015-10-26 追記
inttypes.h については、MSVC9以前の inttypes.h, stdint.h 問題参照。pyx に手を入れるよりは、ちゃんとした inttypes.h 持ってた方がいいでせう。

それより PR #11 での改造みるまで気付かなかったんだけど、int32_t の typedef、間違ってるのよね。正しくは

122 cdef extern from "stdlib.h":
123     void free(void *ptr)
124 
125 # get 32 bit integer type
126 cdef extern from "inttypes.h":
127     ctypedef int int32_t

2021年5月15日の追記というか

Popular Posts の推移をみてるとどうもこのネタに一定数の人々が今でもコンスタントに喰い付いてるようなんだが、これは個人的にはかなり驚き。どういった人たちなんだか…? 学生?

ともあれ、cartopyの実例に使いたくて個人的にはかなり久しぶりに pygrib したくなって、改めて pygrib を構築し直したので、一応書いとく。

「6年経ってとても事態が改善しました」と言えるならそれは素晴らしいことだけど、恐ろしく進展してなくて、なおかつ少し退行し始めてるのが今の現状。具体的には:

  1. (旧)GRIB-API の MSVC 用の CMake ビルドはどうやら保守されてなくて。
  2. なのでexperimentalのままで。
  3. そして experimental のままなので grib_api.lib のままで。

ゆえに当然の帰結として 2015 年時点でそうだったのと同じく、「はなんにもしてくんないので、自分で「置いて」、自分で「環境変数設定」しないといけない」のまま。

ただまぁ、2015年時点と結構違ってるのは、「さすがにもう python 2.7 のことなんか知らんよ」と切り捨てちゃっていいことで、すなわち、pygrib 側に手心を加える必要はなくなってた。

2015年に書いたやつは詳細は何も書かずに「どーせ出来る人しか出来ないんだから出来る人だけやればいいでしょ、ここまで書けば出来る人は絶対出来るでしょ」としてたけど、まぁ今回は書いとくことにするよ。

手順:

  1. eccodes のソースをダウンロードして展開。
    • おそらくシンボリックリンクが使われてて、それが理由で持っている tar がダメな場合は、例えば unarchive.py などを使うと良い。
  2. windows/msvc フォルダの grib_api.sln を Visual Studio で開き、toolset 変換をしてもらう。
    • Python 3.5 以前を使っているならともかく、そうでないならおそらくこれは不可避。どーせあなたが持ってる Visual Studio って 2019 でしょ? (これは CPython 3.9 とかのものと一致してる。) 元の grib_api.sln は 2019 用になってない。
  3. src/eccodes_version.h を手作る。src/eccodes_version.h.in から容易に推察して作れる。
  4. ビルド。「Visual Studio にサインイン」してないならコマンドラインから:
    1 [me@host: ~]$ cd eccodes-2.21.0-Source/windows/msvc
    2 [me@host: msvc]$ # ↓MSBuild.exe にパスを通してないなら。
    3 [me@host: msvc]$ export PATH="${PATH}":"/c/Program Files (x86)/Microsoft Visual Studio/2019/Community/MSBuild/Current/Bin/amd64/"
    4 [me@host: msvc]$ 
    5 [me@host: msvc]$ MSBuild.exe -p:Configuration=Release -p:platform=x64 grib_api.sln
    6     .. (今の場合幸いなことに、Static Library を作ってくれる) ..
    
  5. 目的の「grib_api.lib」は「eccodes」という新しいプロジェクトから取り残された命名、だと思われる。リネームとかリンクとかで:
    1 [me@host: msvc]$ ln grib_api_lib/x64/Release/grib_api_lib.lib grib_api_lib/x64/Release/eccodes.lib
    
  6. pygrib ビルドと実行環境の準備:
     1 [me@host: msvc]$ cd ../..
     2 [me@host: eccodes-2.21.0-Source]$ # ワタシは c:/develop の下に置くことにした。ので:
     3 [me@host: eccodes-2.21.0-Source]$ mkdir -p /c/develop/share/eccodes
     4 [me@host: eccodes-2.21.0-Source]$ cp -prfv definitions /c/develop/share/eccodes
     5 [me@host: eccodes-2.21.0-Source]$ cp -prfv samples /c/develop/share/eccodes
     6 [me@host: eccodes-2.21.0-Source]$ export ECCODES_DEFINITION_PATH=c:/develop/share/eccodes/definitions
     7 [me@host: eccodes-2.21.0-Source]$ export ECCODES_SAMPLES_PATH=c:/develop/share/eccodes/samples
     8 [me@host: eccodes-2.21.0-Source]$ 
     9 [me@host: eccodes-2.21.0-Source]$ # 作ったのは Static Library なので、今の作業フォルダそのものを
    10 [me@host: eccodes-2.21.0-Source]$ # 指しちゃって pygrib ビルドしちゃえばいい:
    11 [me@host: eccodes-2.21.0-Source]$ export LIB="`pwd -W`/windows/msvc/grib_api_lib/x64/Release;${LIB}"
    12 [me@host: eccodes-2.21.0-Source]$ export INCLUDE="`pwd -W`/src;${INCLUDE}"
    13 [me@host: eccodes-2.21.0-Source]$ 
    14 [me@host: eccodes-2.21.0-Source]$ # へば
    15 [me@host: eccodes-2.21.0-Source]$ py -3 -m pip install pygrib
    

これで行くはず。

experimental が「Unfortunately we can offer very limited support for this platform.」としていることが本当に不幸なのかということだが、そもそも pygrib が eccodes のフルスペックを使うノリではないんだと思うし、日本の気象庁提供の MSM GPV (とか)を使うだけの場合は、少なくともワタシが知る限りは問題ないと思う。

ひとまず京都大学によるアーカイブから Z__C_RJTD_20210514000000_MSM_GPV_Rjp_L-pall_FH00-15_grib2.bin を持ってきて…:

 1 >>> import pygrib
 2 >>> fn = "Z__C_RJTD_20210514000000_MSM_GPV_Rjp_L-pall_FH00-15_grib2.bin"
 3 >>> src = pygrib.open(fn)
 4 >>> for s in src:
 5 ...     print(s.name, s.validDate)
 6    ... (snip) ...
 7 Geopotential Height 2021-05-14 15:00:00
 8 U component of wind 2021-05-14 15:00:00
 9 V component of wind 2021-05-14 15:00:00
10 Temperature 2021-05-14 15:00:00
11 Vertical velocity 2021-05-14 15:00:00

てな感じ。