ament_cmake_autoを用いたビルド方法

# はじめに
　今回の記事では、ROS 2においてament_cmake_autoを用いてCMakeLists.txtを記述する方法について記載していきます。このament_cmake_autoを用いずとも、ビルドは可能ですが、ament_cmake_autoを用いたほうが記述する量が削減できて楽だと思いますので、参考になればと思います。

:::note info
この記事は[ROSに関する投稿](https://qiita.com/kccs_yoshiteru-imamura/items/ef418e9beb508ac52c5d)の一部です。
目次は[こちら](https://qiita.com/kccs_yoshiteru-imamura/items/ef418e9beb508ac52c5d#%E7%9B%AE%E6%AC%A1)
:::

### 前提条件
　今回の記事は、以下の環境で動かすことを前提に記載しています。
|            |     条件     |
|:-----------|:-------------|
| OS         | Ubuntu 22.04 |
| ROS        | ROS 2 humble |

# 準備
　ament_cmake_autoの動作確認をするにあたって、[以前の記事](https://qiita.com/kccs_kazushi-uchida/items/70bb07e688953cf01e82)で作成したPub&Sub通信のコードを流用します。今回新しく、pub_sub_cpp_02というパッケージを作成し、.cppファイルと.hppファイルをコピーしておきます。コピー後、そのままのソースコードではエラーがでるため、ヘッダファイルの読み込み先等をパッケージ名に合わせて修正します。

### パッケージ作成
``` shell
cd ~/ros2_ws/src
ros2 pkg create --build-type ament_cmake pub_sub_cpp_02
```

### ファイルコピー
``` shell
cp ~/ros2_ws/src/pub_sub_cpp_01/src/publisher.cpp ~/ros2_ws/src/pub_sub_cpp_02/src/publisher.cpp
cp ~/ros2_ws/src/pub_sub_cpp_01/src/subscriber.cpp ~/ros2_ws/src/pub_sub_cpp_02/src/subscriber.cpp
cp ~/ros2_ws/src/pub_sub_cpp_01/include/pub_sub_cpp_01/publisher.hpp ~/ros2_ws/src/pub_sub_cpp_02/include/pub_sub_cpp_02/publisher.hpp
cp ~/ros2_ws/src/pub_sub_cpp_01/include/pub_sub_cpp_01/subscriber.hpp ~/ros2_ws/src/pub_sub_cpp_02/include/pub_sub_cpp_02/subscriber.hpp
```

### package.xmlの編集
package.xmlに以下を追記します。
``` xml:~/ros2_ws/src/pub_sub_cpp_02/package.xml
<build_depend>rclcpp</build_depend>
<build_depend>rclcpp_components</build_depend>
<build_depend>std_msgs</build_depend>

<exec_depend>launch_ros</exec_depend>
<exec_depend>launch_xml</exec_depend>
<exec_depend>rclcpp</exec_depend>
<exec_depend>rclcpp_components</exec_depend>
<exec_depend>std_msgs</exec_depend>
<exec_depend>ros2launch</exec_depend>
```

### CMakeLists.txtの編集
CMakeLists.txtを以下の様に編集します。
``` cmake:~/ros2_ws/src/pub_sub_cpp_02/CMakeLists.txt
cmake_minimum_required(VERSION 3.8)
project(pub_sub_cpp_02)

if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
  add_compile_options(-Wall -Wextra -Wpedantic)
endif()

find_package(ament_cmake_auto REQUIRED)

ament_auto_find_build_dependencies()

ament_auto_add_library(${PROJECT_NAME} SHARED 
  src/publisher.cpp
  src/subscriber.cpp
)

rclcpp_components_register_node(${PROJECT_NAME}
  PLUGIN "kccs_pub_sub_cpp_02::Publisher"
  EXECUTABLE publisher
)
rclcpp_components_register_node(${PROJECT_NAME}
  PLUGIN "kccs_pub_sub_cpp_02::Subscriber"
  EXECUTABLE subscriber
)

install(DIRECTORY launch
  DESTINATION share/${PROJECT_NAME}
)

ament_auto_package()
```

### launchディレクトリの作成
```
cd ~/ros2_ws/src/pub_sub_cpp_02
mkdir launch
```

### ビルド
```
cd ~/ros2_ws
colcon build
```

# 実行と実行結果
 省略します。[ROS 2においてC++を用いたPub&Sub通信を行う方法(コンポーネントを使用)](https://qiita.com/kccs_kazushi-uchida/items/70bb07e688953cf01e82#%E5%AE%9F%E8%A1%8C%E7%B5%90%E6%9E%9C)と同じ結果が得られます。

# 解説
### find_package(ament_cmake_auto REQUIRED)
　ament_cmake_autoのfind_packageはament_cmake_autoを使う上で必要なため記述します。pub_sub_cpp_01ではament_cmake、rclcpp、rclcpp_components、std_msgs等の必要なものを全て手動でfind_packageしていましたが、後述するament_auto_find_build_dependencies()でpackage.xmlから自動で見つけるため記述を簡略化できます。

### ament_auto_find_build_dependencies()
　package.xmlから依存を読み取ってfind_packageを行います。

### ament_auto_add_executable()
　以下の物をまとめて、実行ファイルの生成を行います。
add_executable()
target_include_directories()
target_link_libraries()
ament_target_dependencies()

### ament_auto_add_library()
　以下の物をまとめて、ライブラリの生成を行います。
add_library()
target_include_directories()
target_link_libraries()
ament_target_dependencies()

### ament_auto_package()
　以下の物をまとめて、ライブラリのビルドを行います。
ament_export_dependencies()
ament_export_include_directories()
ament_export_libraries()
ament_package()

### その他
　上記以外にも、以下の様なテスト関連の物も用意されています。
ament_auto_add_gmock()
ament_auto_add_gtest()
ament_auto_find_test_dependencies()

# おわりに
　今回の記事では、ament_cmake_autoについて記載しました。次回は、ROSとROS 2でのTimeの仕様の違いについて記載します。興味がある方は是非ご覧ください。

# 参考資料
https://github.com/ament/ament_cmake/tree/master/ament_cmake_auto/cmake