やったこと
最近FlatCAMというオープンソース基板CAM(ガーバーデータを読んでGコードとかを出力してくれるやつ)ソフト用の野良Homebrew Formulaを作りました。
https://github.com/tomoyanonymous/homebrew-flatcam
というのも、LinuxとWindowsにはビルドされたバイナリがあるのにMacには無く、自力で依存パッケージをbrew
でインストールして、Python依存パッケージはpip
でインストールして自力で立ち上げてね、とのことだったので、流石にちょっとめんどくさいな…と思ったからです。
しかもFlatCAMは現在まだGUIに使っているのPyqtのバージョンが4と一つ古いバージョンで、公式のHomebrewではすでに提供されていません。こういうものは本家リポジトリにFormula
リクエストしても承認されないので野良リポジトリとして作るのが懸命です。
参考にしたもの
インストールステップ自体は概ねこの手順に従いました。
Installing FlatCam on macOS Sierra
https://wolfgang.reutz.at/2017/04/25/installing-flatcam-on-macos-sierra/
あとFormula作る時は本家のFormula Cookbookを穴が空くほど読みましょう。野良リポジトリにしても有用な話がたくさんあります。
それから今回の本題であるPythonアプリに関してのTipsはここに情報がまとまっています。
手順
まずformulaのファイルを作りましょう。
brew create flatcam
こうすると/usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/flatcam.rb
というファイルが出来上がると思います。後で移動しますがこの場所で作業していたほうが楽なのでとりあえずここに置いて直接編集します。ある程度雛形は作ってくれているので、必要なところを埋めていきます。
基本情報
class Flatcam < Formula
version "8.5.0"
desc "FlatCAM: 2D Computer-Aided PCB Manufacturing"
homepage "http://flatcam.org/"
このあたりの基本情報は野良リポジトリならシビアになる必要はないですが何も入れないと警告が出たりするので(特にバージョン名はフォルダ名につながるので)入れましょう。
本体のURL
url "https://bitbucket.org/jpcgt/flatcam.git"
これはビルドされたバイナリが配布されていたりすればその.tar.gzファイルと、そのSHA256キーを書く事が推奨されますが、特にない場合はGitリポジトリのURLそのまんまでも大丈夫です。ブランチは標準でmasterですが、特定のブランチやタグ、コミットハッシュを指定することも出来ます1。
Homebrew依存パッケージ
depends_on "python" => "with-tcl-tk"
depends_on "cartr/qt4/qt@4"
depends_on "cartr/qt4/pyqt@4"
depends_on "cartr/qt4/pyside"
depends_on "geos"
depends_on "spatialindex"
#for matplotlib
depends_on "pkg-config"
depends_on "freetype"
#for scipy(fortran compiler)
depends_on "gcc"
ここからが本題。tapしなければいけない非公式リポジトリは例えば、
brew tap cartr/qt4 # Github上のユーザーcartrのhomebrew-qt4というリポジトリを指定
brew install qt@4
というものは depends_on cartr/qt4/qt@4
として書いておけばいいです。バージョン古いぞとwarningは出ますがそういう目的なので仕方ない。
geosとspatialindexは普通に最新版でいいのでそのようにしています。あと参考記事では書いてなくて引っかかりましたが、python上でmatplotlibを動かすためにはpkg-configとfreetypeが、scipyを動かすためにはgfortranが、つまりそれが入っているgccが(何かのfftライブラリが依存してるらしいです…)必要なので書いておきます。
仮にHomebrewで自分のマシンにgccとかがインストール済みになっていても、明示的に依存を指定しておかないとパスが通りません。余談ながらgccはビルドに1時間ぐらいかかるので初回インストールでは罠になります。
HomebrewにおけるPythonのバージョン達
本題中の本題です。
まず前提として、Homebrewを使っている人のMac上には大体3種類のPythonがインストールされていると思ってください。これらはごっちゃにならないようにそれぞれのコマンド名が分けられています。パッケージマネージャpipも同様に、それぞれインストールされるパッケージのフォルダも異なります。
インストール元 | 系列 | コマンド名 | pipコマンド | pipインストールディレクトリ |
---|---|---|---|---|
システム標準 | 2.7 | python |
(標準では付属せず) |
|
Homebrew python
|
2.7 | python2 |
pip/pip2 |
/usr/local/lib/python2.7/site-packages |
Homebrew python3
|
3.x | python3 |
pip3 |
/usr/local/lib/python3.x/site-packages |
pyenvやvirtualenvを使っている人は更にこれに加えて幾つかのバージョンがインストールされていたり、エイリアスが変更されていたりします。ここは突っ込み始めると泥沼なのでノータッチです。
HomebrewでPythonアプリを扱う場合、特別なことがなければシステムのpythonを使うようにやってくれるのですが、今回のアプリではtcl-tkのインタプリタが入っていないとダメで、Homebrewの2.7に--with-tcl-tkオプションを付けてインストールすることになります。
というわけでdepends_on "python" => "with-tcl-tk"
という物を書いておく必要があります。
Homebrewでpipパッケージの管理
さてFlatCAMが依存していたpipでインストールすべきパッケージは以下です。
numpy matplotlib rtree scipy shapely simplejson svg.path
例えばここでインストールスクリプトにpip install <packages>
と直打ちしてしまうのも一つの手ですが、HomebrewではHomebrew以外の何かをDLするツールを使用しない事が原則となっています。それに、Homebrewでインストールしていたら知らない間に/usr/local/lib/python2.7/site-packages
の中に知らないライブラリが山のように溜まっている…という状況も嫌なものです。
そこでHomebrewではvirtualenv
を用いてpython
/python2
/python3
のどれかをベースにしたPythonの仮想実行環境を作り、パッケージはその仮想環境内にそれぞれインストールする形を取っています。
/usr/local/Cellar/flatcam/8.5.0/libexec/lib
内にPythonの仮想環境のが構築され、画像のような感じでsite-packagesが作られ、その中にpipでインストールしたものが入るというわけです。
homebrew-pypi-poetを使ってpipパッケージをURLに
では具体的にpipコマンドを使わずにこのフォルダにパッケージをDLするために、pipがインストールする時に取ってくるpypi
のリポジトリから.tar.xzファイルとそのSHA256ハッシュを拾い集めなければなりません。それを手動で…?と思ったらhomebrew-pypi-poet
という便利スクリプトがあるようです。使い方を説明したほうが速いと思うのでそうすると、
# virtualenvwrapperという仮想環境作成ユーティリティを入れる(これだけはグローバルで入れてしまって下さい)
brew install python
python -m pip install virtualenvwrapper #システムのpythonからpython2のpipを呼び出している
source $(brew --prefix)/bin/virtualenvwrapper.sh
# 一時的な仮想環境を作ります
mkdir ~/hoge && cd ~/hoge
mktmpenv
# homebrew-pypi-poetと、Formulaに必要なpackage達を一時的にインストール
pip install homebrew-pypi-poet numpy matplotlib rtree scipy shapely simplejson svg.path
# poetコマンドでFormulaに必要な文言を出力(2個以上のパッケージに依存する場合は-aと共に列挙します)
poet numpy -a matplotlib -a rtree -a scipy -a shapely -a simplejson -a svg.path
# 全部終わったら一時的な仮想環境を消去
deactivate
cd ~ && rm -rf ~/hoge
poetコマンドを実行した結果こんな文が帰ってきます。
resource "backports.functools_lru_cache" do
url "https://files.pythonhosted.org/packages/57/d4/156eb5fbb08d2e85ab0a632e2bebdad355798dece07d4752f66a8d02d1ea/backports.functools_lru_cache-1.5.tar.gz"
sha256 "9d98697f088eb1b0fa451391f91afb5e3ebde16bbdb272819fd091151fda4f1a"
end
resource "Cycler" do
url "https://files.pythonhosted.org/packages/c2/4b/137dea450d6e1e3d474e1d873cd1d4f7d3beed7e0dc973b06e8e10d32488/cycler-0.10.0.tar.gz"
sha256 "cd7b2d1018258d7247a71425e9f26463dfb444d411c39569972f4ce586b0c9d8"
end
resource "matplotlib" do
url "https://files.pythonhosted.org/packages/6d/bd/3e8cec37bcf71cfd81fe798cf733c046b1ceb123e7dddf6d3435cf03b506/matplotlib-2.1.2.tar.gz"
sha256 "725a3f12739d133adfa381e1b33bd70c6f64db453bfc536e148824816e568894"
end
resource "numpy" do
url "https://files.pythonhosted.org/packages/ee/66/7c2690141c520db08b6a6f852fa768f421b0b50683b7bbcd88ef51f33170/numpy-1.14.0.zip"
sha256 "3de643935b212307b420248018323a44ec51987a336d1d747c1322afc3c099fb"
end
resource "pyparsing" do
url "https://files.pythonhosted.org/packages/3c/ec/a94f8cf7274ea60b5413df054f82a8980523efd712ec55a59e7c3357cf7c/pyparsing-2.2.0.tar.gz"
sha256 "0832bcf47acd283788593e7a0f542407bd9550a55a8a8435214a1960e04bcb04"
end
resource "python-dateutil" do
url "https://files.pythonhosted.org/packages/54/bb/f1db86504f7a49e1d9b9301531181b00a1c7325dc85a29160ee3eaa73a54/python-dateutil-2.6.1.tar.gz"
sha256 "891c38b2a02f5bb1be3e4793866c8df49c7d19baabf9c1bad62547e0b4866aca"
end
resource "pytz" do
url "https://files.pythonhosted.org/packages/60/88/d3152c234da4b2a1f7a989f89609ea488225eaea015bc16fbde2b3fdfefa/pytz-2017.3.zip"
sha256 "fae4cffc040921b8a2d60c6cf0b5d662c1190fe54d718271db4eb17d44a185b7"
end
resource "Rtree" do
url "https://files.pythonhosted.org/packages/b0/6c/6cc8d738f14d5efa0c38ec29403bbd9c75e64b3fe84b53290178dda0dbd9/Rtree-0.8.3.tar.gz"
sha256 "6cb9cf3000963ea6a3db777a597baee2bc55c4fc891e4f1967f262cc96148649"
end
resource "scipy" do
url "https://files.pythonhosted.org/packages/d0/73/76fc6ea21818eed0de8dd38e1e9586725578864169a2b31acdeffb9131c8/scipy-1.0.0.tar.gz"
sha256 "87ea1f11a0e9ec08c264dc64551d501fa307289460705f6fccd84cbfc7926d10"
end
resource "Shapely" do
url "https://files.pythonhosted.org/packages/7d/3c/0f09841db07aabf9cc387662be646f181d07ed196e6f60ce8be5f4a8f0bd/Shapely-1.6.4.post1.tar.gz"
sha256 "30df7572d311514802df8dc0e229d1660bc4cbdcf027a8281e79c5fc2fcf02f2"
end
resource "simplejson" do
url "https://files.pythonhosted.org/packages/0d/3f/3a16847fe5c010110a8f54dd8fe7b091b4e22922def374fe1cce9c1cb7e9/simplejson-3.13.2.tar.gz"
sha256 "4c4ecf20e054716cc1e5a81cadc44d3f4027108d8dd0861d8b1e3bd7a32d4f0a"
end
resource "six" do
url "https://files.pythonhosted.org/packages/16/d8/bc6316cf98419719bd59c91742194c111b6f2e85abac88e496adefaf7afe/six-1.11.0.tar.gz"
sha256 "70e8a77beed4562e7f14fe23a786b54f6296e34344c23bc42f07b15018ff98e9"
end
resource "subprocess32" do
url "https://files.pythonhosted.org/packages/b8/2f/49e53b0d0e94611a2dc624a1ad24d41b6d94d0f1b0a078443407ea2214c2/subprocess32-3.2.7.tar.gz"
sha256 "1e450a4a4c53bf197ad6402c564b9f7a53539385918ef8f12bdf430a61036590"
end
resource "svg.path" do
url "https://files.pythonhosted.org/packages/1d/6c/cf484a95b895a7acd3989082501c67c8f43b6f91181f2a0b7aa634d1df6f/svg.path-2.2.tar.gz"
sha256 "bc7b75606e76f910bf0045d09a5f8415aaafff3cedd0a3ce9f0d474fe2007722"
end
この文章をdepends_on
の後に続けて書いておけば良いだけです。後はインストールステップで
include Language::Python::Virtualenv #実際にはclass先頭に書いてます
def install
virtualenv_install_with_resources
end
とやるとHomebrewがよしなにやってくれます。このvirtualenv_install_with_resources
は
venv = virtualenv_create(libexec)
venv.pip_install resources
venv.pip_install_and_link buildpath
のエイリアスになっていて、例えば今回はFlatCAM自体がsetup.pyというファイルを持っているのでpipがそれに従ってリソースファイルの移動などをやってくれるのですが、./configureやmakeなどをしなければいけない場合はよくあるhomebrew formulaのようにsystem "make", "arg1"
やbin.install("file1")
などと組み合わせていく必要があります。
テストと公開
実際にインストール出来るかテストするのに便利なコマンド達を紹介しておきます。
brew info flatcam
brew install --debug flatcam
brew install --interactive flatcam
brew audit --strict flatcam
まずシンタックスエラーがあればbrew info
の時点でエラーが出ます。幾つかWarningもここで出してくれます。brew install --debug
はインストール中の情報を全部表示してくれたり、エラーで止まった時にシェルに入れたりします。brew install --interactive
は必要なリソースをDLし展開終わったところでtmpフォルダに移動してシェルに入れます(その後は全部手動です)。brew audit
はFormulaのフォーマットとしておかしいところがないかチェックしてくれます。--strictは公式リポジトリにプルリクする時は付けたほうがいいですが野良リポジトリならそこまで気にする必要ない部分まできっちりチェックしてくれます。
で、大丈夫だったら元々flatcam.rbが作られた場所はhomebrew-coreという公式のGitリポジトリそのものなのでこれを置いているとbrew updateなどに支障がでます。適当にフォルダを作って逃がしてやりましょう。
mkdir ~/homebrew-flatcam #適当です
mv /usr/local/Homebrew/Library/Taps/homebrew/homebrew-core/Formula/flatcam.rb ~/homebrew-flatcam
出来上がったらGithub上にhomebrew-xxというリポジトリ名で公開しておきましょう。
brew tap username/xx
でtapしてインストールできるようになります。
希望
Formulaの中にpip install hogehoge
って書いたらサーバサイドとかでhomebrew-pypi-poetが自動で全部解決して欲しい…
-
今回は最終リリース版の
8p5
というブランチがあったのですが、setup.py
がそれ以降に整備されていたようなのでheadバージョンを使っています。ブランチ指定は本来はいつ変更があるかわからないのでコミット指定の方がいいとは思います…。 ↩