diff --git a/CMakeLists.txt b/CMakeLists.txt
index fa2997a8..960b3b8f 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -38,8 +38,13 @@ install(
DIRECTORY config DESTINATION . USE_SOURCE_PERMISSIONS
)
+install(
+ DIRECTORY patches DESTINATION share/${PROJECT_NAME} USE_SOURCE_PERMISSIONS
+)
+
install(
PROGRAMS
+ scripts/apply_patches.sh
scripts/create_ws.sh
scripts/create_agent_ws.sh
scripts/create_firmware_ws.sh
diff --git a/config/host/generic/client_host_packages.repos b/config/host/generic/client_host_packages.repos
index 55b3191a..047018f5 100644
--- a/config/host/generic/client_host_packages.repos
+++ b/config/host/generic/client_host_packages.repos
@@ -25,7 +25,7 @@ repositories:
uros/rosidl_typesupport_microxrcedds:
type: git
url: https://github.com/micro-ROS/rosidl_typesupport_microxrcedds.git
- version: jazzy
+ version: jazzy_fix_interfaces
uros/micro-ROS-demos:
type: git
url: https://github.com/micro-ROS/micro-ROS-demos.git
diff --git a/patches/ros2-core-generators-to-default-generators.patch b/patches/ros2-core-generators-to-default-generators.patch
new file mode 100644
index 00000000..ff071c22
--- /dev/null
+++ b/patches/ros2-core-generators-to-default-generators.patch
@@ -0,0 +1,43 @@
+diff --git a/ros2/rcl_interfaces/action_msgs/CMakeLists.txt b/ros2/rcl_interfaces/action_msgs/CMakeLists.txt
+index b5f34b9..65db062 100644
+--- a/ros2/rcl_interfaces/action_msgs/CMakeLists.txt
++++ b/ros2/rcl_interfaces/action_msgs/CMakeLists.txt
+@@ -15,7 +15,7 @@ find_package(ament_cmake REQUIRED)
+ find_package(builtin_interfaces REQUIRED)
+ # Depend on "core" generators instead of "default" generators
+ # because ROS actions depend on this package
+-find_package(rosidl_core_generators REQUIRED)
++find_package(rosidl_default_generators REQUIRED)
+ find_package(unique_identifier_msgs REQUIRED)
+
+ set(msg_files
+diff --git a/ros2/rcl_interfaces/builtin_interfaces/CMakeLists.txt b/ros2/rcl_interfaces/builtin_interfaces/CMakeLists.txt
+index 282d38e..67c1339 100644
+--- a/ros2/rcl_interfaces/builtin_interfaces/CMakeLists.txt
++++ b/ros2/rcl_interfaces/builtin_interfaces/CMakeLists.txt
+@@ -14,7 +14,7 @@ endif()
+ find_package(ament_cmake REQUIRED)
+ # Depend on "core" generators instead of "default" generators
+ # because ROS actions depend on this package
+-find_package(rosidl_core_generators REQUIRED)
++find_package(rosidl_default_generators REQUIRED)
+diff --git a/ros2/rcl_interfaces/type_description_interfaces/CMakeLists.txt b/ros2/rcl_interfaces/type_description_interfaces/CMakeLists.txt
+index c3ac72b..4374456 100644
+--- a/ros2/rcl_interfaces/type_description_interfaces/CMakeLists.txt
++++ b/ros2/rcl_interfaces/type_description_interfaces/CMakeLists.txt
+@@ -13,7 +13,7 @@ endif()
+ find_package(ament_cmake REQUIRED)
+ # Depend on "core" generators instead of "default" generators
+ # because other generators depend on this.
+-find_package(rosidl_core_generators REQUIRED)
++find_package(rosidl_default_generators REQUIRED)
+diff --git a/ros2/unique_identifier_msgs/CMakeLists.txt b/ros2/unique_identifier_msgs/CMakeLists.txt
+index 382b8ec..00498c3 100644
+--- a/ros2/unique_identifier_msgs/CMakeLists.txt
++++ b/ros2/unique_identifier_msgs/CMakeLists.txt
+@@ -15,7 +15,7 @@ endif()
+ find_package(ament_cmake REQUIRED)
+ # Depend on "core" generators instead of "default" generators
+ # because ROS actions depend on this package
+-find_package(rosidl_core_generators REQUIRED)
++find_package(rosidl_default_generators REQUIRED)
diff --git a/patches/ros2-example-interfaces-action-deps.patch b/patches/ros2-example-interfaces-action-deps.patch
new file mode 100644
index 00000000..608b7c19
--- /dev/null
+++ b/patches/ros2-example-interfaces-action-deps.patch
@@ -0,0 +1,38 @@
+diff --git a/ros2/example_interfaces/CMakeLists.txt b/ros2/example_interfaces/CMakeLists.txt
+index e7dae2c..033eda0 100644
+--- a/ros2/example_interfaces/CMakeLists.txt
++++ b/ros2/example_interfaces/CMakeLists.txt
+@@ -12,7 +12,10 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ endif()
+
+ find_package(ament_cmake REQUIRED)
++find_package(action_msgs REQUIRED)
++find_package(builtin_interfaces REQUIRED)
+ find_package(rosidl_default_generators REQUIRED)
++find_package(unique_identifier_msgs REQUIRED)
+
+ rosidl_generate_interfaces(${PROJECT_NAME}
+ "action/Fibonacci.action"
+@@ -48,6 +51,7 @@ rosidl_generate_interfaces(${PROJECT_NAME}
+ "srv/AddTwoInts.srv"
+ "srv/SetBool.srv"
+ "srv/Trigger.srv"
++ DEPENDENCIES builtin_interfaces unique_identifier_msgs
+ )
+
+ install(FILES mapping_rules.yaml DESTINATION share/${PROJECT_NAME})
+diff --git a/ros2/example_interfaces/package.xml b/ros2/example_interfaces/package.xml
+index f127a53..31f8653 100644
+--- a/ros2/example_interfaces/package.xml
++++ b/ros2/example_interfaces/package.xml
+@@ -17,6 +17,10 @@
+
+ rosidl_default_generators
+
++ action_msgs
++ builtin_interfaces
++ unique_identifier_msgs
++
+ rosidl_default_runtime
+
+ rosidl_interface_packages
diff --git a/patches/ros2-test-msgs-action-deps.patch b/patches/ros2-test-msgs-action-deps.patch
new file mode 100644
index 00000000..449778e6
--- /dev/null
+++ b/patches/ros2-test-msgs-action-deps.patch
@@ -0,0 +1,40 @@
+diff --git a/ros2/rcl_interfaces/test_msgs/CMakeLists.txt b/ros2/rcl_interfaces/test_msgs/CMakeLists.txt
+index 433833b..b2472b8 100644
+--- a/ros2/rcl_interfaces/test_msgs/CMakeLists.txt
++++ b/ros2/rcl_interfaces/test_msgs/CMakeLists.txt
+@@ -17,9 +17,11 @@ if(CMAKE_COMPILER_IS_GNUCXX OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")
+ endif()
+
+ find_package(ament_cmake REQUIRED)
++find_package(action_msgs REQUIRED)
+ find_package(builtin_interfaces REQUIRED)
+ find_package(rosidl_default_generators REQUIRED)
+ find_package(test_interface_files REQUIRED)
++find_package(unique_identifier_msgs REQUIRED)
+
+ # TODO(sloretz) Change to test_msgs_interfaces when ros2/rosidl_typesupport#120 is fixed
+ rosidl_generate_interfaces(test_msgs
+@@ -29,7 +31,7 @@ rosidl_generate_interfaces(test_msgs
+ ${test_interface_files_IDL_FILES}
+ "msg/Builtins.msg"
+ "action/NestedMessage.action"
+- DEPENDENCIES builtin_interfaces
++ DEPENDENCIES builtin_interfaces unique_identifier_msgs
+ ADD_LINTER_TESTS
+ )
+
+diff --git a/ros2/rcl_interfaces/test_msgs/package.xml b/ros2/rcl_interfaces/test_msgs/package.xml
+index 67fe631..0f76490 100644
+--- a/ros2/rcl_interfaces/test_msgs/package.xml
++++ b/ros2/rcl_interfaces/test_msgs/package.xml
+@@ -17,8 +17,10 @@
+
+ rosidl_default_generators
+
++ action_msgs
+ builtin_interfaces
+ test_interface_files
++ unique_identifier_msgs
+
+ builtin_interfaces
+ rosidl_default_runtime
diff --git a/scripts/apply_patches.sh b/scripts/apply_patches.sh
new file mode 100755
index 00000000..c40f7708
--- /dev/null
+++ b/scripts/apply_patches.sh
@@ -0,0 +1,88 @@
+#!/bin/bash
+
+set -e
+set -o nounset
+set -o pipefail
+
+if [ $# -ne 1 ]; then
+ echo "Syntax: $0 "
+ exit 255
+fi
+
+WORKSPACE_DIR=$1
+SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd)
+PATCH_DIR=""
+
+for candidate in \
+ "${SCRIPT_DIR}/../../share/micro_ros_setup/patches" \
+ "${SCRIPT_DIR}/../share/micro_ros_setup/patches" \
+ "${SCRIPT_DIR}/../patches"
+do
+ if [ -d "${candidate}" ]; then
+ PATCH_DIR="${candidate}"
+ break
+ fi
+done
+
+if [ ! -d "${WORKSPACE_DIR}" ]; then
+ echo "Error: Workspace '${WORKSPACE_DIR}' does not exist"
+ exit 255
+fi
+
+if [ -z "${PATCH_DIR}" ]; then
+ echo "Error: Patch directory not found (searched: ${SCRIPT_DIR}/../../share/micro_ros_setup/patches, ${SCRIPT_DIR}/../share/micro_ros_setup/patches, ${SCRIPT_DIR}/../patches)"
+ exit 255
+fi
+
+patch_targets_workspace() {
+ local patch_file=$1
+ local candidate_path=""
+ local repo_path=""
+ local saw_diff=0
+
+ while read -r _ _ old_path new_path; do
+ saw_diff=1
+ old_path=${old_path#a/}
+ new_path=${new_path#b/}
+
+ for candidate_path in "${old_path}" "${new_path}"; do
+ repo_path=$(printf '%s\n' "${candidate_path}" | cut -d/ -f1-2)
+ if [ -n "${repo_path}" ] && [ -d "${WORKSPACE_DIR}/${repo_path}" ]; then
+ return 0
+ fi
+ done
+ done < <(grep '^diff --git a/' "${patch_file}" || true)
+
+ if [ "${saw_diff}" -eq 0 ]; then
+ return 0
+ fi
+
+ return 1
+}
+
+apply_patch_file() {
+ local patch_file=$1
+
+ if ! patch_targets_workspace "${patch_file}"; then
+ echo "Skipping $(basename "${patch_file}") (workspace does not contain the patched repository)"
+ return
+ fi
+
+ if patch --batch --forward -p1 -d "${WORKSPACE_DIR}" --dry-run < "${patch_file}" >/dev/null 2>&1; then
+ echo "Applying $(basename "${patch_file}")"
+ patch --batch --forward -p1 -d "${WORKSPACE_DIR}" < "${patch_file}" >/dev/null
+ return
+ fi
+
+ if patch --batch --reverse -p1 -d "${WORKSPACE_DIR}" --dry-run < "${patch_file}" >/dev/null 2>&1; then
+ echo "Skipping $(basename "${patch_file}") (already applied)"
+ return
+ fi
+
+ echo "Warning: Failed to apply $(basename "${patch_file}") in ${WORKSPACE_DIR}" >&2
+}
+
+shopt -s nullglob
+for patch_file in "${PATCH_DIR}"/*.patch; do
+ apply_patch_file "${patch_file}"
+done
diff --git a/scripts/create_ws.sh b/scripts/create_ws.sh
index 1ba75e96..910da277 100755
--- a/scripts/create_ws.sh
+++ b/scripts/create_ws.sh
@@ -44,6 +44,6 @@ curl -s https://raw.githubusercontent.com/ros2/ros2/jazzy/ros2.repos |\
ros2 run micro_ros_setup yaml_filter.py ${PACKAGES} > ros2.repos
vcs import --input ros2.repos --skip-existing
vcs import --input $REPOS --skip-existing
+bash "$(dirname "$0")/apply_patches.sh" "$(pwd)"
popd >/dev/null
-