MoriKen's Journal

MoriKen's Journal

アラサー社会人博士による徒然日記。技術についてつらつら。だけだとコンテンツが貧弱なので、会社公認で大学院博士課程に進学した経緯や、独学でTOEICを475→910にしたノウハウを共有します。

GitLab CI を使って GitHub の Private Repository を無料で CI ③SSH 編

はじめに

さて、前回まででミラーリングの設定が完了しました。

www.moriken254.com

ここからは、SSH の設定に入っていきます。外部の Private Repository に依存している場合には、SSH 認証によってクローンするしか術がないからです。

f:id:MoriKen254:20190601192608p:plain


GitLab CI はそんなこともあろうかと言わんばかりに、WEBシステムから環境変数を設定できるような仕様になっています。(さもないと、.gitlab-ci.ymlに秘密鍵を直書きしなければならなくなり、いくらPrivateリポジトリとは言え、さすがにそれは品位を欠くわけでして汗。)

てなわけで、その辺の設定方法を含めて、ノウハウを共有します。

今回は、GitLab CI 側から、GitHub の Private Repository をクローンするという構成を取ります。

よって、GitLab CI に秘密鍵を、GitHub の Private Repository に公開鍵を渡すように設定を行っていきます。

SSH 鍵ペアの作成

まずは、秘密鍵と公開鍵のペアを作成します。

f:id:MoriKen254:20190601225508p:plain


GitLab の公式ドキュメントを参照します。

docs.gitlab.com

ローカルで以下のコマンドを実行します。当方ではRSAでの実績があります。

メアドはなくてもいけるみたいですが、公式に従って入れておきます。GitHubに登録しているメールアドレスを入力します。

パスフレーズは無しで。

$ ssh-keygen -o -t rsa -b 4096 -C "email@example.com"
Generating public/private rsa key pair.
Enter file in which to save the key (/home/karuma/.ssh/id_rsa): ← Enter
Created directory '/home/yourname/.ssh'.
Enter passphrase (empty for no passphrase): ← Enter
Enter same passphrase again: ← Enter
Your identification has been saved in /home/yourname/.ssh/id_rsa.
Your public key has been saved in /home/yourname/.ssh/id_rsa.pub.

これで、以下のように鍵が生成されました。

  • 秘密鍵:~/.ssh/id_rsa
  • 公開鍵:~/.ssh/id_rsa.pub

GitLab CI への秘密鍵の登録

作成した秘密鍵を GitLab CI に登録します。

f:id:MoriKen254:20190601232317p:plain


まず、秘密鍵をクリップボードに格納します。

 xclip -sel clip < ~/.ssh/id_rsa

次に、GitLab CI の環境変数登録画面に遷移します。

「インポートした Private Repository」→「Settings」→「CI/CD」を選択し、「Variables」を展開します。

f:id:MoriKen254:20190601193444p:plain


SSH 秘密鍵について、以下のように入力します。

  • Type: Variable
  • Key: SSH_PRIVATE_KEY
  • Value: 先程クリップボードに入れた変数をペースト
    • -----BEGIN/END RSA PRIVATE KEY----- から始まるもの。
  • State: Protected を解除
  • Maked: Masked を解除
f:id:MoriKen254:20190601193648p:plain


次に、known hosts の情報を設定します。対象は GitHub です。

$ ssh-keyscan github.com
# github.com:22 SSH-2.0-babeld-80573d3e
github.com ssh-rsa ここに HOST KEY の文字列が入る
# github.com:22 SSH-2.0-babeld-80573d3e
# github.com:22 SSH-2.0-babeld-80573d3e

出力のうち、 # がついていない 2 行目のgithub.com ssh-rsa ここ文字列が入るの部分を、以下のように GitHub の取りうるIP アドレス(192.30.252.*,192.30.253.*,192.30.254.*,192.30.255.*)を挿入した形に置き換えます。

github.com,192.30.252.*,192.30.253.*,192.30.254.*,192.30.255.* ssh-rsa ここ文字列が入る

そして、下記のようにブラウザから入力します。

  • Type: Variable
  • Key: SSH_SERVER_HOSTKEYS
  • Value: github.com,192.30.252.*,192.30.253.*,192.30.254.*,192.30.255.* ssh-rsa ここに HOST KEY の文字列が入る をペースト
  • State: Protected を解除
  • Maked: Masked を解除
f:id:MoriKen254:20190601212246p:plain


そして、「Save variables」をクリックし、環境変数を保存します。

実は、この変数は ROS の industrial_ci を利用する際の環境変数に準拠しているので、同分野で GitLab CI を利用する人にとっては、この設定を踏襲する方が移行がスムーズになります。

github.com

GitHub への公開鍵の登録

続いて、GitHub 側に公開鍵を登録します。

f:id:MoriKen254:20190601212838p:plain


