1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MIDIスイッチャを作る:(備忘録)mididingsのpython3対応

Last updated at Posted at 2021-03-24

はじめに

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行目あたりを見たら

setup.py

    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

ソース見ると:

mididings/units/call.py
     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_pythonboost_python38に変更
  • mididings/units/call.pyのclass _CallBasedef __init__の変数asyncを全てリネーム

ぐらいで動くっぽい。

python3+mididingsで自前アプリを動かす時には他にも色々細かいところの修正が必要かも。

同じ名前で中身の微妙に違うバイナリ(スクリプト)が/usr/binと/usr/local/binに存在するの気持ち悪いかなーーーー。やっぱpyenvですかね
個人的な感想としてはpython3に対応してるものは、もうどんどんそっちに移行したパッケージにしてほしいですね。
ただmididingsは全然メンテされてない....うーーーん

ちなみになんでmididingsをpython3で動かしたかったかというと
rtmidiと組み合わせてスイッチアプリを組み直したくなったから。
ubuntuのrtmidiパッケージはデフォルトで配布されてるのがpython3バージョンなので
そっちに合わせたってカンジです。

ソースとかいろいろ追いかけたんですけど、rtmidiもmididings、統一されないかなーー
とか思いました。

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?