ament_cmake用户文档
[需手动修复的语法]ament _ cmake是ROS 2中基于CMake的包的构建系统 (特别是,它将用于大多数 (如果不是全部的话) C/cmake项目)。它是一组增强CMake并为包作者添加便利功能的脚本。了解 CMake will be very helpful, an official tutorial can be found here 的基本知识。 [待校准@5760]
目录
基础知识
可以在命令行上使用 ros2 pkg create <package_name>
生成基本的CMake大纲。然后将基本构建信息收集在两个文件中: package.xml
和 CMakeLists.txt
。 package.xml
必须包含所有依赖项和一些元数据,以允许colcon为您的包找到正确的构建顺序,在CI中安装所需的依赖项,并为 bloom
版本提供信息。 CMakeLists.txt
包含构建和打包可执行文件和库的命令,并将成为本文档的主要重点。 [待校准@5763]
基本项目大纲 [待校准@5764]
基本轮廓 CMakeLists.txt
的ament包包含: [待校准@5765]
cmake_minimum_required(VERSION 3.5)
project(my_project)
ament_package()
[需手动修复的语法] project
的参数将是包装名称,并且必须与 package.xml
中的包装名称相同。 [待校准@5766]
项目设置由 ament_package()
完成,每个包必须进行一次调用。 ament_package()
安装 package.xml
,将包注册到ament索引,并为CMake安装配置 (可能还有目标) 文件,以便其他使用 find_package
的包可以找到它。因为 ament_package()
从 CMakeLists.txt
收集了很多信息,所以它应该是你 CMakeLists.txt
的最后一次调用。虽然可调用的 ament_package()
通过调用的 install
功能复制文件和目录,简单只是保持 ament_package()
最后调用。 [待校准@5767]
[需手动修复的语法]``ament_package`` can被给予额外的论据: [待校准@5768]
包装的客户应该可以得到``CONFIG_EXTRAS``: a list of CMake files (
.cmake
or.cmake.in
templates expanded byconfigure_file()
)。有关何时使用这些参数的示例,请参阅 “添加源文件 _. For more information on how to use template files, see `the official documentation ” 中的讨论。 [待校准@5769]后来包括``CONFIG_EXTRAS_POST``: same as
CONFIG_EXTRAS
, but the order in which the files are added differs. WhileCONFIG_EXTRAS
files are included before the files generated for theament_export_*
calls the files fromCONFIG_EXTRAS_POST
are。 [待校准@5770]
除了添加到 ament_package
,您还可以添加到变量 “${PROJECT_NAME}_ CONFIG _ EXTRAS `` and `` ${PROJECT_NAME}_ CONFIG_EXTRAS_POST”,具有相同的效果。唯一的区别是文件的添加顺序,总顺序如下: [待校准@5771]
files added by
CONFIG_EXTRAS
通过附加到 “${PROJECT_NAME}_ CONFIG_EXTRAS” 来添加的文件 [待校准@5773]
通过附加到 “${PROJECT_NAME}_ CONFIG_EXTRAS_POST” 来添加的文件 [待校准@5774]
files added by
CONFIG_EXTRAS_POST
添加文件和标题 [待校准@5776]
构建的主要目标有两个: 分别由 add_library
和 add_executable
构建的库和可执行文件。 [待校准@5777]
随着头文件的分离和在C/C ++ 中的实现,并不总是需要将两个文件都添加为 add_library
/ add_executable
的参数。 [待校准@5778]
提出以下最佳实践: [待校准@5779]
如果您正在构建一个库,请将客户端应该可以使用的所有标头放入
include
文件夹的子目录中,该文件夹的名称类似于包,而所有其他文件 (不应导出的.c/.cpp
文件和头文件) 都在src
文件夹中。 [待校准@5780]只有cpp文件在对
add_library
或add_executable
的调用中被明确引用。 [待校准@5781]允许通过 [待校准@5782]
target_include_directories(my_target
PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>)
安装时,这会添加文件夹 “${CMAKE_CURRENT_SOURCE_DIR}/包含 `` to the public interface during build time and all files in the include folder (relative to `` ${CMAKE_INSTALL_DIR}” 中的所有文件。 [待校准@5783]
原则上,使用生成器表达式不是必要如果文件夹调用ed include
和顶级关于 ''${CMAKE_CURRENT_SOURCE_DIR} `` and `` ${CMAKE_INSTALL_DIR}'', 但很普通。 [待校准@5784]
添加依赖项 [待校准@5785]
有两种方法可以将包与新的依赖项链接起来。 [待校准@5786]
第一个也是推荐的方法是使用ament宏观 ament_target_dependencies
。例如,假设我们想将 my_target
与线性代数库特征3联系起来。 [待校准@5787]
find_package(Eigen3 REQUIRED)
ament_target_dependencies(my_target Eigen3)
它包括项目要正确找到的必要的标头和库及其依赖项。它还将确保在使用覆盖工作区时正确排序所有依赖项的包含目录。 [待校准@5788]
第二种方法是使用 target_link_libraries
。 [待校准@5789]
在现代CMake中推荐的方法是只使用目标,导出和链接目标。CMake目标是命名空间,类似于C++。例如, Eigen3
定义了目标 “本征3:: 本征”。 [待校准@5790]
至少直到 Crystal Clemmys
目标名称不支持 ament_target_dependencies
微距。有时需要调用 target_link_libaries
CMake函数。在本征3的示例中,调用应该看起来像 [待校准@5791]
find_package(Eigen3 REQUIRED)
target_link_libraries(my_target Eigen3::Eigen)
这还将包括必要的标头、库及其依赖项,但与 ament_target_dependencies
相比,在使用覆盖工作区时,它可能无法正确排序依赖项。 [待校准@5792]
注解
它不应该必须 find_package
库不明确需要但依赖另一个依赖明确需要。如果是这种情况,请针对相应的包提交错误。 [待校准@5793]
构建一个库
构建可重用的库时,需要导出一些信息,以便下游包轻松使用。 [待校准@5795]
ament_export_targets(my_libraryTargets HAS_LIBRARY_TARGET)
ament_export_dependencies(some_dependency)
install(
DIRECTORY include/
DESTINATION include
)
install(
TARGETS my_library
EXPORT my_libraryTargets
LIBRARY DESTINATION lib
ARCHIVE DESTINATION lib
RUNTIME DESTINATION bin
INCLUDES DESTINATION include
)
在这里,我们假设文件夹 include
包含需要导出的标题。请注意,没有必要将所有标头放入单独的文件夹中,只需要将那些标头包含在客户端中。 [待校准@5796]
下面是上面片段中发生的事情: [待校准@5797]
[需手动修复的语法]
ament_export_targets
宏观出口CMake的目标。这是允许库的客户端使用 “target_link_library (客户端my_library::my_library)” 语法所必需的。[需手动修复的语法]ament_export_targets
可以在安装调用中采用名为EXPORT
的任意目标列表和一个附加选项HAS_LIBRARY_TARGET
,这将潜在的库添加到环境变量中。 [待校准@5798][需手动修复的语法]
ament_export_dependencies
将依赖项导出到下游包。这是必要的,这样库的用户也不必为这些依赖项调用find_package
。 [待校准@5799]第一个
install
命令安装应该对客户端可用的头文件。 [待校准@5800]
警告
从CMake子目录调用 ament_export_targets
、 ament_export_dependencies
或其他ament命令将无法正常工作。这是因为CMake子目录无法在调用 ament_package
的父范围内设置必要的变量。 [待校准@5801]
最后一个大型安装命令安装库。档案和库文件将被导出到lib文件夹,运行时二进制文件将被安装到bin文件夹,并且安装的标题的路径是
include
。 [待校准@5802]
注解
Windows dll被视为运行时工件,并安装到 RUNTIME DESTINATION
文件夹中。因此,即使在基于Unix的系统上开发库时,也建议不要忽略 RUNTIME
安装。 [待校准@5803]
关于
include directory
,安装命令只向CMake添加信息,它实际上并没有安装包含文件夹。如上所述,通过install(DIRECTORY <dir> DESTINATION <dest>)
复制标题来完成。 [待校准@5804]安装调用的
EXPORT
符号需要额外注意: 它为my_library
目标安装CMake文件。它的名字和ament_export_targets
的论点一模一样,可以像图书馆一样命名。然而,这将禁止使用ament_target_dependencies
的方式包括你的图书馆。为了实现充分的灵活性,建议在出口目标之前添加类似<target>Targets
的内容。 [待校准@5805]所有安装路径都是相对于
CMAKE_INSTALL_PREFIX
的,它已经由colcon/ament正确设置 [待校准@5806]
有两个附加功能可以使用,但对于基于目标的安装来说是多余的: [待校准@5807]
ament_export_include_directories(include)
ament_export_libraries(my_library)
第一个宏标记导出的包含目录的目录 (这是由目标 install
调用中的 INCLUDES DESTINATION
实现的)。第二个宏标记已安装库的位置 (这是通过对 ament_export_targets
的调用中的 HAS_LIBRARY_TARGET
参数完成的)。 [待校准@5808]
对于非目标导出,有些宏可以采用不同类型的参数,但是由于现代Make推荐的方法是使用目标,因此我们在这里不介绍它们。这些选项的文档可以在源文件本身中找到。 [待校准@5809]
编译器和链接器选项 [待校准@5810]
ROS 2目标编译器符合C++ 14 C99标准直到至少 Crystal Clemmys
。较新的版本可能是未来的目标,并被引用为 here 。因此,通常设置相应的CMake标志: [待校准@5811]
if(NOT CMAKE_C_STANDARD)
set(CMAKE_C_STANDARD 99)
endif()
if(NOT CMAKE_CXX_STANDARD)
set(CMAKE_CXX_STANDARD 14)
endif()
为了保持代码干净,编译器应该对有问题的代码发出警告,并且这些警告应该被修复。 [待校准@5812]
建议至少覆盖以下警告级别: [待校准@5813]
对于Visual Studio,保留默认的
W1
警告 [待校准@5814]对于GCC和Clang:
-Wall -Wextra -Wpedantic
是必需的,-Wshadow -Werror
是可取的 (后者会出现警告错误)。 [待校准@5815]
尽管现代CMake建议在目标基础上添加编译器标志,即调用 [待校准@5816]
target_compile_options(my_target PRIVATE -Wall)
目前建议使用目录级函数 add_compile_options(-Wall)
,以免代码中包含所有可执行文件和测试的基于目标的编译选项。 [待校准@5817]
在Windows上构建库 [待校准@5818]
由于Linux、Mac和Windows都是官方支持的平台,为了产生最大的影响,任何包都应该建立在Windows上。Windows库格式强制执行符号可见性: 应从客户端使用的每个符号都必须由库显式导出 (数据符号需要隐式导入)。 [待校准@5819]
为了使其与Clang和GCC构建兼容,建议使用 the GCC wiki 中的逻辑。将其用于调用ed my_library
的包: [待校准@5820]
将链接中的逻辑复制到调用ed
visibility_control.hpp
的头文件中。 [待校准@5821]用
MY_LIBRARY
取代DLL
(例如,见 rviz_rendering 能见度控制)。 [待校准@5822]对需要导出的所有符号使用宏 "MY_LIBRARY_PUBLIC" (即类或函数)。 [待校准@5823]
在
CMakeLists.txt
项目中使用: [待校准@5824]
target_compile_definitions(my_library PRIVATE "MY_LIBRARY_BUILDING_LIBRARY")
测试和脱毛 [待校准@5825]
为了将测试与使用colcon构建库分开,将所有调用s包装到linters和测试中,条件如下: [待校准@5826]
if(BUILD_TESTING)
find_package(ament_cmake_gtest REQUIRED)
ament_add_gtest(<tests>)
endif()
林廷 [待校准@5827]
建议使用来自 ament_lint_auto 的组合调用: [待校准@5828]
find_package(ament_lint_auto REQUIRED)
ament_lint_auto_find_test_dependencies()
这将运行 package.xml
中定义的林特。建议使用由 ament_lint_common
包装定义的一组短吻鳄。包括在那里的单个漆器,以及它们的功能,可以在 ament_lint_common docs 中看到。 [待校准@5829]
[需手动修复的语法]ament提供的短吻鳄也可以单独添加,而不是运行 ament_lint_auto
。如何做到这一点的一个例子可以在 ament_cmake_lint_cmake documentation 中找到。 [待校准@5830]
测试 [待校准@5831]
[需手动修复的语法]Ament包含CMake宏来简化GTests的设置。呼叫: [待校准@5832]
find_package(ament_cmake_gtest)
ament_add_gtest(some_test <test_sources>)
添加GTest。然后,这是一个常规目标,可以与其他库 (例如项目库) 链接。这些宏具有其他参数: [待校准@5833]
[需手动修复的语法]``APPEND_ENV``:附加环境变量。例如,您可以通过调用以下命令添加到ament前缀路径: [待校准@5834]
find_package(ament_cmake_gtest REQUIRED)
ament_add_gtest(some_test <test_sources>
APPEND_ENV PATH=some/addtional/path/for/testing/resources)
[需手动修复的语法]``APPEND_LIBRARY_DIRS``: append libraries so that they can be found by the linker at runtime. This can be achieved by setting environment variables like
PATH
on Windows andLD_LIBRARY_PATH
onLinux,但这使得调用平台特定。 [待校准@5835]ENV
: set environment variables (same syntax asAPPEND_ENV
). [待校准@5836][需手动修复的语法]``TIMEOUT``:将测试超时设置为秒。GTests的默认值为60秒。例如: [待校准@5837]
ament_add_gtest(some_test <test_sources> TIMEOUT 120)
[需手动修复的语法]``SKIP_TEST``:跳过此测试 (将在控制台输出中显示为 "passed" )。 [待校准@5838]
[需手动修复的语法]``SKIP_LINKING_MAIN_LIBRARIES``:与GTest没有联系。 [待校准@5839]
[需手动修复的语法]``WORKING_DIRECTORY``:设置了测试的工作目录。 [待校准@5840]
否则,默认的工作目录是 CMAKE_SOURCE_DIR
,它将被评估为顶级 CMakeLists.txt
的目录。 [待校准@5841]
同样,有一个CMake宏来设置GTest,包括GMock: [待校准@5842]
find_package(ament_gmock REQUIRED)
ament_add_gmock(some_test <test_sources>)
它具有与 ament_add_gtest
相同的附加参数。 [待校准@5843]
延伸ament [待校准@5844]
可以向 ament_cmake
注册其他宏/函数,并以多种方式扩展它。 [待校准@5845]
向ament添加函数/宏 [待校准@5846]
扩展ament通常意味着你希望有一些功能可供其他包使用。向客户包提供宏的最佳方式是向ament注册。 [待校准@5847]
这可以通过附加 “${PROJECT_NAME}_ CONFIG_EXTRAS” 变量来完成,该变量由 ament_package()
通过 [待校准@5848]
list(APPEND ${PROJECT_NAME}_CONFIG_EXTRAS
path/to/file.cmake"
other/pathto/file.cmake"
)
或者,您可以直接将文件添加到 ament_package()
调用中: [待校准@5849]
ament_package(CONFIG_EXTRAS
path/to/file.cmake
other/pathto/file.cmake
)
添加到扩展点 [待校准@5850]
除了具有可在其他包中使用的功能的简单文件之外,您还可以向ament添加扩展名。这些扩展是使用定义扩展点的函数执行的脚本。ament扩展最常见的用例可能是注册rosidl消息生成器: 当编写生成器时,您通常希望使用生成器生成所有消息和服务,而无需修改消息/服务定义包的代码。通过将发电机注册为 rosidl_generate_interfaces
的延伸,这是可能的。 [待校准@5851]
作为示例,请参见 [待校准@5852]
ament_register_extension(
"rosidl_generate_interfaces"
"rosidl_generator_cpp"
"rosidl_generator_cpp_generate_interfaces.cmake")
哪个寄存器宏观 rosidl_generator_cpp_generate_interfaces.cmake
包 rosidl_generator_cpp
的扩展点 rosidl_generate_interfaces
。当执行扩展点时,这将在此处触发脚本 rosidl_generator_cpp_generate_interfaces.cmake
的执行。特别是,每当函数 rosidl_generate_interfaces
被执行时,这将调用生成器。 [待校准@5853]
除了 rosidl_generate_interfaces
之外,发电机最重要的扩展点是 ament_package
,它将简单地用 ament_package()
调用执行脚本。在注册re源文件时,此扩展点非常有用 (见下文)。 [待校准@5854]
[需手动修复的语法]``ament_register_extension`` is函数采用三个参数: [待校准@5855]
extension_point
: The name of the extension point (most of the time this will be one ofament_package
orrosidl_generate_interfaces
) [待校准@5856][需手动修复的语法]``package_name``:包含CMake文件的包的名称 (即文件写入项目的项目名称) [待校准@5857]
[需手动修复的语法]``cmake_filename``:CMake文件时执行扩展点运行 [待校准@5858]
注解
可以以类似于 ament_package
和 rosidl_generate_interfaces
的方式定义自定义扩展点,但这几乎没有必要。 [待校准@5859]
添加扩展点 [待校准@5860]
很少,定义一个新的ament延伸点可能会很有趣。 [待校准@5861]
扩展点可以在宏中注册,以便在调用相应的宏时执行所有扩展。为此: [待校准@5862]
定义并记录扩展的名称 (例如
my_extension_point
),这是使用扩展点时传递给ament_register_extension
宏的名称。 [待校准@5863]在应执行扩展调用的宏/函数中: [待校准@5864]
ament_execute_extensions(my_extension_point)
[需手动修复的语法]Ament扩展的工作原理是定义一个包含扩展点名称的变量,并用要执行的宏填充它。调用 ament_execute_extensions
后,变量中定义的脚本将一个接一个地执行。 [待校准@5865]
添加re源文件 [待校准@5866]
尤其是在开发允许插件的插件或包时,通常必须将re源文件从另一个ROS包 (例如插件) 添加到一个ROS包中。示例可以是使用pluginlib的工具插件。 [待校准@5867]
这可以通过使用的ament指数 (也调用了 "resource index" )。 [待校准@5868]
ament指数解释 [待校准@5869]
有关设计和意图的详细信息,请参见 here [待校准@5870]
原则上,ament索引包含在包的安装/共享文件夹中的一个文件夹中。它包含以不同类型的re源文件命名的浅子文件夹。在子文件夹中,每个提供所述re源文件的包都以 "marker file" 名称引用。该文件可以包含获取re源文件所需的任何内容,例如到re源文件的安装目录的相对路径,它也可以简单地为空。 [待校准@5871]
举个例子,考虑为RViz提供显示插件: 当在一个名为 my_rviz_displays
的项目中提供RViz插件时,你将提供一个 plugin_description.xml
文件,它将由pluginlib安装并用于加载插件。为此,plugin_description.xml注册为重新源文件再次源文件 _ 指数通过 [待校准@5872]
pluginlib_export_plugin_description_file(rviz_common plugins_description.xml)
运行 colcon build
时,这会将文件 my_rviz_displays
安装到re源文件 _ index的子文件夹 rviz_common__pluginlib__plugin
中。rviz_common中的Pluginlib工厂将知道从所有名为 rviz_common__pluginlib__plugin
的文件夹中收集用于导出插件的包的信息。pluginlib工厂的标记文件包含 plugins_description.xml
文件的安装文件夹相对路径 (以及作为标记文件名的库名称)。有了这些信息,pluginlib可以加载库,并知道从 plugin_description.xml
文件加载哪些插件。 [待校准@5873]
作为第二个例子,考虑让你自己的RViz插件使用你自己的自定义网格的可能性。网格在启动时加载,因此插件所有者不必处理它,但这意味着RViz必须了解网格。为了实现这一点,RViz提供了一个功能: [待校准@5874]
register_rviz_ogre_media_exports(DIRECTORIES <my_dirs>)
这将目录注册为ament索引中的ogre_media re源文件。简而言之,它将一个以调用函数的项目命名的文件安装到调用 rviz_ogre_media_exports
的子文件夹中。该文件包含安装文件夹与宏中列出的目录的相对路径。在启动时,RViz现在可以搜索所有调用 rviz_ogre_media_exports
的文件夹,并在提供的所有文件夹中加载源文件。这些搜索是使用 ament_index_cpp
(或蟒蛇包的 ament_index_py
) 完成的。 [待校准@5875]
在以下各节中,我们将探讨如何将您自己的re源文件添加到ament索引中,并为此提供最佳实践。 [待校准@5876]
查询ament指数 [待校准@5877]
如有必要,可以通过CMake查询re源文件的ament索引。为此,有三个功能: [待校准@5878]
[需手动修复的语法]``ament_index_has_resource``:获得前缀路径重新源文件如果存在以下参数: [待校准@5879]
[需手动修复的语法]``var``:输出参数: 如果re源文件不存在,则用FALSE填充此变量,否则用re源文件的前缀路径填充 [待校准@5880]
resource_type
: The type of the resource (e.g.rviz_common__pluginlib__plugin
) [待校准@5881]resource_name
: The name of the resource which usually amounts to the name of the package having added the resource of type resource_type (e.g.rviz_default_plugins
) [待校准@5882]
[需手动修复的语法]``ament_index_get_resource``:获得特定re源文件的内容,即ament索引中标记文件的内容。 [待校准@5883]
[需手动修复的语法]``var``:输出参数: 如果存在,则填充re源文件的内容。 [待校准@5884]
resource_type
: The type of the resource (e.g.rviz_common__pluginlib__plugin
) [待校准@5881]resource_name
: The name of the resource which usually amounts to the name of the package having added the resource of type resource_type (e.g.rviz_default_plugins
) [待校准@5882]PREFIX_PATH
: The prefix path to search for (usually, the defaultament_index_get_prefix_path()
will就够了)。 [待校准@5885]
请注意,如果re源文件不存在, ament_index_get_resource
将引发错误,因此可能有必要使用 ament_index_has_resource
进行检查。 [待校准@5886]
[需手动修复的语法]``ament_index_get_resources``:从索引中获取注册特定类型的re源文件的所有包 [待校准@5887]
[需手动修复的语法]``var``:输出参数: 填充所有注册了re源文件类型的re源文件的包的名称列表 [待校准@5888]
resource_type
: The type of the resource (e.g.rviz_common__pluginlib__plugin
) [待校准@5881]PREFIX_PATH
: The prefix path to search for (usually, the defaultament_index_get_prefix_path()
will就够了)。 [待校准@5885]
添加到ament指数 [待校准@5889]
定义重新源文件需要两个信息: [待校准@5890]
re源文件的名称必须是唯一的, [待校准@5891]
标记文件的布局,可以是任何东西,也可以是空的 (例如,标记ROS 2包的 "package" re源文件也是如此) [待校准@5892]
对于RViz网格re源文件,相应的选择是: [待校准@5893]
[需手动修复的语法]``rviz_ogre_media_exports`` asre源文件的名称, [待校准@5894]
安装包含re源文件的所有文件夹的路径相对路径。这将使您能够编写在包中使用相应re源文件的逻辑。 [待校准@5895]
为了允许用户轻松注册包的re源文件,您还应该提供宏或函数,如pluginlib函数或 rviz_ogre_media_exports
函数。 [待校准@5896]
要注册re源文件,请使用ament函数 ament_index_register_resource
。这将在re源文件 _ index中创建和安装标记文件。例如,对 rviz_ogre_media_exports
的相应调用如下: [待校准@5897]
ament_index_register_resource(rviz_ogre_media_exports CONTENT ${OGRE_MEDIA_RESOURCE_FILE})
这个安装文件像 ''${PROJECT_NAME} ”到一个文件夹 rviz_ogre_media_exports
到重新源文件 _ 指数内容给出变量 ''${OGRE_MEDIA_RESOURCE_FILE}”。该宏具有许多有用的参数: [待校准@5898]
第一个 (未命名) 参数是re源文件的名称,相当于re源文件 _ index中文件夹的名称 [待校准@5899]
CONTENT
: The content of the marker file as string. This could be a list of relative paths, etc.CONTENT
cannot be used together withCONTENT_FILE
. [待校准@5900]CONTENT_FILE
: The path to a file which will be use to create the marker file. The file can be a plain file or a template file expanded withconfigure_file()
.CONTENT_FILE
cannot be used together withCONTENT
. [待校准@5901]PACKAGE_NAME
: The name of the package/library exporting the resource, which amounts to the name of the marker file. Defaults to${PROJECT_NAME}
. [待校准@5902]AMENT_INDEX_BINARY_DIR
: The base path of the generated ament index. Unless really necessary, always use the default${CMAKE_BINARY_DIR}/ament_cmake_index
. [待校准@5903][需手动修复的语法]``SKIP_INSTALL``:跳过安装标记文件。 [待校准@5904]
由于每个包只存在一个标记文件,如果CMake函数/宏被同一项目调用两次通常是一个问题。但是,对于大型项目,最好拆分注册源文件的调用。 [待校准@5905]
因此,最好的做法是让注册re源文件 (如 register_rviz_ogre_media_exports.cmake
) 的宏只填充一些变量。然后,对 ament_index_register_resource
的真正调用可以添加到 ament_package
的ament扩展中。因为每个项目只能有一个对 ament_package
的调用,所以总是只有一个地方注册了re源文件。就 rviz_ogre_media_exports
而言,这相当于以下策略: [待校准@5906]
宏
register_rviz_ogre_media_exports
获取文件夹列表,并将它们附加到调用edOGRE_MEDIA_RESOURCE_FILE
的变量中。 [待校准@5907]如果 “${OGRE_MEDIA_RESOURCE_FILE}” 为非空,则另一个宏调用ed
register_rviz_ogre_media_exports_hook
调用sament_index_register_resource
。 [待校准@5908]通过调用,
register_rviz_ogre_media_exports_hook.cmake
文件在第三文件register_rviz_ogre_media_exports_hook-extras.cmake
中注册为ament扩展名 [待校准@5909]
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
。 [待校准@5910]