まず、公開鍵をクリップボードに格納しておきます。

 xclip -sel clip < ~/.ssh/id_rsa.pub

GitHub のページから、クローン対象の Private Repository を開きます。「Settings」→「Deploy keys」→「Add deploy key」を選択します。

f:id:MoriKen254:20190601214621p:plain


「Title」に鍵の名称(例えば、SSH_PUBLIC_KEY_FOR_GITLAB_CI とか)を入力し、「Key」に先程コピーした公開鍵をペーストします。

f:id:MoriKen254:20190601214907p:plain


「Add key」を押下し、鍵を登録します。

f:id:MoriKen254:20190601215527p:plain


.gitlab-ci.yml へ SSH 認証コマンドを追加

まだ続きます。これまでに登録した SSH の設定を、CI 空間で有効にするために、.gitlab-ci.ymlbefore_script: に然るべきコマンドを追加します。

f:id:MoriKen254:20190601215952p:plain


ここでは、.gitlab-ci.ymlbefore_script 部分の、しかも SSH 認証で必要となる部分だけ抜粋して記載します。対象の依存 Repository をクローンする前に以下のコマンドを挿入すれば、SSH 認証は通るはずです。

before_script:
  - mkdir -p ~/.ssh
  - echo "$SSH_PRIVATE_KEY" > ~/.ssh/id_rsa # 秘密鍵作成
  - chmod 600 ~/.ssh/id_rsa # 秘密鍵の権限編集
  - ssh-add ~/.ssh/id_rsa # SSH 登録
  - echo "$SSH_SERVER_HOSTKEYS" > ~/.ssh/known_hosts # ホスト登録
  - これ以降はプロジェクト次第

このコマンドを GitHub 側から追加しておきます。あとは、Push 後に GitLab CI が動くのを待つのみです。

ユーザ操作によるミラーリング

実は、GitHub 側で Push しても、GitLab 側で即それを検知してくれるわけではありません。

そう、ミラーリングのタイミングは、コールバックではなくポーリングなのです。長いと30分くらい待つこともあります。いやいや、いくら無料とは言え、CI デバッグをしている身としては、これはきついです涙。

f:id:MoriKen254:20190601221701p:plain


というわけで、GitHub 側でプッシュした後に、ミラーリング先の GitLab からユーザ操作でミラーリングする方法を共有します。少々面倒ですが、ポーリングで時間を食うよりマシです。

「インポートした Repository」のページから、「Settings」→「Repository」を選択し、「Mirror a repository」を展開します。先程のミラーリングの設定画面です。

下の方にある「Mirrored repositories」で右側にある更新を彷彿とさせるロゴを有したミラーリングボタンを押下します。Last update の時間が更新されれば、手動ミラーリングの完了です!

f:id:MoriKen254:20190601171624p:plain


GitLab CI Job にて SSH 認証の確認

以上の設定でちゃんと GitLab ⇔ GitHub 間で SSH 認証ができているか、確認してみましょう。

「インポートした Private Repository」→「CI/CD」を展開→「Piplelines」を選択→「Job ステータス」を選択、と操作します。ここでは既に成功している Job を選択するので、「passed」と表示されている部分を選択します。(実際にデバッグする時は failed を表示された赤いアイコンをクリックすることになるのですが笑。)

f:id:MoriKen254:20190601222650p:plain


展開したページから「Pipeline 名」を選択します。当方のケースではたまたま「kinetic」という名前をつけていているので、これを選択します。

f:id:MoriKen254:20190601223059p:plain


展開先のページで、最新の Job の実際の出力を確認できます。

f:id:MoriKen254:20190601223157p:plain


このうち、冒頭の before_scripts 部分を見に行けば、SSH 認証時のメッセージが見られます。

f:id:MoriKen254:20190601223257p:plain


ここで、下記のようなメッセージが表示されていれば、SSH 認証は成功しています。

Agent pid hoge
Identity added: /dev/hoge/hoge (メールアドレス)

ここまでできて晴れて、依存する Private Repository を巻き込んだ上で、Private Repository の CI を通すことができるようになります。

長かったー汗。

おわりに

GitHub x Travis CI で Private Repository を CI しようとしたらお金がかかってしまう問題を、GitLab CI で解決する方法を記述しました。

きっと、同じような状況で困っているエンジニアがいるはず!

そんなエンジニアにとって、この記事が少しでもお役に立てることを願っています。

前回:② ミラーリング編

www.moriken254.com

GitLab CI を使って GitHub の Private Repository を無料で CI ②ミラーリング編

はじめに

さて、タイトルの通りです。前回は背景を話しましたが、今回からは具体的なチュートリアルに入っていきます。

www.moriken254.com

まずは、ミラーリング編。GitHub の Repository をGitLab にミラーリングしないと、GitLab CI にかけることができませんので、その手順を示します。

その後、CI を有効にするための設定ファイルを準備します。

