Vcpkg

Vcpkg は、Visual C++ でオープンソースのライブラリをパッケージとして簡単に管理できるツールとして Microsoft がさいきん公開したツール。GitHub で公開されている。

有名どころのライブラリはほとんどがすでにポートとして網羅されていて、boost、curl、gettext、gtk などを vcpkg コマンドを使って VC++ で使うためにビルドできる。個人的に気になるのは freetype, icu, opencv, openssl, python3, wxwidgets あたりかな。これまで NuGet にもあった WTL はこっちにもある。

オープンソースのライブラリはメインターゲットがほとんど Linux なので Windows で使おうとすると README 読んで自分でがんばるしかないという状況だったので、MS 謹製でこういうものを用意してくれるとありがたい。Visual Studio でこれらを扱う標準的なやりかたが出たのも大きい。

たとえば、ひみつメモ帳は OpenSSL と(現在公開しているバージョンでは)wxWidgets を使っているのだけど、それぞれ自力でビルドしてプロジェクトの設定にマニュアルでパスを追加している。これが、コマンドラインで vcpkg install openssl wxwidgets とだけ叩けば、プロジェクトのソースで #include <openssl/crypto.h> といきなり書けるようになる。ビルドの設定じゃなくてコードに集中できてよい。

気になるのは、OSS のライブラリに交じって、ATL とか MFC とかのポートが含まれているところ。あんまり使う機会はなさそうだけど、やるとどうなるのだろう。

Visual Studio 向けのインストーラープロジェクト

これまた以前に書いた、Visual Studio で MSI 形式のインストーラを作れなくなったという話の続き。

その後、Visual Studio の拡張機能として Microsoft から「Microsoft Visual Studio 2017 Installer Projects」がリリースされた。Visual Studio のツールメニューからインストールできる。リンク先は VS 2017 用だけど、2015 用もある。

まだちゃんと試してないけど、とりあえず障壁は除かれた。

pip 非対応のモジュールを virtualenv で使うには(Windows 編)

プロジェクトごとに独立した Python インストール環境を作れる virtualenv は便利なのだけど、pip でのインストールに対応していないモジュールを使いたいとなるととたんに難しいことになる。Windows では標準で拡張モジュールをビルドできないこともあってインストーラーの配布形式(bdist_wininst)が長い間使われてきたので、古いパッケージだと pip でインストールできる wheel 形式での配布がなされていないものが多い。wxPython とか py2exe とかである。

しかし、一旦インストーラーでシステムの Python にインストールしたうえで、それらを virtualenv 環境のライブラリのディレクトリにリダイレクトしてやれば、virtualenv 環境からでもインポートできるようになる。リダイレクトといっても、ようは site-packages にハードリンクやジャンクションを張るだけだけど。

たとえば wxPython の場合、通常どおりインストーラーで導入してシステムの Python から使ってみると、

C:\Users\mshibata>python
Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win 32
Type "help", "copyright", "credits" or "license" for more information.
>>> import wx
>>> wx.__file__
'C:\\Python27\\lib\\site-packages\\wx-3.0-msw\\wx\\__init__.pyc'
>>>

パッケージが C:\Python27\lib\site-packages\wx-3.0-msw\wx にあるということがわかる。そこで、virtualenv 環境があるディレクトリで、

C:\Users\mshibata\work>virtualenv venv
New python executable in venv\Scripts\python.exe
Installing setuptools, pip...done.
C:\Users\mshibata\work>mklink /j venv\Lib\site-packages\wx C:\Python27\lib\site-packages\wx-3.0-msw\wx
venv\Lib\site-packages\wx <<===>> C:\Python27\lib\site-packages\wx-3.0-msw\wx のジャンクションが作成されました

とすれば、

C:\Users\mshibata\work>venv\Scripts\activate.bat
(venv) C:\Users\mshibata\work>python
Python 2.7.9 (default, Dec 10 2014, 12:24:55) [MSC v.1500 32 bit (Intel)] on win 32
Type "help", "copyright", "credits" or "license" for more information.
>>> import wx
>>>

とこのようにインポートできる。パッケージではなく単体のモジュールの場合は、ジャンクションではなくモジュールの .py ファイルへのハードリンクを張ればよい(けど、そういうのはふつうに virtualenv 環境にインストールできるか)。

py2exe もこの方法で virtualenv 環境で使えるようにすることができる。しかしこれだと py2exe がさらに読みこんでいる別のモジュールまではリダイレクトされていないので、ImportError が発生することがある。その場合は適宜足りてないモジュールへのリンクを張ればよい(いいかげんだ)。

最初だけなので手作業でやってもいいのだけれど、いちいちインポートされてるモジュールのパスを調べてコピペするのは面倒なので、上記の作業をやってくれるスクリプトを作ってみた。

C:\Users\mshibata\work>redirect-package.py venv wx py2exe
venv\Lib\site-packages\wx <<===>> C:\Python27\lib\site-packages\wx-3.0-msw\wx のジャンクションが作成されました
venv\Lib\site-packages\py2exe <<===>> C:\Python27\lib\site-packages\py2exe のジャンクションが作成されました

と、こんなふうに使う。