6
2

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.

colcon について調べた

Posted at

諸事情 により ROS/ROS2 で使われているメタビルドシステムである colcon について調べていた。あまりドキュメントがなくなかなか苦戦していたのだが、折角なのでその時まとめていたメモを公開します。

ちなみに https://github.com/nonanonno/colcon_d を作ってました。(修正しなきゃ

Q. 誰向けの記事?
A. colcon を開発したい皆さん

とは言え、Getting Started 的なものではない。colcon の概要は把握したが結局何ができるのかを調べたい、あるいは、なんとなく colcon の拡張機能を作る準備はできた(↓のツイートみたいに)が、どこを開発したら良さそうなのかわからないといった時に参考にできるかもしれない。私自身が開発していて気になった部分をコードを見ながら(コードを見るしかないのである!)解析していたメモが含まれている。力尽きている箇所があったりするがそこはご了承願いたい。

では、本編。

colcon

以降では D言語向けビルドツール権パッケージ管理ツールである DuB 向けの拡張を開発するものとします。

概要

複数のパッケージ間の依存関係を解決しつつ各パッケージのビルドやテストを行うメタビルドシステム。やるのは依存関係解決とビルドやテストなどのキックまでで、実際にビルドを行うのは CMake など、各パッケージに対応するツールになる。

colcon は Python(>=3.5)で作られており、拡張可能である。拡張ポイントは以下の通り。

Point Who use Description
Verb colcon colcon <verb> を作成
PackageDiscovery Verb package を探すルール(デフォルト./ とか?)
PackageIdentification Discovery package の種類を解釈(cmake とか ament_cmake とか)
PackageAugmentation package 識別した後の Verb 任意の情報を package descriptor に追加(追加の依存先など)
PackageSelection package 識別し追加情報を与えた後の Verb --packages-select とかのあれ
Task package識別し追加情報を与えた後のVerb verb と package type の組み合わせに対応する処理を定義(build と cmake など)
Executor some verb extensions --parallel-workers とかのあれ
Shell some task extensions bash や zsh など、それぞれ向けの環境変数設定スクリプトを作るためのもの
Environment some task extensions environment や environment hook を作るもの?
EventHandler --event-handlers とかのあれ
AugmentParser undocumented
PrefixPath undocumented

ここのフォルダがそれぞれの拡張ポイントに対応していそう。
また、インストールされている拡張は colcon extensions で確認することができる。

詳細

新たなビルドツール向けの拡張を作る際に必要になりそうな拡張ポイントについて少し詳細に書いている。

Verb

colcon <verb> を作成するための拡張ポイント。colcon-core では buildtest最初から定義されている。

PackageDiscovery

パッケージを探す場所に関するルール。colcon buildcolcon test など、各 Verb によって使用される。colcon build --help で見つけることができる Discovery arguments セクションのオプションを提供する。探索位置を指定するオプションを提供したり、ディレクトリを再帰的に探す機能の提供を行っている。

PackageIdentification

概要

パッケージの種類を解釈するための拡張ポイント。PackageDiscovery によって得られたディレクトリが何らかのパッケージであるか、それが何の種類なのかを解釈する。setup.pysetup.cfg が Python, CMakeLists.txt があれば cmake プロジェクト、など。

使い方

colcon_core.package_identification.PackageIdentificationExtensionPoint を継承し、identify を override する。

from colcon_core.package_identification import PackageIdentificationExtensionPoint

class DubPackageIdentificationExtensionPoint(PackageIdentificationExtensionPoint):
    PRIORITY = 100

    def identify(self,desc: PackageDescriptor) -> None:
        ...
  • PRIORITY : 識別のための優先度

    • 数字が高い程優先度が高い
    • 複数の PackageIdentification にマッチした時にどれを選択するかをする
      • CMakeLists.txtpackage.xml がある時、cmake 向けではなく ros 向けを優先する、といった
    • 同じ優先度で複数の PackageIdentification がマッチしたら警告とともにそのパッケージは無視される
  • identify : 識別処理を行う

    • desc: PackageDescriptor が渡される
      • フィールド
        • path : パッケージパス
        • type : パッケージの種類 (cmake とか ros.ament_cmake とか)
        • name : パッケージ名
        • dependencies : defaultdict(set)
        • hooks : Each item in 'hooks' must be a relative path in the installation space.
        • matadata : any additional information
      • パッケージのユニーク性は pathtypename の triplet で表現される
        • path は、文字列として違っていても同じ絶対パスを指していれば同じと見なす
        • identify 関数でこの3つに値を入れれば、識別した、と解釈される
        • path には最初から値が入っている
      • dependencies は依存パッケージのリストではない。DependencyDescriptor あるいは文字列で表現されるカテゴリをキーとして、その値として依存パッケージのリストが入っている
      • hooks の PackageIdentification での使い方はよくわからなかった
      • matadata は好きに使えば良いと思う。colcon_ros では versionget_python_setup_options を設定している。