依存する Repository を CI にクローンする方法の方はちょっとゴチャゴチャするので、次回に持ち越すことにします。

GitLab にログイン

GitLab にログインしないと何も始まりませんね。

about.gitlab.com

f:id:MoriKen254:20190601162054p:plain


GitHub の Repository をミラーリングするので、GitHub のセッション経由でログインをします。

f:id:MoriKen254:20190601162344p:plain


Repository のインポート

CI をする対象となる GitHub の Repository を GitLab にインポートします。

f:id:MoriKen254:20190601162525p:plain


左上の「Projects」→「Your Projects」→右上の「New Projects」を選択します。

f:id:MoriKen254:20190601162814p:plain


「Import Project」を選択します。

f:id:MoriKen254:20190601163025p:plain


「GitHub」を選択します。

f:id:MoriKen254:20190601163119p:plain


「インポート元の GitHub Private Repository」を選択します。このとき、「インポート先の GitLab User / Group」も選択できるので、然るべきインポート先にしておいて下さい。間違えると面倒なので。そして、「Import」を押下します。

f:id:MoriKen254:20190601163227p:plain


選択した Repository が一覧の先頭に移動します。インポート中であれば「Running...」と表示されます。

f:id:MoriKen254:20190601232003p:plain


インポートが完了すれば、「Done」と表示されます。

f:id:MoriKen254:20190601163737p:plain


Repository のミラーリング

次に、ミラーリング設定を行います。実は、インポートをしただけでは GitHub 側の Repository と同期を取ってくれるわけではないのです。

明示的にミラーリング設定を追加しないと、インポートした Repository は、GitHub 側で変化が起きたとしても、初回インポートの状態ままになってしまいます。CI したくて GitLab にやってきたのに、同期されないのでは意味がありませんね。

f:id:MoriKen254:20190601164118p:plain


てなわけで、設定ページに参りましょう。

「インポートした Repository」のページから、「Settings」→「Repository」を選択します。

表示されたページ内の「Mirror a repository」を展開すると、設定項目が出てきます。

f:id:MoriKen254:20190601164641p:plain


ミラーリング元の GitHub Repository の URL を入力する欄がありますが、少し注意が必要です。その Repository にアクセスできる GitHub ユーザ ID を URL に挿入します。書式は下図を参照下さい。

ミラーリング方向は「Pull」、認証は「Password」、Password には「GitHubのパスワード」、Mirror userは「Private Repository にアクセス可能な GitHub ユーザ名」となります。

このユーザは必ずしも自分自身である必要はなく、共通ユーザなどを持っていて、そのユーザが対象 Repository へのアクセス権を持っていれば、そのユーザを設定することもできます。

そして必要項目にチェックを入れて(下図参照)、「Mirror repository」をクリック!これでミラーリングが開始されます。

f:id:MoriKen254:20190601164835p:plain


「Mirror repository」ボタン直下にある「Mirrored repositories」の「Last update」に最新更新時間が記載されれば、ミラーリング成功です!

f:id:MoriKen254:20190601165702p:plain


CI の有効化

CI を有効化するために、GitHub 側のリポジトリにあるファイルを追加します。

そう、.gitlab-ci.yml です。

f:id:MoriKen254:20190601171725p:plain


この記事ではこの内部の書式について細かくは語りません。ここは、ユーザアプリ次第ですので、他記事による良質な解説に譲らせていただきます。

qiita.com

とにかく、この.gitlab-ci.ymlにしかるべき設定を記述した上で、 GitHub Repository 直下に格納し、リモートにプッシュして下さい。

私の開発分野でのユースケースですが、以下に例を示します。

cd "ミラーリング元の GitHub のローカル Repository 最上位ディレクトリ"
vim .gitlab-ci.yml

yml の例です。ROS の industrial_ci を用いる場合です。何度も言いますが、このファイルの中身は、ご自身の開発プロジェクトの内容に合わせて適切なものに置き換えて下さい。

image: docker:git
services:
  - docker:dind
before_script:
  - apk add --update bash coreutils tar
  - git clone --quiet --depth 1 https://github.com/ros-industrial/industrial_ci .industrial_ci
  
kinetic:
  script:
    - .industrial_ci/gitlab.sh
  variables:
    ROS_DISTRO: "kinetic"
    CATKIN_LINT: "true"
    OPT_VI: "-vi"

上記ファイルを保存して、あとはリモートにプッシュしておいて下さい。

それ以外の設定(Runner 等)は全てデフォルトでも基本は大丈夫ですので、この記事では扱いません。

おわりに

これで、最低限 GitLab CI を有効にするためのミラーリング設定は完了です。

次は、依存するプライベート Repository を クローンできるように、SSH 認証を行えるようにする手順を述べます。

次回:③SSH 編

www.moriken254.com

前回:①背景編

www.moriken254.com

