はじめに
ubuntu studioに普通にapt-getでmididings入れるとpython2.7で動いてしまうので
python3で動くようにしたときのメモ
ソースの取得
どうやらpython3-mididingsとかいうパッケージはなさそうなので、
ソースからビルドして/usr/local/binにつっこむことにした
まずはソースの取得
$ git clone https://github.com/dsacre/mididings.git
mididingsってフォルダがあるのでそこのフォルダで色々作業する
※2021/03/25追記
なんか今アクティブなブランチは以下のものらしいpython3.7対応済みとのこと
https://github.com/marcan/mididings.git
ソースの修正
修正箇所は4ファイル
- setup.py
- scripts/livedings
- scripts/mididings
- scripts/sendmidi
先頭行の#!/usr/bin/env python
を #!/usr/bin/env python3
に書き換え
ビルド&インストール
さぁビルドだ
# ./setup.py build
(中略)
86_64-linux-gnu-g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 -Wl,-Bsymbolic-functions -Wl,-z,relro -g -fwrapv -O2 -g -fstack-protector-strong -Wformat -Werror=format-security -Wdate-time -D_FORTIFY_SOURCE=2 build/temp.linux-x86_64-3.8/src/engine.o build/temp.linux-x86_64-3.8/src/patch.o build/temp.linux-x86_64-3.8/src/python_caller.o build/temp.linux-x86_64-3.8/src/send_midi.o build/temp.linux-x86_64-3.8/src/python_module.o build/temp.linux-x86_64-3.8/src/backend/base.o build/temp.linux-x86_64-3.8/src/backend/alsa.o build/temp.linux-x86_64-3.8/src/backend/jack.o build/temp.linux-x86_64-3.8/src/backend/jack_buffered.o build/temp.linux-x86_64-3.8/src/backend/jack_realtime.o -lboost_python -lboost_thread -lasound -ljack -lglib-2.0 -o build/lib.linux-x86_64-3.8/_mididings.cpython-38-x86_64-linux-gnu.so
/usr/bin/ld: -lboost_python が見つかりません
/usr/bin/ld: -lboost_thread が見つかりません
collect2: error: ld returned 1 exit status
boost_python
とがないよとか怒られる、ふーん。
ぐぐったらlibboost-all-dev
とかいうパッケージががないせいらしいので
# apt-get install libboost-all-dev
してからビルド。
すると boost_thread
は見つかったみたいだけどboost_python
が相変わらずみつからないらしい。
うーんこまった。
ぐぐったらこんなのが
https://askubuntu.com/questions/944035/installing-libboost-python-dev-for-python3-without-installing-python2-7
ubuntuだとlibboost-python1.67
がpython2.x系でlibboost-python1.71
がpython3系らしい。
dpkgでインストールされてるパッケージをみると
$ dpkg -l | grep libboost-python
ii libboost-python-dev 1.71.0.0ubuntu2 amd64 Boost.Python Library development files (default version)
ii libboost-python1.67.0 1.67.0-17ubuntu8 amd64 Boost.Python Library
ii libboost-python1.71-dev 1.71.0-6ubuntu6 amd64 Boost.Python Library development files
ii libboost-python1.71.0 1.71.0-6ubuntu6 amd64 Boost.Python Library
両方入ってるやんけ!!
むしろpython2用のlibboost-python1.67-dev
は入ってない
libboost-pthread
と何がちがうのかなーと思って調べてみたら
$ cd /usr/lib/x86_64-linux/gnu
$ ls -al libboost_python*
-rw-r--r-- 1 root root 276128 4月 1 2020 libboost_python27.so.1.67.0
-rw-r--r-- 1 root root 701312 4月 1 2020 libboost_python38.a
lrwxrwxrwx 1 root root 27 4月 1 2020 libboost_python38.so -> libboost_python38.so.1.71.0
-rw-r--r-- 1 root root 280224 4月 1 2020 libboost_python38.so.1.67.0
-rw-r--r-- 1 root root 259776 4月 1 2020 libboost_python38.so.1.71.0
$
$ ls -al libboost_thread*
-rw-r--r-- 1 root root 485178 4月 1 2020 libboost_thread.a
lrwxrwxrwx 1 root root 25 4月 1 2020 libboost_thread.so -> libboost_thread.so.1.71.0
-rw-r--r-- 1 root root 186536 4月 1 2020 libboost_thread.so.1.67.0
-rw-r--r-- 1 root root 174272 4月 1 2020 libboost_thread.so.1.71.0
あああああ、なるほどね、-lboost_python
じゃなくて-lboost_python38
にしなきゃダメなのね
シンボリックリンク張ってごまかそうかとも思ったけど、影響でかそうかもだったので、mididingsフォルダ直下のsetup.pyを修正しようと思って150行目あたりを見たら
151 boost_python_suffixes = ['-py%d%d' % sys.version_info[:2]]
152 if sys.version_info[0] == 3:
153 boost_python_suffixes.append('3')
154 libraries.append(boost_lib_name('boost_python', boost_python_suffixes))
155 libraries.append(boost_lib_name('boost_thread'))
156
あああああ、python3のときだけなんか変なサフィックスつけてやがる.....
しかもboost_lib_name()
は結局すりぬけてて単純にboost_python
って名前がlibraries
に入ってるっぽい。
よくわからんのでlibraries.append(boost_lib_name('boost_python',boost_python_suffixes))
を
libraries.append(boost_lib_name('boost_python38',boost_python_suffixes))
に変更してビルド
やったーーービルド通ったァァァ、あとはsetup.py install
して終了
動作確認
で、ワクワクしながら起動してみるじゃないですか、そしたら
$ mididings
Traceback (most recent call last):
File "/usr/local/bin/mididings", line 4, in <module>
__import__('pkg_resources').run_script('mididings==2015+rbbec99a', 'mididings')
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 667, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 1463, in run_script
exec(code, namespace, namespace)
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/EGG-INFO/scripts/mididings", line 20, in <module>
import mididings
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/__init__.py", line 14, in <module>
from mididings.setup import config, hook
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/setup.py", line 15, in <module>
import mididings.arguments as _arguments
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/arguments.py", line 13, in <module>
from mididings import misc
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/misc.py", line 21, in <module>
import decorator
ModuleNotFoundError: No module named 'decorator'
なんかdecoratorとかいうモジュールが無いっぽい....またか.
とりあえずapt-get install python3-decorator
してから起動してみると
$ mididings
Traceback (most recent call last):
File "/usr/local/bin/mididings", line 4, in <module>
__import__('pkg_resources').run_script('mididings==2015+rbbec99a', 'mididings')
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 667, in run_script
self.require(requires)[0].run_script(script_name, ns)
File "/usr/lib/python3/dist-packages/pkg_resources/__init__.py", line 1463, in run_script
exec(code, namespace, namespace)
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/EGG-INFO/scripts/mididings", line 20, in <module>
import mididings
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/__init__.py", line 15, in <module>
from mididings.engine import run, process_file
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/engine.py", line 15, in <module>
import mididings.patch as _patch
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/patch.py", line 15, in <module>
import mididings.units as _units
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/units/__init__.py", line 19, in <module>
from mididings.units.call import *
File "/usr/local/lib/python3.8/dist-packages/mididings-2015+rbbec99a-py3.8-linux-x86_64.egg/mididings/units/call.py", line 36
def __init__(self, function, async, cont):
^
SyntaxError: invalid syntax
ソース見ると:
35 class _CallBase(_Unit):
36 def __init__(self, function, async, cont): ### ←これ!!
37 def do_call(ev):
38 # add additional properties that don't exist on the C++ side
39 ev.__class__ = _event.MidiEvent
40
41 # call the function
42 ret = function(ev)
あああああああ、python3.6あたりで予約語になったasyncってキーワードが変数として使われてるぅぅぅ!!!
asyncって変数名をテキトーに変更して再度ビルド&インストール
ふぅ、やっとおわった
おわりに
まとめると
- パッケージとして
libboost-all-dev
,python3-decorator
は入れとけ - スクリプトの先頭に
#!/usr/bin/env python
になってるやつは#!/usr/bin/env python3
になおしとけ - setup.pyの
libraries_append
してるところのboost_python
はboost_python38
に変更 - mididings/units/call.pyの
class _CallBase
のdef __init__
の変数async
を全てリネーム
ぐらいで動くっぽい。
python3+mididingsで自前アプリを動かす時には他にも色々細かいところの修正が必要かも。
同じ名前で中身の微妙に違うバイナリ(スクリプト)が/usr/binと/usr/local/binに存在するの気持ち悪いかなーーーー。やっぱpyenvですかね
個人的な感想としてはpython3に対応してるものは、もうどんどんそっちに移行したパッケージにしてほしいですね。
ただmididingsは全然メンテされてない....うーーーん
ちなみになんでmididingsをpython3で動かしたかったかというと
rtmidiと組み合わせてスイッチアプリを組み直したくなったから。
ubuntuのrtmidiパッケージはデフォルトで配布されてるのがpython3バージョンなので
そっちに合わせたってカンジです。
ソースとかいろいろ追いかけたんですけど、rtmidiもmididings、統一されないかなーー
とか思いました。