diff --git a/rosidl_cmake/cmake/rosidl_find_package_idl.cmake b/rosidl_cmake/cmake/rosidl_find_package_idl.cmake
new file mode 100644
index 000000000..b084afa25
--- /dev/null
+++ b/rosidl_cmake/cmake/rosidl_find_package_idl.cmake
@@ -0,0 +1,43 @@
+# Copyright 2023 Open Source Robotics Foundation, Inc.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Get the absolute path of an IDL file stored in a package's share
+# directory, checking if the package's find module set a GNUInstallDirs
+# pkgname_DATADIR variable pointing to a separate location from the
+# default pkgname_DIR.
+#
+# :param var: A name of a variable to store the idl file absolute path.
+# :param pkg_name: Name of the package, assumed to have already been
+# find_package'd.
+# :type pkg_name: string
+# :param idl_name: The filename of the idl file to look for.
+# :type idl_name: string
+#
+# @public
+#
+function(rosidl_find_package_idl var pkg_name idl_file)
+ set(_candidates
+ "${${pkg_name}_DATADIR}/${idl_file}"
+ "${${pkg_name}_DIR}/../${idl_file}"
+ )
+ foreach(_try ${_candidates})
+ if(EXISTS "${_try}")
+ normalize_path(_norm "${_try}")
+ set("${var}" "${_norm}" PARENT_SCOPE)
+ return()
+ endif()
+ endforeach()
+ message(FATAL_ERROR "Unable to find ${idl_file} in any of ${_candidates} for ${pkg_name}.")
+ set("${var}" "-NOTFOUND" PARENT_SCOPE)
+endfunction()
diff --git a/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake b/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake
index edf14de07..f491ef7ea 100644
--- a/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake
+++ b/rosidl_cmake/cmake/rosidl_generate_interfaces.cmake
@@ -193,8 +193,7 @@ macro(rosidl_generate_interfaces target)
"'${_dep}' has not been found before using find_package()")
endif()
foreach(_idl_file ${${_dep}_IDL_FILES})
- set(_abs_idl_file "${${_dep}_DIR}/../${_idl_file}")
- normalize_path(_abs_idl_file "${_abs_idl_file}")
+ rosidl_find_package_idl(_abs_idl_file "${_dep}" "${_idl_file}")
list(APPEND _dep_files "${_abs_idl_file}")
endforeach()
endforeach()
diff --git a/rosidl_cmake/rosidl_cmake-extras.cmake b/rosidl_cmake/rosidl_cmake-extras.cmake
index 6b82c0887..1ebda4e89 100644
--- a/rosidl_cmake/rosidl_cmake-extras.cmake
+++ b/rosidl_cmake/rosidl_cmake-extras.cmake
@@ -58,3 +58,4 @@ endmacro()
include("${rosidl_cmake_DIR}/rosidl_export_typesupport_libraries.cmake")
include("${rosidl_cmake_DIR}/rosidl_export_typesupport_targets.cmake")
+include("${rosidl_cmake_DIR}/rosidl_find_package_idl.cmake")
diff --git a/rosidl_generator_c/cmake/rosidl_generator_c_generate_interfaces.cmake b/rosidl_generator_c/cmake/rosidl_generator_c_generate_interfaces.cmake
index 85706d0a4..10cae3297 100644
--- a/rosidl_generator_c/cmake/rosidl_generator_c_generate_interfaces.cmake
+++ b/rosidl_generator_c/cmake/rosidl_generator_c_generate_interfaces.cmake
@@ -13,6 +13,7 @@
# limitations under the License.
find_package(rcutils REQUIRED)
+find_package(rosidl_cmake REQUIRED)
find_package(rosidl_runtime_c REQUIRED)
find_package(rosidl_typesupport_interface REQUIRED)
@@ -43,8 +44,7 @@ set(_dependency_files "")
set(_dependencies "")
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
foreach(_idl_file ${${_pkg_name}_IDL_FILES})
- set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
- normalize_path(_abs_idl_file "${_abs_idl_file}")
+ rosidl_find_package_idl(_abs_idl_file "${_pkg_name}" "${_idl_file}")
list(APPEND _dependency_files "${_abs_idl_file}")
list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}")
endforeach()
diff --git a/rosidl_generator_c/package.xml b/rosidl_generator_c/package.xml
index e2ffa9a0d..81bfb0d3b 100644
--- a/rosidl_generator_c/package.xml
+++ b/rosidl_generator_c/package.xml
@@ -24,6 +24,7 @@
python3
rosidl_pycommon
+ rosidl_cmake
rosidl_generator_type_description
rosidl_typesupport_interface
rcutils
diff --git a/rosidl_generator_cpp/cmake/rosidl_generator_cpp_generate_interfaces.cmake b/rosidl_generator_cpp/cmake/rosidl_generator_cpp_generate_interfaces.cmake
index 1f7159067..7b91c2559 100644
--- a/rosidl_generator_cpp/cmake/rosidl_generator_cpp_generate_interfaces.cmake
+++ b/rosidl_generator_cpp/cmake/rosidl_generator_cpp_generate_interfaces.cmake
@@ -12,6 +12,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
+find_package(rosidl_cmake REQUIRED)
find_package(rosidl_runtime_cpp REQUIRED)
set(_output_path
@@ -47,8 +48,7 @@ set(_dependency_files "")
set(_dependencies "")
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
foreach(_idl_file ${${_pkg_name}_IDL_FILES})
- set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
- normalize_path(_abs_idl_file "${_abs_idl_file}")
+ rosidl_find_package_idl(_abs_idl_file "${_pkg_name}" "${_idl_file}")
list(APPEND _dependency_files "${_abs_idl_file}")
list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}")
endforeach()
diff --git a/rosidl_generator_cpp/package.xml b/rosidl_generator_cpp/package.xml
index a39e1b837..88d91ba25 100644
--- a/rosidl_generator_cpp/package.xml
+++ b/rosidl_generator_cpp/package.xml
@@ -22,6 +22,7 @@
python3
rosidl_pycommon
+ rosidl_cmake
rosidl_generator_c
rosidl_runtime_cpp
diff --git a/rosidl_typesupport_introspection_c/cmake/rosidl_typesupport_introspection_c_generate_interfaces.cmake b/rosidl_typesupport_introspection_c/cmake/rosidl_typesupport_introspection_c_generate_interfaces.cmake
index 3d686c07e..b5cd93b25 100644
--- a/rosidl_typesupport_introspection_c/cmake/rosidl_typesupport_introspection_c_generate_interfaces.cmake
+++ b/rosidl_typesupport_introspection_c/cmake/rosidl_typesupport_introspection_c_generate_interfaces.cmake
@@ -18,6 +18,7 @@ if(NOT TARGET ${rosidl_generate_interfaces_TARGET}__rosidl_generator_c)
"'rosidl_typesupport_introspection_c' extension.")
endif()
+find_package(rosidl_cmake REQUIRED)
find_package(rosidl_runtime_c REQUIRED)
find_package(rosidl_typesupport_interface REQUIRED)
find_package(rosidl_typesupport_introspection_c REQUIRED)
@@ -41,8 +42,7 @@ set(_dependency_files "")
set(_dependencies "")
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
foreach(_idl_file ${${_pkg_name}_IDL_FILES})
- set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
- normalize_path(_abs_idl_file "${_abs_idl_file}")
+ rosidl_find_package_idl(_abs_idl_file "${_pkg_name}" "${_idl_file}")
list(APPEND _dependency_files "${_abs_idl_file}")
list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}")
endforeach()
diff --git a/rosidl_typesupport_introspection_c/package.xml b/rosidl_typesupport_introspection_c/package.xml
index 784c59945..154fc58bf 100644
--- a/rosidl_typesupport_introspection_c/package.xml
+++ b/rosidl_typesupport_introspection_c/package.xml
@@ -25,6 +25,7 @@
rosidl_generator_c
rosidl_pycommon
+ rosidl_cmake
rosidl_runtime_c
rosidl_typesupport_interface
diff --git a/rosidl_typesupport_introspection_cpp/cmake/rosidl_typesupport_introspection_cpp_generate_interfaces.cmake b/rosidl_typesupport_introspection_cpp/cmake/rosidl_typesupport_introspection_cpp_generate_interfaces.cmake
index c44a136eb..60c7cef7a 100644
--- a/rosidl_typesupport_introspection_cpp/cmake/rosidl_typesupport_introspection_cpp_generate_interfaces.cmake
+++ b/rosidl_typesupport_introspection_cpp/cmake/rosidl_typesupport_introspection_cpp_generate_interfaces.cmake
@@ -18,6 +18,7 @@ if(NOT TARGET ${rosidl_generate_interfaces_TARGET}__rosidl_generator_cpp)
"'rosidl_typesupport_introspection_cpp' extension.")
endif()
+find_package(rosidl_cmake REQUIRED)
find_package(rosidl_runtime_c REQUIRED)
find_package(rosidl_typesupport_interface REQUIRED)
find_package(rosidl_typesupport_introspection_cpp REQUIRED)
@@ -41,8 +42,7 @@ set(_dependency_files "")
set(_dependencies "")
foreach(_pkg_name ${rosidl_generate_interfaces_DEPENDENCY_PACKAGE_NAMES})
foreach(_idl_file ${${_pkg_name}_IDL_FILES})
- set(_abs_idl_file "${${_pkg_name}_DIR}/../${_idl_file}")
- normalize_path(_abs_idl_file "${_abs_idl_file}")
+ rosidl_find_package_idl(_abs_idl_file "${_pkg_name}" "${_idl_file}")
list(APPEND _dependency_files "${_abs_idl_file}")
list(APPEND _dependencies "${_pkg_name}:${_abs_idl_file}")
endforeach()
diff --git a/rosidl_typesupport_introspection_cpp/package.xml b/rosidl_typesupport_introspection_cpp/package.xml
index fd3f3be32..2bf76fea2 100644
--- a/rosidl_typesupport_introspection_cpp/package.xml
+++ b/rosidl_typesupport_introspection_cpp/package.xml
@@ -26,6 +26,7 @@
rosidl_generator_cpp
rosidl_pycommon
+ rosidl_cmake
rosidl_runtime_c
rosidl_runtime_cpp