GitLab CI を使って GitHub の Private Repository を無料で CI ①背景編

はじめに

GitHub ユーザは Travis CI を使っていることが多い

GitHub のリポジトリを CI するサービスは様々ありますが、多くの方は Travis CI を利用されているのではないでしょうか。簡単に連携できますし。

Public Repository を利用する限りは、無料版の Travis CI で制限なく CI ができるので、特に問題はありません。ある Repository を CI する際に、依存する Repository が存在したとしても、それも Public であればこれまた問題はありません。

f:id:MoriKen254:20190601153831p:plain


Private Repository だとお金がかかる…

ところが、訳あって秘匿にしなければならなくなった Private Repository を CI したくなったときが、困りものです。Travis CI を有償プランにアップデートしないと、Private Repository が CI できないというのですから、これは大変です!

f:id:MoriKen254:20190601154043p:plain


そんな!せっかく GitHub で Private Repository を作りやすくなったっていうのに、Travis CI の方がお金かかっちゃうだなんて。いくら社会人とは言え、訳あって何度も休職を余儀なくされるため薄給であり、かつ曲がりなりにも学生でもあるゆえに何かと出費も嵩む私の身では、あまりに痛い仕打ちではあーりませんか(Repository よりも、無駄に事情の方が Private 過ぎる笑)。

救世主、GitLab CI の登場

そんな悩める苦社会人に差し伸べられて救いの手…。それが GitLab CI です!

f:id:MoriKen254:20190601154613p:plain


  • GitLab では Private Repository を無料で作成できる
  • GitLab が提供する GitLab CI では Private Repository を無料で CI できる
    • 1ユーザ or 1グループにつき月2000分が上限
  • GitLab CI では、依存する Private Repository のクローンもできる
    • SSH の設定が必要

性能もお墨付き

このように、うまく設定して使いこないさえすれば、無料で CI できてしまう優れもの!しかも、第三者機関による性能評価も上々というのだからアッパレです。


難点が

素敵過ぎる!そう思ったでしょ。

でもね、でもね…。手順が複雑なんです!!!涙

Travis CI みたいに、軽くポチればいいんじゃなくて、色々と準備をしないといけません。Private Repository クローンしてくるあたりとか、もうなんど諦めかけたことか(オイ)!

まぁ、無料で使えるだけありがたいので、そこはエンジニアとしてハンドリングすればよいのですが、にしたって手順が複雑です。

Private Repository を無料で CI したいと画策したものの、おとなしく Travis CI に泣く泣くお金を払う運びとなったエンジニア仲間がどこかにいるはず!(妄想だったりして…)

というわけで、その複雑な手順を図を交えてチュートリアル形式に記事にしていきます!私と同じような状況に至った悩めるエンジニアにとって、少しでも助けになればと思います。

構成

具体的な手順は次回以降、2回の記事に分けて記述します。

少し補足

GitLab CI 自体は汎用的なサービスですが、私は自分の趣向の関係で、ROS のプロジェクトに CI をかけることが多いです。

そのため、変数定義やユースケースが、ROS の CI サービス用 Repository である industrial_ci に(こっそり)準拠させている場合があります。

github.com

特に動作に支障はないと思いますが、念の為補足です。

それでは、また次回!

次回: ② ミラーリング編

www.moriken254.com

【ROS 2】2 つの別々の docker コンテナで 2 つのノードを実行 (公式文書和訳)

ROS 2 公式文書(英語) 日本語訳シリーズです。

本ブログの日本語翻訳版のトップページは以下のリンクを参照下さい。

www.moriken254.com

※2019/05/11 現在のものです。

ターミナルを開きます。対話モードでコンテナ内のイメージを実行し、ros2 run を使用してトピックパブリッシャ(パッケージ demo_nodes_cpp からの実行可能トーカ)を起動します。

docker run -it --rm osrf/ros2:ardent-basic ros2 run demo_nodes_cpp talker

2 番目のターミナルを開きます。対話モードでコンテナ内のイメージを実行し、ros2 run を使用してトピック購読者(パッケージ demo_nodes_cpp からの実行可能リスナ)を起動します。

docker run -it --rm osrf/ros2:ardent-basic ros2 run demo_nodes_cpp listener

コマンドライン呼び出しの代わりに、以下の(最小限の)内容でdocker-compose.yml ファイル(ここではバージョン 2)を作成することができます。

version: '2'

services:
  talker:
    image: osrf/ros2:ardent-basic
    command: ros2 run demo_nodes_cpp talker
  listener:
    image: osrf/ros2:ardent-basic
    command: ros2 run demo_nodes_cpp listener
    depends_on:
      - talker

コンテナを実行するには、docker-compose up を同じディレクトリで呼び出します。 Ctrl+C でコンテナを閉じることができます。

翻訳元文書

index.ros.org

関連文書

www.moriken254.com

www.moriken254.com

