Overview
-
cakin_make install
時に,pythonモジュールのデータファイルを,ディレクトリ構成を変えずにインストールする
前置き
ROSにおいて,pythonモジュールは,以下のようなディレクトリ構成をとることが推奨されています( http://wiki.ros.org/ja/PyStyleGuide ).
catkin_ws/
|- <package_name>
|- ~~~
|- setup.py
|- src/
|- <package_name>/
|- __init__.py
|- a.py
このモジュールが参照する,データファイルdata/b.txt
を,cakin_make install
時にも,適切にインストールされることを目標とします.
catkin_ws/
|- <package_name>
|- ~~~
|- setup.py
|- src/
|- <package_name>/
|- __init__.py
|- a.py
|- data/
|- b.txt
ディレクトリ構成
src
catkin_ws/
|- <package_name>
|- ~~~
|- setup.py
|- src/
|- <package_name>/
|- __init__.py
|- a.py
|- data/
|- b.txt
dst (catkin_make install
を実行)
catkin_ws/install/lib/python2.7/dist-packages/
|- <package_name>/
|- __init__.py
|- a.py
|- data/
|- b.txt
方法
setup.py
を編集します.
一般に,モジュールのインストールは,CMakeLists.txt
ではなく,setup.py
で行われます.
setup.py
を,次のように編集します.
setup.py
import os
from distutils.core import setup
from catkin_pkg.python_setup import generate_distutils_setup
__pkgname__ = 'package_name'
def package_datas(dir_list):
prefix_path = os.path.join('src', __pkgname__)
data_files = []
for directory in dir_list:
# Recursive-Search files
start_point = os.path.join(prefix_path, directory)
for root, dirs, files in os.walk(start_point):
for file_name in files:
# Append file path that is removed prefix path (e.g. 'src/pkgname/aaa.txt' -> 'aaa.txt')
data_files.append(os.path.join(root, file_name)[len(prefix_path)+1:])
return data_files
setup_args = generate_distutils_setup(
packages=[__pkgname__],
package_dir={'': 'src'},
package_data={__pkgname__: package_datas(['data'])}
)
setup(**setup_args)
データファイルをインストールするには,インストールしたいファイルのリストを,package_data
オプションに追加します.
package_datas()
メソッドは,引数に渡されたディレクトリのリストを探索範囲とし,サブディレクトリを含む全てのファイルのリストを返します.
ここで注意しないといけない点は, ファイルのパスです.
ファイルのパスは,src/package_name/
からの相対パスでなければなりません.
今回のケースであれば,package_data{'package_name': ['data/b.txt']}
となります(package_data{'package_name': ['src/package_name/data/b.txt']}
ではありません).