ROS 2 公式文書(英語) 日本語訳シリーズです。
本ブログの日本語翻訳版のトップページは以下のリンクを参照下さい。
※2019/05/09 現在のものです。
ament_cmake は ROS 2 の CMake ベースのパッケージビルドシステムです(全部とは言わないまでも、ほとんどの C/C++ プロジェクトで使用されています)。これは CMake を拡張したもので、パッケージ作成時の便利機能が追加されています。 CMake の基本を知っておくと理解が深まります。公式のチュートリアルも参考になります。
基本
基本的な CMake のアウトラインは、コマンドラインでros2 pkg create <パッケージ名>
で作成されます。その後、基本的なビルド情報はpackage.xml
とCMakeLists.txt
の2つのファイルに集約されます。 colcon がパッケージの正しいビルドの順番を検出したり、必要な依存関係を CI にインストールしたり、さらにリリースに関する情報をbloom
で提供できるようにするには、package.xml
にすべての依存関係とメタデータを含めておく必要があります。 CMakeLists.txt
には、実行可能ファイルとライブラリをビルドおよびパッケージ化するためのコマンドが含まれています。このページでは主としてそのコマンドについて説明します。
ament チュートリアルも参照してください。←リンク切れ
標準プロジェクト概要
ament パッケージのCMakeLists.txt
の基本的な概要は以下の通りです。
cmake_minimum_required(VERSION 3.5) project(my_project) ament_package()
project
の引数はパッケージ名になり、package.xml
のパッケージ名と同じでなければなりません。
プロジェクトの設定はament_package()
によって行われます。この呼び出しはパッケージごとに1回だけ行う必要があります。 ament_package()
は、package.xml
をインストールし、そのパッケージをament
インデックスに登録し、そして CMake のための config(そしておそらくtarget)ファイルをインストールします。これにより、find_package
で他のパッケージから検出できるようになります。 ament_package()
はCMakeLists.txt
内の全ての情報を集約して処理をする関数なので、"CMakeLists.txt"の最終行に記述する必要があります。ファイルとディレクトリをコピーするinstall
関数によってament_package()
を再現することもできますが、ament_package()
を最後の呼び出すほう楽です。
ament_package
には追加の引数を与えることができます。
CONFIG_EXTRAS
:パッケージのクライアントに利用できるようにする追加の CMake ファイル(configure_file() によって展開された.cmake
または.cmake.in
テンプレート)のリスト。これらの引数を使用する場合の例については、リソースの追加を参照してください。テンプレートファイルの使用方法の詳細については、Cmake の公式文書を参照してください。CONFIG_EXTRAS_POST
:CONFIG_EXTRAS
と同じですが、ファイルが追加される順序が異なります。CONFIG_EXTRAS
から生成されたファイルがament_export_*
用に生成されたファイルの「前」に含まれるのに対して、CONFIG_EXTRAS_POST
から生成されたファイルはその「後」に含まれます。
ament_package
に追加する代わりに、変数${PROJECT_NAME}_CONFIG_EXTRAS
および${PROJECT_NAME}_CONFIG_EXTRAS_POST
に同じ効果を追加することもできます。唯一の違いは、ファイルが追加される順序が次の通りであることです。
CONFIG_EXTRAS
によって追加されたファイル${PROJECT_NAME} _CONFIG_EXTRAS
にアペンドして追加されたファイル${PROJECT_NAME} _CONFIG_EXTRAS_POST
にアペンドして追加されたファイルCONFIG_EXTRAS_POST
によって追加されたファイル
ファイルとヘッダの追加
ビルドする主なターゲットは2つあります。それぞれadd_library
とadd_executable
によってビルドされる、ライブラリと実行可能ファイルです。
ヘッダーファイルの分離と C/C++ での実装では、add_library
/add_executable
の引数として、必ずしも両ファイルを追加する必要はありません。
以下のベストプラクティスが提案されています。
- ライブラリをビルドする場合は、クライアントに解放する全ヘッダーをパッケージ名に相当する名前のフォルダ配下の
include
サブディレクトリに格納しておきます。一方、エクスポートしてはいけないファイル(.c / .cpp
とヘッダファイル)はsrc
フォルダ内にあります。 add_library
またはadd_executable
の呼び出しでは、cpp ファイルのみを明示的に参照する。- 下記のコマンドでヘッダを検出させる:
target_include_directories(my_target PUBLIC $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<INSTALL_INTERFACE:include>)
これにより、ビルド時に${CMAKE_CURRENT_SOURCE_DIR}/include
フォルダ内の全てのファイルがパブリックインターフェースに追加され、インストール時に include フォルダ内の全てのファイル(${CMAKE_INSTALL_DIR}
からの相対パス)が追加されます。
原則として、両フォルダともinclude
フォルダだった場合や、${CMAKE_CURRENT_SOURCE_DIR}
および${CMAKE_INSTALL_DIR}
直下のフォルダの場合には、ジェネレータ式を使用する必要はありません。ただし、そのような場合でもジェネレータ式を記述しておくのが一般的です。
リソースの追加
パッケージを新しい依存関係に対してリンクするには2つの方法があります。
最初の、そして推奨される方法は ament マクロ であるament_target_dependencies
を使うことです。例として、my_target
を線形代数ライブラリ Eigen3 に対してリンクさせたいとします。
find_package(Eigen3 REQUIRED) ament_target_dependencies(my_target Eigen3)
これにより、必要なヘッダとライブラリおよびそれらの依存関係を、プロジェクトが検出できるようになります。また、オーバーレイワークスペースを使用するときに、すべての依存関係のインクルードディレクトリが正しく順序付けされていることも保証されます。
2番目の方法はtarget_link_libraries
を使うことです。
現代の CMake で推奨される方法は、ターゲットのみを使用し、それらをエクスポートしてリンクすることです。 CMake ターゲットは C++ と同様に名前空間があります。たとえば、Eigen3
の場合は、ターゲットとしてEigen3 :: Eigen
をを指定します。
少なくともCrystal Clemmys
より前までは、ターゲット名がament_target_dependencies
マクロでサポートされていません。場合によっては、target_link_libaries
CMake 関数を使う必要があります。 Eigen3 の例では、呼び出しは次のようになります。
find_package(Eigen3 REQUIRED) target_link_libraries(my_target Eigen3::Eigen)
これには必要なヘッダ、ライブラリ、およびそれらの依存関係も含まれますが、ament_target_dependencies
とは対照的に、オーバーレイワークスペースを使用するときに依存関係を正しく順序付けできない可能性があります。
注意
明示的に必要とされないライブラリをfind_package
することは不要ですが、別の依存関係(依存A)を持つ依存関係(依存B)を記述する場合には、依存Aを明示的に記述しなければなりません。
その場合、該当するパッケージに対してバグを報告してください。
ライブラリのビルド
再利用可能なライブラリをビルドするとき、それを利用しやすくするために下流のパッケージ用にいくつかの情報をエクスポートする必要があります。
ament_export_interfaces(export_my_library HAS_LIBRARY_TARGET) ament_export_dependencies(some_dependency) install( DIRECTORY include/ DESTINATION include ) install(my_library TARGETS my_library EXPORT export_my_library LIBRARY DESTINATION lib ARCHIVE DESTINATION lib RUNTIME DESTINATION bin INCLUDES DESTINATION include )
ここでは、include
フォルダーにエクスポートする必要があるヘッダーが含まれているとします。すべてのヘッダを別々のフォルダに入れる必要はないことに注意してください。クライアントが含めるべきヘッダだけを入れてください。
上記のスニペットで起こっていることは以下の通り:
ament_export_interfaces
マクロは CMake のターゲットをエクスポートします。これは上記ライブラリのクライアントがtarget_link_libraries(client my_library::my_library)
構文を使えるようにするために必要です。ament_export_interfaces
は、install コマンドにおけるEXPORT
という名前の任意のターゲットリストと、環境変数に潜在的な依存ライブラリを登録する追加オプションHAS_LIBRARY_TARGET
を取ることができます。ament_export_dependencies
は依存関係を下流のパッケージにエクスポートします。これは、ライブラリのユーザがそれらの依存関係に対してもfind_package
を呼び出さなくてもいいようにするためです。最初の
install
コマンドは、クライアントに公開するヘッダファイルをインストールするためのものです。最後の大きな
install
コマンドはライブラリをインストールします。アーカイブとライブラリファイルはlib
フォルダにエクスポートされ、ランタイムバイナリはbin
フォルダにインストールされ、インストールされたヘッダへのパスもシステムに登録されます。- 注意:Windows の dll は(ライブラリではなく)ランタイムとして扱われ、
RUNTIME DESTINATION
フォルダにインストールされます。したがって、UNIX ベースのシステムでライブラリを開発する場合でも、RUNTIME
インストールを除外しないことをお勧めします。
- 注意:Windows の dll は(ライブラリではなく)ランタイムとして扱われ、
include directory
に関しては、install コマンドは CMake に情報を追加するだけで、実際には includes フォルダをインストールしません。これは上述のように、install(DIRECTORY <dir> DESTINATION <dest>)
によってヘッダをコピーすることによって行われます。install 呼び出しの
EXPORT
表記にはさらに注意が必要です。これは、my_library
ターゲット用の CMake ファイルをインストールします。これはament_export_interfaces
の引数とまったく同じ名前で、ライブラリのように名前を付けることもできます。しかし、これよって出力されたライブラリは、ament_target_dependencies
でインクルードできなくなってしまいます。それとは完全に切り離せるよう、専用のexport_<target>
のようなものをエクスポート先に追加することをお勧めします。すべてのインストールパスは、colcon/amentによってすでに正しく設定されている
CMAKE_INSTALL_PREFIX
からの相対パスです。
使用できる2つの追加機能がありますが、ターゲットベースのインストールには不要です。
ament_export_include_directories(include) ament_export_libraries(my_library)
最初のマクロは、エクスポートされたインクルードディレクトリをマークします(これは、ターゲットinstall
のINCLUDES DESTINATION
によって実現されます)。 2番目のマクロは、インストールされているライブラリの場所を示します(これはament_export_interface
への呼び出しのHAS_LIBRARY_TARGET
引数によって行われます)。
いくつかのマクロは非ターゲットエクスポートに対して異なるタイプの引数を取ることができますが、最近のMakeのための推奨される方法はターゲットを使うことであるので、ここでは カバー しません。これらのオプションのドキュメントはソースコード内に記載してあります。
コンパイラとリンカのオプション
ROS 2 は、少なくともCrystal Clemmys
までは、C++14 および C99 規格に準拠しているコンパイラを対象としています。より新しいバージョンは将来的には見据えていて、こちらで言及されています。したがって、対応する規格に応じた CMake フラグを設定するのが慣例です。
if(NOT CMAKE_C_STANDARD) set(CMAKE_C_STANDARD 99) endif() if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 14) endif()
コードをきれいに保つために、コンパイラは不正が疑われるコードに対してワーニングを出すべきであり、修正されるべきです。
少なくとも次の警告レベルをカバーすることをお勧めします。
- Visual Studioの場合:デフォルトの
W1
警告は保持されます。 - GCC と Clang の場合:
-Wall -Wextra -Wpedantic
が必要で、-Wshadow -Werror
が推奨されます(後者はワーニングをエラーと解釈します)。
現代の CMake はターゲットベースでコンパイラのフラグを追加することをお勧めしますが(例:call)、
target_compile_options(my_target PRIVATE -Wall)
現時点では、ディレクトリレベルの関数add_compile_options(-Wall)
を使用して、すべての実行可能ファイルおよびテスト用のターゲットベースのコンパイルオプションで行数が増えてしまい、コードが乱れないようにすることをお勧めします。
Windows におけるライブラリのビルド
Linux、Mac、Windows はすべて公式にサポートされているプラットフォームなので、効果を最大限得るためには、どのパッケージも Windows 上でビルドできるようにする必要があります。 Windows ライブラリフォーマットはシンボルの可視性を強化します。クライアントから使用されるべきすべてのシンボルはライブラリによって明示的にエクスポートされる必要があります(そしてデータシンボルは暗黙的にインポートされる必要があります)。
Clang と GCC ビルドとの互換性を保つために、GCC ウィキ内に記載されているロジックを使用することをお勧めします。 my_library
というパッケージに使用するには
- リンク内のロジックを
visibility_control.hpp
というヘッダーファイルにコピーします。 DLL
をMY_LIBRARY
に置き換えます(例については、rviz_rendering の可視性制御を参照してください)。- エクスポートする必要があるすべてのシンボル(つまり、クラスまたは関数)に対してマクロ「MY_LIBRARY_PUBLIC」を使用します。
- プロジェクト
CMakeLists.txt
で、以下のコマンドを使用します。
target_compile_definitions(my_library PRIVATE "MY_LIBRARY_BUILDING_LIBRARY")
テストと構文チェック
colcon を使ってライブラリをビルドをすることととテストを分離するために、構文チェックとテストへのすべての呼び出しを条件付きでラップします。
if(BUILD_TESTING) find_package(ament_gtest) ament_add_gtest(<tests>) endif()
構文チェック
ament によって提供されるすべての構文チェッカは別々に追加することができますが、それらを組み合わせたコマンドを使用することをお勧めします。
find_package(ament_lint_auto REQUIRED) ament_lint_auto_find_test_dependencies()
これはpackage.xml
で定義されているように構文チェッカを実行します。 ament_lint_common
パッケージで定義されている一連の構文チェッカを使用することをお勧めします。これにより、以下のすべての構文チェッカ実行されます。
- 著作権文とライセンスヘッダの存在とその正当性を確認する著作権構文チェッカ
- cppcheck、論理テストも見つけることができるC++ 構文チェッカ
- cpplint、C++ スタイルの構文チェッカ(例えばコメントスタイル)
- C++ スタイル構文チェッカ
- cmake チェッカ
- XML uncrustify
- flake8、python ファイル用のスタイルチェッカ
- pep257、python docstrings のスタイルチェッカ
ament_uncrustify
には、コマンドラインツールが付属しています。これを呼び出すと、スタイルガイドに従ってコードを自動的に再フォーマットできます。
ament_uncrustify --reformat <path_to_source_folders>
テスト
Ament には GTests の設定を簡単にするための CMake マクロが含まれています。下記のように GTest を追加します。
find_package(ament_gtest) ament_add_gtest(some_test <test_sources>)
これは他のライブラリ(プロジェクトライブラリなど)に対してリンクできる通常のターゲットです。マクロには追加のパラメータがあります。
APPEND_ENV
:環境変数を追加します。たとえば、次のように呼び出して ament プレフィックスパスに追加できます。
find_package(ament_gtest REQUIRED) ament_add_gtest(some_test <test_sources> APPEND_ENV PATH=some/addtional/path/for/testing/resources)
APPEND_LIBRARY_DIRS
:実行時にリンカが検出できるようにライブラリを追加します。Windows ではPATH
、Linux ではLD_LIBRARY_PATH
のような環境変数を設定することでも実現できますが、この場合は呼び出しプラットフォームごとに異なる設定をしなければなりません。ENV
:環境変数を設定します(APPEND_ENV
と同じ構文)。TIMEOUT
:テストタイムアウトを秒単位で設定します。 GTestsのデフォルトは60秒です。SKIP_TEST
:このテストをスキップします(コンソール出力に "passed" と表示されます)。SKIP_LINKING_MAIN_LIBRARIES
:GTestにリンクしません。WORKING_DIRECTORY
:テスト用の作業ディレクトリを設定します。
それ以外のデフォルトの作業ディレクトリはCMAKE_SOURCE_DIR
で、これは最上位のCMakeLists.txt
のディレクトリとなります。
同様に、GMock を含む GTest を設定するための CMakeマクロがあります。
find_package(ament_gmock REQUIRED) ament_add_gmock(some_test <test_sources>)
ament_add_gtest
と同様に追加パラメータがあります。
ament の拡張
追加のマクロ/関数を ament_cmake
に登録し、それを拡張することができます。
ament への関数/マクロの追加
ament を拡張することはしばしば他のパッケージが使えるようにするための機能を追加したいという意図があると思われます。マクロをクライアントパッケージに提供する最善の方法は、それを ament に登録することです。
これは、${PROJECT_NAME}_CONFIG_EXTRAS
変数を追加することによって実行できます。これは、次の関数を呼び出した後、ament_package()
を呼ぶことで実現できます。
list(APPEND ${PROJECT_NAME}_CONFIG_EXTRAS path/to/file.cmake" other/pathto/file.cmake" )
あるいは、ファイルをament_package()
で直接追加することもできます。
ament_package(CONFIG_EXTRAS path/to/file.cmake other/pathto/file.cmake )
拡張ポイントへの追加
他のパッケージで使用できる機能を追加する単純な設定ファイル以外にも、ament 自体への拡張も可能です。その拡張機能は拡張ポイントを定義する関数で実行されるスクリプトです。 ament 拡張の最も一般的なユースケースは、おそらく rosidl メッセージジェネレータを登録することです。ジェネレータを書くとき、メッセージ/サービス定義パッケージのためのコードを修正することなしにジェネレータですべてのメッセージとサービスを通常生成するのが望ましいです。これは、ジェネレータをrosidl_generate_interfaces
の拡張として登録することで可能です。
例として、下記があります。
ament_register_extension( "rosidl_generate_interfaces" "rosidl_generator_cpp" "rosidl_generator_cpp_generate_interfaces.cmake")
これは、パッケージrosidl_generator_cpp
のマクロrosidl_generator_cpp_generate_interfaces.cmake
を、拡張ポイントrosidl_generate_interfaces
に登録するものです。拡張ポイントが実行されると、ここでスクリプトrosidl_generator_cpp_generate_interfaces.cmake
の実行がトリガーされます。もっと正確に言うと、これは関数rosidl_generate_interfaces
が実行されるたびにジェネレータを呼び出します。
ジェネレータ用のrosidl_generate_interfaces
以外の最も重要な拡張ポイントはament_package
です。これは単にament_package()
呼び出しでスクリプトを実行するだけです。この拡張ポイントは、リソースを登録するときに役立ちます(下記参照)。
ament_register_extension
は、必ず3つの引数をとる関数です。
extension_point
:拡張ポイントの名前(ほとんどの場合、これはament_package
またはrosidl_generate_interfaces
のいずれかになります)package_name
:CMake ファイルを含むパッケージの名前(すなわち、ファイルが書き込まれているプロジェクトのプロジェクト名)cmake_filename
:拡張ポイントが実行されたときに実行されるcmakeファイル
注意:ament_package
やrosidl_generate_interfaces
と同じようにカスタム拡張ポイントを定義することは可能ですが、これはほとんど必要ないでしょう。
拡張ポイントの追加
ごくまれに、ament への新しい拡張ポイントを定義したくなることもあるでしょう。
対応するマクロが呼び出されたときにすべての拡張が実行されるように、拡張ポイントをマクロ内に登録できます。以下のように行います。
- 登録したい拡張の名前(例えば
my_extension_point
)を定義して、ファイルとして保存してください。これは拡張ポイントを使うときにament_register_extension
マクロに渡される名前です。 - 拡張機能を実行するマクロ/関数では、次のように呼び出します。
ament_execute_extensions(my_extension_point)
ament 拡張は、拡張ポイントの名前を含む変数を定義し、それに実行するマクロを入れることによって機能します。 ament_execute_extensions
を呼び出すと、変数に定義されたスクリプトが次々に実行されます。
リソースを追加する
特にプラグインやプラグインを利用するパッケージを開発するときは、ある ROS パッケージから別の ROS パッケージにリソースを追加することが不可欠です(例:プラグイン)。例としては、pluginlib を使ったツール用のプラグインがあります。
これは、ament インデックス(「リソースインデックス」とも呼ばれる)を使用して実現できます。
ament インデックスの説明
設計の詳細については、こちらを参照してください。
原則として、ament インデックスはパッケージの install/share 内のフォルダに含まれています。さまざまな種類のリソースにちなんだ名称のサブフォルダが含まれています。サブフォルダ内では、上記リソースを提供する各パッケージは「マーカファイル」という名で参照されます。ファイルには、リソースを取得するために必要なあらゆるコンテンツが含まれます。(リソースのインストールディレクトリへの相対パスが例。それは単に空の場合もありますが。)
例として、RViz 用の表示プラグインを提供することを検討してください。pluginlib によって読み込まれるmy_rviz_displays
という名前のプロジェクトで RViz プラグインを提供するときは、pluginlib によってインストールおよび使用されるplugin_description.xml
ファイルを提供します。プラグインこれを実現するために、plugin_description.xml は次のようにして resource_index にリソースとして登録されます。
pluginlib_export_plugin_description_file(rviz_common plugins_description.xml)
colcon build
を実行すると、my_rviz_displays
ファイルを resource_index のサブフォルダrviz_common__pluginlib__plugin
にインストールします。 rviz_common 内の Pluginlib モジュールは、プラグインをエクスポートするパッケージについて、rviz_common__pluginlib__plugin
という名称の全フォルダから情報を収集することを認識します。 pluginlib モジュール用のマーカーファイルには、plugins_description.xml
ファイルへのインストールフォルダへの相対パス(およびマーカファイル名としてのライブラリの名前)が含まれています。この情報を使って、pluginlib はライブラリをロードし、どのプラグインをplugin_description.xml
ファイルからロードするかを知ることができます。
2つ目の例として、RViz プラグインがあなた自身のカスタムメッシュを使うようにする可能性を考えてください。メッシュは起動時にロードされるため、プラグインの所有者はそれを処理する必要はありませんが、これは RViz がメッシュについて知っている必要があることを意味します。これを達成するための関数を RViz は備えています。
register_rviz_ogre_media_exports(DIRECTORIES <my_dirs>)
これは、ディレクトリを agre_media リソースとして ament インデックスに登録します。つまり、関数を呼び出すプロジェクト名のファイルをrviz_ogre_media_exports
というサブフォルダーにインストールします。このファイルには、マクロにリストされているディレクトリへのインストールフォルダへの相対パスが含まれています。RViz の起動時、rviz_ogre_media_exports
という名前のすべてのフォルダを検索し、指定された全フォルダにリソースをロードできるようになりました。これらの検索はament_index_cpp
(または Python パッケージの場合はament_index_py
)を使って行われます。
以下のセクションでは、カスタマイズしたリソースを ament index に追加し、そうするためのベストプラクティスを提供する方法を探ります。
ament インデックスへの問い合わせ
必要ならば、CMake を介して ament インデックスに対してリソースの問い合わせが可能です。これについては、3 つの機能があります。
ament_index_has_resource
:以下のパラメータで存在する場合、リソースへのプレフィックスパスを取得します。var
:出力パラメータ:リソースが存在しない場合はこの変数にFALSEを、存在する場合はリソースへのプレフィックスパスを設定します。resource_type
:リソースの種類(例:rviz_common__pluginlib__plugin
)
resource_name
:通常resource_type 型のリソースを追加したパッケージの名前に相当するリソースの名前(例:rviz_default_plugins
)ament_index_get_resource
:特定のリソースの内容、すなわち ament インデックス内のマーカファイルの内容を取得する。var
:出力パラメータ:リソースマーカファイルが存在する場合はその内容が代入されます。resource_type
:リソースの種類(例:rviz_common__pluginlib__plugin
)
resource_name
:通常resource_type型のリソースを追加したパッケージの名前に相当するリソースの名前(例:rviz_default_plugins
)PREFIX_PATH
:検索するプレフィックスパス(通常、デフォルトのament_index_get_prefix_path()
で十分です)。
リソースが存在しない場合、ament_index_get_resource
はエラーをスローするので、ament_index_has_resource
を使用して確認する必要があるかもしれません。
ament_index_get_resources
:インデックスから特定の種類のリソースを登録したすべてのパッケージを取得します。- var:出力パラメータ:resource_typeのリソースを登録した全てのパッケージ名のリストが代入されます。
resource_type
:リソースの種類(例:rviz_common__pluginlib__plugin
)
PREFIX_PATH
:検索するプレフィックスパス(通常、デフォルトの`ament_index_get_prefix_path() で十分です)。
ament インデックスへの追加
リソースを定義するには、2 ビットの情報が必要です。
- ユニークなリソース名
- マーカファイルのレイアウト。これは何でもかまいませんし、空にすることもできます(例えば ROS 2 パッケージをマークする“package”リソースに当てはまります)。
RVizメッシュリソースの場合、対応する選択肢は次のとおりです。
- リソースの名前として
rviz_ogre_media_exports
、 - リソースを含むすべてのフォルダへの相対パスをインストールします。これにより、パッケージ内の対応するリソースを使用するためのロジックを記述できるようになります。
パッケージのリソース登録を容易にするには、さらに、pluginlib関数やrviz_ogre_media_exports
などのマクロや関数を用意する必要があります。
リソースを登録するには、ament関数ament_index_register_resource
を使用します。これによりマーカファイルが作成され、resource_index
にインストールされます。例として、rviz_ogre_media_exports
の対応する呼び出しは以下のとおりです。
ament_index_register_resource(rviz_ogre_media_exports CONTENT ${OGRE_MEDIA_RESOURCE_FILE})
これにより、${PROJECT_NAME}
のような名前のファイルが、変数${OGRE_MEDIA_RESOURCE_FILE}
で指定された内容で resource_index の中にあるrviz_ogre_media_exports
フォルダにインストールされます。マクロには色々な便利パラメータが用意されています。
- 最初の(名前なし)パラメータはリソースの名前です。これは、resource_index 内のフォルダの名前になります。
CONTENT
:文字列としてのマーカファイルの内容。これは相対パスのリストなどです。CONTENT
をCONTENT_FILE
と一緒に使用することはできません。CONTENT_FILE
:マーカファイル作成のために使用されるファイルへのパス。ファイルはプレーンファイルでも、configure_file()
で展開されたテンプレートファイルでも、どちらでも構いません。CONTENT_FILE
をCONTENT
と一緒に使用することはできません。PACKAGE_NAME
:リソースをエクスポートしているパッケージ/ライブラリの名前。マーカファイルの名前になります。デフォルトは${PROJECT_NAME}
です。AMENT_INDEX_BINARY_DIR
:生成された ament インデックスの基底パス。本当に必要な場合以外は、常にデフォルトの${CMAKE_BINARY_DIR}/ament_cmake_index
を使用してください。SKIP_INSTALL
:マーカファイルのインストールをスキップします。
パッケージごとに存在するマーカファイルは1つだけなので、cmake 関数/マクロが同じプロジェクトによって 2 回呼び出されると、通常は問題になります。ただし、大規模プロジェクトでは、リソースを登録する呼び出しを分割するのが最善の方法です。
したがって、register_rviz_ogre_media_exports.cmake
などのリソースを登録するマクロにいくつかの変数のみを設定させることがベストプラクティスとなります。 ament_index_register_resource
の実際の呼び出しは、ament_package
へのament 拡張内で追加できます。プロジェクトごとにament_package
を呼び出すのは 1 回限りでなければならないため、リソースが登録される場所は常に1つのみとなります。 rviz_ogre_media_exports
の場合、これは次のような方針となります。
- マクロ
register_rviz_ogre_media_exports
はフォルダのリストを受け取り、それらをOGRE_MEDIA_RESOURCE_FILE
という変数に追加します。
${OGRE_MEDIA_RESOURCE_FILE}
が空でない場合、register_rviz_ogre_media_exports_hook
という別のマクロがament_index_register_resource
を呼び出します。
register_rviz_ogre_media_exports_hook.cmake
は、呼び出しによって3番目のファイル register_rviz_ogre_media_exports_hook-extras.cmake
に ament
拡張として登録されます。
ament_register_extension("ament_package" "rviz_rendering" "register_rviz_ogre_media_exports_hook.cmake")
register_rviz_ogre_media_exports.cmake
およびregister_rviz_ogre_media_exports_hook-extra.cmake
は、ament_package()
でCONFIG_EXTRA
として登録されます。