【ROS 2】単一の docker コンテナ内で2つのノードを実行(公式文書和訳)

ROS 2 公式文書(英語) 日本語訳シリーズです。

本ブログの日本語翻訳版のトップページは以下のリンクを参照下さい。

www.moriken254.com

※2019/05/11 現在のものです。

Docker イメージの pull

タグ「ardent-basic」を使用して ROS 2 docker イメージを pull します。

docker pull osrf/ros2:ardent-basic

Docker イメージの実行

インタラクティブモードでコンテナ内のイメージを実行します。

$ docker run -it osrf/ros2:ardent-basic
root@<container-id>:/#

Docker イメージ内での ROS コマンドの実行

例 1:ros2 コマンドラインヘルプの実行

root@<container-id>:/# ros2 --help

例 2:インストールされているすべてのパッケージのリスト

root@<container-id>:/# ros2 pkg list
(you will see a list of packages)

例 3:すべての実行ファイルの一覧表示

root@<container-id>:/# ros2 pkg executables
(you will see a list of <package> <executable>)

例 4:パブリッシャとサブスクライバの起動

このコンテナの demo_nodes_cpp パッケージから、2 つの C++ ノード(1 つのトピック購読者リスナー、1 つのトピックパブリッシャートーカー)の最小限の例を実行します。

ros2 run demo_nodes_cpp listener &
ros2 run demo_nodes_cpp talker

翻訳元文書

index.ros.org

関連文書

www.moriken254.com

www.moriken254.com

【ROS 2】RQt プラグインを Windows に移植する(公式文書和訳)