他の PackageIdentificationidentify を呼ぶ、といった使い方も可能ではある。例えば、colcon_ros のを使うと package.xml を解釈した。 PackageDescriptor が得られるなど。(_get_package を呼べば良い気もする)

PackageArgumentation

PackageDiscovery でフォルダを得て、PackageIdentification で何のパッケージであるかを、例えばPython と解釈し、その後 Python パッケージ向けに追加の依存を設定する、といったのがこの拡張ポイントの役割。

Python では PackageDescriptor に対して metadata['version'] の設定と、setup.cfg に書かれている依存パッケージをdependencies['setup_requires|install_requires|test_requires'] に設定するのをやっている。

あるいは、package_information ではパッケージ同士のバージョン整合性の確認に利用しているようだ。

パッケージを識別した後、依存関係を計算してそれぞれ処理する前に何かをやりたい時に利用する、といったところか。

PackageSelection

--packages-select などを提供するための拡張ポイント。タイミングは PackageAugmentation の後。

Task

verbpackage type の組み合わせで処理を行うためのポイント、verb の部分については、ここを見る限り setup.cfg で設定することになっている。例えば以下のようなセクションを書く。

[options.entry_points]
colcon_core.task.build =
    dub = colcon_dub.task.dub.build:DubBuildTask

使い方

colcon_core.task.TaskExtensionPoint を継承する。

  • add_arguments(self, *, parser: ArgumentParser) : コマンドライン引数を追加する。必要なら override

  • <verb> : タスク名のメンバ関数を定義する(getattr(self, self.TASK_NAME) が呼ばれる)

    • 引数は、(self, *, hoge=None, fuga=0) といった形でデフォルト値付きで設定する。
    • verb 自体は引数なしで呼び出すが、他の拡張のタスクを呼ぶ時に伝搬してもらう必要があるものを引数として定義する
    • async である必要あり
  • 情報には self.context 経由でアクセスする

    • フィールド
      • pkg : PackageDescriptor
      • args : <verb? 毎に違うらしい build の場合、 BuildPackageArguments
      • dependencies : 再帰的に解決されたタスクに必要最終的な依存パッケージ
  • 何をやる必要があるのかは、<verb> 次第(次節)

Task.build

colcon build で実行されるタスクを定義する。TaskExtensionPoint を継承し、build 関数を定義する。

  • self.context.dependencies には自身が直接依存しているパッケージ + run カテゴリの依存パッケージが再帰的に入っている
  • インストールまで実装する必要がある
  • 必要に応じて create_environment_script を呼ぶ
    • 自身に依存する別パッケージをビルドする際に必要となる環境変数(例えば、CMAKE_PREFIX_PATH)を設定するためのスクリプトを作るため

Task.test

colcon test で実行されるタスクを定義する。TaskExtensionPoint を継承し、test を定義する。

  • self.context.dependencies には build のと同様のに加えて自分自身も入っている。
    • テストコードをビルドするのに自分自身が必要だからか

Executor

Job 実行の仕組みを提供しているはず。--parallel-workers--executor を提供しているあれ。

Shell

bash や zsh など、各shell 向けの shell script や hook を作るための拡張ポイント。必要な機能を持つ(例えば setup.bash といった)スクリプトを作るためのルールを作る。

Environment

environment hook を定義する。実際の environment hooks script は shell extension を使って作られる。

これはビルドタイプとは関係ない。build タスクなどが create_environment_scripts を呼んだ時に全ての Environment 拡張が実行される。

使い方

colcon_core.environment.EnvironmentExtensionPoint を継承し、create_environment_hooks(self, prefix_path, pkg_name) -> OrderedDict を override する。

create_environment_hooks 内で必要に応じて必要な環境変数を設定する。

EventHandler

--event-handlers のあれ。

6
2
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
6
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?