文書の過去の版を表示しています。
PyprojとPyinstallerの共存
2020/03 pyprojを使ったプロジェクトを、pyinstallerで.exe化したが、なんかエラー出て上手くいかない。
調べると、結構あるあるらしい。
pyprojは、EPSGコードなどを使って測地系を指定できるが、それはPROJ4モジュールのバックデータに依存している。 その場所が特定できないということらしい。
- Windows 10
- Python 3.7
- pyproj 2.4.1
- pyinstaller 3.6
datadirモジュールの指定
バックデータの場所を特定するにはpyproj.datadirモジュールを裏で読むのだが、これが明示的にはimportされていない(?)ため、pyinstallerが捕捉できない。
これを捕捉されるようにするには、主に2通りあって、
- スクリプト内のどこか(冒頭がよい)で、
from pyproj import _datadir, datadir
で明示的に読み込む - pyinstallerで初回コンパイルすると.pyと同階層に作成される hogehoge.spec を編集
Analysis()
に渡す引数のhiddenimports=[]
を、['pyproj._datadir', 'pyproj.datadir']
にする
これで、pyinstallerがdatadirを見れるようになる。
これだけで、「従来Pythonが動いていた環境なら」exeも動く。
環境変数 PROJ_LIBの指定
別環境に持っていくには、もう1つ作業が必要となる。
pyproj.datadirは以下のようなコードなのだが、要はこれ自体が“datadir”なわけではなく、datadirがありそうな場所を探すスクリプトである。
pythonも何もインストールしていない環境では、だいたい全て見つからないでエラーとなる。
Valid PROJ data directory not found. Either set the path using the environmental variable PROJ_LIB or with `pyproj.datadir.set_data_dir`.
候補の1つに環境変数「PROJ_LIB」を参照しようとしている箇所があるので、これを使えばいけそう。
1ファイルにならないのが何とも残念だが、(そしてpyinstallerの設定によって1ファイルに収めることが可能なのかも知れないが) ひとまず、
- pyprojをインストールした環境からdatadirの実データを探して、exe(の出力予定フォルダ)にコピーする
- pythonコード内で、そのディレクトリに対して「PROJ_LIB」という名で環境変数を定義する
とすれば、動くようにはなる。
if 'PROJ_LIB' not in os.environ: proj_dir = './proj' # 実データを置いた位置によって任意に変更 os.environ['PROJ_LIB'] = proj_dir