ROS 2 公式文書(英語)](https://index.ros.org/doc/ros2/) 日本語訳シリーズです。

本ブログの日本語翻訳版のトップページは以下のリンクを参照下さい。

www.moriken254.com

※2019/05/11 現在のものです。

RQt は歴史的には Windows 上でサポートされていませんが、互換性は持つようになってきています(ゆっくりとではありますが)。

RQt 移植の例

Microsoft は ROS の大部分を Windows に移植するよう努力しました。彼らのリポジトリは必要な変更を知るための良いリソースとなっています。そのリソースは init-windows と呼ばれるブランチを持つリポジトリとして、 ms-iot オーガニゼーションに格納してあります。例えば、こちらです。

こちらが qt_gui_core の ROS 2 ポートです。

こちらが python_qt_binding の ROS 2 ポートです。

Windows 10 に関する考慮事項

TinyXML バージョン 1 に関する問題

TinyXML バージョン 1 ではうまく動作しませんでした。ですので、必要に応じて TinyXML-2 にアップグレードしました。それはかなり簡単です。

TinyXML-2 への移植の例についてはこの PR をチェックしてください。

__cplusplus を使用するコードと pluginlib を必要とするコード

何箇所か、特に pluginlib の ROS 2 移植版では、__cplusplusフラグの使用があります。残念ながら Windows では、Visual Studio は実際に使用されている C++ 標準に関係なく、このフラグを正しく設定できません。詳しくはこちらのページをご覧ください。

設定するには、コンパイルオプション /Zc:__cplusplus を追加する必要があります。

たとえば、CMake では、次のようにすることができます。

target_compile_options(${PROJECT_NAME} PUBLIC "/Zc:__cplusplus")

ビルド生成物の格納場所(インストール前)

これは qt_gui_cpp をビルドしている間にだけ起こりました。そのパッケージでは、カスタムコマンドはパッケージの他の部分のターゲットライブラリに依存します。ただし、そのライブラリはビルドが完了するまでインストールされません。 Windowsは ${configuration} ディレクトリに構築されています。例えば:

  • Linuxでは、qt_gui_cpp.a<ros2_ws>/build/qt_gui_cpp/src/qt_gui_cpp / にビルドされます。
  • しかし Windows では qt_gui_cpp.lib<ros2_ws>/build/qt_gui_cpp/src/qt_gui_cpp/Release にビルドされています。

この状況でのプラットフォーム間の互換性のためには、CMake 生成式を使用してください。ただし、リンクするライブラリが必要な場合は、必ず $<TARGET_FILE:_target> ではなく $<TARGET_LINKER_FILE:_target> を使用してください。後者は .dll ファイルを検出できるでしょう(ただしそれは Windows 上でリンクされることができません)。こちらの例をご覧ください。

コンパイラとリンカのフラグ

一般に、Windows に移植するとき、多くのパッケージは追加のコンパイラフラグを利用するかもしれません。 Windows のコンパイラフラグは Microsoft のドキュメントにあります。 C++ コンパイラは cl.exe と呼ばれます。

リンカフラグについては、Microsoft のドキュメントを参照してください。リンカプログラムは link.exe と呼ばれます。

しかし、CMake は実際には変数でこれらのオプションの多くを提供しています。この StackOverflow ページには、スクリプトで使用可能なすべての CMake 変数を確認する方法の良い例が含まれています。

翻訳元文書

index.ros.org

関連文書

www.moriken254.com

www.moriken254.com

【ROS 2】ament と catkin の混合(→ catment)について(公式文書和訳)

ROS 2 公式文書(英語) 日本語訳シリーズです。

本ブログの日本語翻訳版のトップページは以下のリンクを参照下さい。

www.moriken254.com

※2019/05/11 現在のものです。

背景

かつて rosbuild というビルドシステムがありました。それから catkin と呼ばれるものもできました。最近導入されたものは ament と呼ばれるもので、いつか catkin に取って代わるかもしれません。

これら 3 つのツールはすべて「メタビルドシステム」と見なすことができます。他のビルドシステム(CMake、Python setuptools など)の上に配置され、特に複数のパッケージにまたがる依存関係を管理するときや単一のワークスペースに複数のパッケージをビルドするときに、これらのビルドシステムを使いやすくするための追加機能を提供してくれます。

これらの各メタビルドシステムは、2 つのことを行います。

  1. 一般的なタスクを単純化するために使用できるAPI(例:CMake)を基盤となるビルドシステムに追加します(たとえば、実行可能ファイルをビルドするときに依存パッケージによってエクスポートされるすべてのフラグを指定する)。通常、コアのメタビルドシステムの外部のパッケージによる追加のAPIのインジェクションを可能にするためのフックがあります。
    • rosbuildmk/cmake.mkrosbuild_init()rosbuild_add_executable()など
    • catkincatkin_package()catkin_install_python() など
    • amentament_target_dependencies()ament_export_dependencies()ament_package() など
  2. パッケージでいっぱいのワークスペースで依存関係の順序で反復し、それぞれをビルドしてインストールするために使用できるツールを提供します。
    • rosbuildrosmake
    • catkincatkin buildcatkin_makecatkin_make_isolated など
    • amentament build

これらのシステムすべてを結び付ける共通のスレッドは、コードをパッケージに分割することです。各パッケージには、マニフェストファイル(manifest.xml または package.xml)が含まれています。このマニフェストは、メタビルドシステムの API とビルドツールの両者が機能するために(いくつかの例外を除いて)必要となります。

仮定

  1. 私たちは通常、メタビルドシステムの 2 つの特長(API とビルドツール)を組み合わせることを考えていますが、そうである必要はありません。
    • パッケージ内で使用される API とパッケージを反復処理するツールは、パッケージマニフェストがそれらの間のインタフェースを形成しているため、ほぼ独立していると見なすことができます。rosmake が(cmakemake に渡される適切なフラグを使って)、 catkin パッケージが入っているワークスペースを反復処理し、依存関係の順序でそれらにステップインして、それぞれのルーチン(mkdir build; cd build; cmake ..; make install)を実行するように変更できないのは、原則として理由はありません。
  2. あるメタビルドシステムから別のビルドシステムへ移行するのに必要な労力は最小限にすべきです。

    • rosbuild からcatkin` への大量移行は困難で、多くのユーザにとって依然として悩ましい点です。新機能にアクセスできるようにする、開発者に変更を加えるよう依頼することは合理的なのですが、その変更のため新しいシステムの有効性が損なわれるような影響は可能な限り最小化すべきです。これは、古いシステムが広く使用されている場合に特に当てはまります。
    • 導かれる知見:新しいメタビルドシステムへの移行は、よっぽど正当な理由がない限り、要求されるべきではありません。
      • 開発者が新しいシステムによって提供される機能を特に欲さないのであれば、古いシステムでは解決不能なレベルの問題がない限り(例えば rosbuild のインソースビルドパターンや「インストール」ステップがない等)、そのパッケージを無理に新しいシステムに移行すべきではありません。
  3. 相互運用性は良いことです。

    • 可能であれば(すべての組み合わせが実用的ではない)、開発者は、異なる側面を混在させることを含めて、メタビルドシステムを混在させることができます(つまり、あるシステムの構築ツールと別のシステムのAPIを使用)。このようなミキシングおよびマッチングは、開発者が1つのメタビルドシステム(ROSとcatkinなど)を使用する大規模な既存のコードベースを、別のメタビルドシステムを使用するコードベースによって提供される新しいライブラリとツール(ROS2など)と組み合わせる場合に特に重要です。 amentと)理想的には、そのような組み合わせは、どちらのコードベースでも使用されるAPIへの変更を必要とせずに、またどのビルダーツールを使用するかを開発者に指示することなく実行できます。

    • 導かれる知見:ワークスペースは均一である必要はありません。

      • catkinament の両パッケージをワークスペース内に入っていて、しかも依存関係は両方向にあるような状況だとしても、使用するビルダツールがそれらを両方をビルドできる仕様であれば、それができない理由はありません(要は、両方入っていてもビルドできるでしょってこと)。パッケージ(少なくとも CMake 管理パッケージ)間の主要なインターフェースはそれらの CMake 設定ファイルです。その設定ファイルが標準プロトコル(foo_LIBRARIESの設定など)に従っている限り、誰がファイルを書いたかは関係ありません。 catkinament によって自動生成されたりすることもありますし、自作パッケージでプレーンな CMake を使いたい開発者が手で直接書いた設定ファイルであることもあります。しかも、後者の自作設定ファイル内で、更にcatkinament に依存されているパッケージを記述している場合もあるくらいです。

実験的な実装によるユースケース

ROS 2 ワークスペースに ROS パッケージを追加して ament build でビルドする

既存の ROS パッケージを ROS 2 ワークスペースに追加し、その ROS パッケージを catkin から ament に(またはその逆に)移行したくない状況を仮定としましょう。これを可能にする 2 つのパッチがあります。

  • ament_package:フォーマット 2 を要求する代わりに、フォーマット 1 のパッケージマニフェストのサポートを追加します。この変更は、catkinamentに厳密には関係しません。というのも、フォーマット 2 はしばらく前から存在し、catkin がそれをサポートしているので、開発者が既にcatkin側のマニフェストを更新できる状況でうす。しかし、フォーマット1を使用する大量の ROS コードがありますので、それをサポートする必要があります。この実装は、たとえば、さまざまな種類の依存タグ、およびフォーマット 1 と 2 の間でタグがどのように異なるかを推論することによって改善できます。
  • ament_tools:新しい catkin ビルドタイプを ament に追加します。この実装は catkin パッケージを普通の cmake パッケージと同じように扱うだけで、うまくいきます。今後もっと洗練されたものになるでしょう。

  • 使用例

    1. 上記のブランチを使用して、通常どおり ROS 2 コードを入手してください。
    2. ワークスペースに catkin ROS パッケージを追加して、それらのすべての依存関係が満たされていることを確認します(ワークスペースに存在するか、適切なセットアップシェルファイルを使用して他の場所にインストールされます)。
    3. 通常どおりにビルドします(例:./src/ament/ament_tools/scripts/ament.by build)。

ジャジャ~ン!:新しいビルダーツールが使用されているからといって、既存のコードが突然壊れることはありません。

ケース 1:ament build を使って ROS パッケージをビルドする

新しい ament ツールがお気に入りになり、catkin を内部的に使用する既存の ROS パッケージをビルドするのに ament を使いたくなったとしましょう。これを実行する方法の例を次に示します。ament を最小インストールしてから、それを使用して ROS catkin パッケージの入ったワークスペースを構築します。

mkdir -p ~/ament_ws/src
cd ~/ament_ws/src
git clone https://github.com/osrf/osrf_pycommon.git
git clone https://github.com/ament/ament_package.git
cd ament_package
git checkout catkin
cd ..
git clone https://github.com/ament/ament_tools.git
cd ament_tools
git checkout catkin
cd ../..
 ./src/ament_tools/scripts/ament.py build

それではROSパッケージをビルドしてください。

. $HOME/ament_ws/install/setup.bash
cd ~/ros_catkin_ws
ament build

ジャジャ~ン:catkin パッケージを移行することなく、ament build ツールを使って catkin パッケージを構築しました。

ケース 2:ROS 2 パッケージで catkin API を使う

ここでは、まず ROS 2 上ででビルドしていて(ament API を内部的に使用している)、その後 catkin API を使用して新しいパッケージを追加したい状況を考えます。

これを機能させるには、catkin の Python3 のインストールが必要です(バイナリ Debian は Python2.7 を使用します)。これを行う例を次に示します。$HOME/catkin にインストールします。

# install catkin_pkg
git clone https://github.com/ros-infrastructure/catkin_pkg.git
cd catkin_pkg
git checkout ament
python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb
# install catkin
git clone https://github.com/ros/catkin.git
cd catkin
git checkout ament
mkdir build
cd build
PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3
make install

そのバージョンの catkin を使用するには、$HOME/catkin/setup.bash ファイルを入手するだけです。

通常の ROS 2 ワークスペースが ~/ros2_ws にあり、ament_packageament_toolscatkin ブランチにいるとしましょう。そのワークスペースに https://github.com/gerkey/catment から image_tools_catkin パッケージを追加してください。これは ROS 2 の image_tools パッケージを単純に移植したもので、ament API から catkin API に変更されました。それをビルドするには:

cd ~/ros2_ws
. $HOME/catkin/setup.bash
./src/ament/ament_tools/scripts/ament.py build

ジャジャ~ン:ROS 2 の上に新しいパッケージを追加するとき、自作パッケージに対して、どの CMake API を好むかを自由に選ぶことができます。

  • 警告catkin_package() の中で CATKIN_DEPENDS を使用することをコメントアウトしなければなりませんでした。なぜなら、rclcpp 等(ROS 2 で追加されたパッケージ)が catkin パッケージではないことで怒られたからです。その制約はなんとかして外してやる必要があります。
  • TODO:同じデモですが、catkin パッケージに依存する ament パッケージがあります(これは簡単に解決できます)。
  • TODO:同じデモですが、amentcatkin も使用しないきれいな CMakeLists.txtを持ち、ROS の外部でも普通に使えるように適切なものをエクスポートする、手入力で生成された fooConfig.cmake ファイルを提供するパッケージがあります。

catkin_make_isolated による ROS 2 パッケージの構築

すでに ROS と catkin に精通しており、ROS 2 を試すことに興奮しているそこのあなた。ament について学ぶ気なんて起きないかも知れませんね。そんなあなたに、catkin_make_isolated を使ってすべてをビルドできる機能があれば、良いと思いませんか?これを可能にするパッチがあるのです。

  • catkin:ビルドタイプが ament_* であることを宣言しているパッケージのサポートを追加しました。この実装はそのような各パッケージをビルドするために ament を要求します。 ament_cmake パッケージはプレーンな cmake パッケージとして扱うことができますが(amentcatkin サポートを追加したときのように)、ament_python パッケージは普通の Python 呼び出しを必要とする場合があります。そのロジックを catkin で再現するのではなく、単に ament に処理させる方が簡単です。またこのパッチでは、 buildtool_export_depend パッケージをビルド時に考慮されるセットに追加します。
  • catkin_pkg:このパッチでも、トポロジ順序を計算するときに考慮されるbuildtool_export_dependパッケージをセットに追加します。

ここでは ament build を呼び出すことになるので、前の例で行ったように、最低限の ament のインストールも必要になります。

mkdir -p ~/ament_ws/src
cd ~/ament_ws/src
git clone https://github.com/osrf/osrf_pycommon.git
git clone https://github.com/ament/ament_package.git
cd ament_package
git checkout catkin
cd ..
git clone https://github.com/ament/ament_tools.git
cd ament_tools
git checkout catkin
cd ../..
 ./src/ament_tools/scripts/ament.py build

それから、ament 対応版の catkin をどこかにインストールする必要があります。

# install catkin_pkg
git clone https://github.com/ros-infrastructure/catkin_pkg.git
cd catkin_pkg
git checkout ament
python3 setup.py install --prefix $HOME/catkin --single-version-externally-managed --record foo --install-layout deb
# install catkin
git clone https://github.com/ros/catkin.git
cd catkin
git checkout ament
mkdir build
cd build
PYTHONPATH=$HOME/catkin/lib/python3/dist-packages/ cmake .. -DCMAKE_INSTALL_PREFIX=$HOME/catkin -DPYTHON_EXECUTABLE=/usr/bin/python3
make install

それでは ROS 2 パッケージをビルドしてください。

. $HOME/catkin/setup.bash
. $HOME/ament_ws/install/setup.bash
cd ~/ros2_ws
touch src/eProsima/AMENT_IGNORE
PYTHONPATH=$PYTHONPATH:/home/gerkey/ros2_ws_catkin/install_isolated/lib/python3.5/site-packages
catkin_make_isolated --install

ジャジャ~ン:ROS 2 はお馴染みのツールでビルドできました。

  • 警告package.xml ファイルがないため、ワークスペース内の eProsima パッケージは無視されます。つまり、catkin はそれらを見ることができません。ament はそのようなパッケージを扱うための経験則を持っています。
    • オプション:この経験則を catkin に戻します。ワークスペースの外側で package.xml を含まないパッケージのインストールに切り替えます。または、単にそれらの各パッケージに package.xml を追加します(たとえば、fork して編集する等)。

ROS と ROS 2 のすべてを一つのワークスペースにまとめて構築する(TODO)

このステップでは、少なくとも以下を含むいくつかのことを整理する必要があります。

  • パッケージ名の競合:現在、ROS メッセージパッケージのROS 2 バージョンがあります。geometry2 にも同様のものが含まれてしまっています。この機能を両方のシステムをサポートできる 1 つのパッケージにマージするか、新しいバージョンでは異なる名前とする必要があります。
  • メッセージ生成:ROS と ROS 2 には異なるメッセージ生成手順があり、その出力は競合する場合としない場合があります。単一のメッセージパッケージから正しい実体をすべて生成できるようにするには、何らかのうまい方法を実行する必要があります(または、上記のように、新しいメッセージパッケージには別の名前が必要です)。

bloom を使って ament パッケージをリリースする(TODO)¶

ament CMake API を使用するパッケージを bloom がリリースできるようになり、その結果リリースされるものはファーム上に構築できるようになるはずです。このユースケースを有効にするために必要に応じて bloomros_buildfarm に変更を加えることができます。

翻訳元文書

index.ros.org

関連文書

www.moriken254.com

www.moriken254.com