cartographer源码学习笔记之CMakeLists.txt文件解读

1 CMakeLists.txt的解释

cmake_minimum_required(VERSION 2.8.12)  # Ships with Ubuntu 14.04 (Trusty)

project(cartographer_ros)

set(PACKAGE_DEPENDENCIES
  cartographer_ros_msgs
  geometry_msgs
  message_runtime
  nav_msgs
  pcl_conversions
  rosbag
  roscpp
  roslib
  sensor_msgs
  std_msgs
  tf2
  tf2_eigen
  tf2_ros
  urdf
  visualization_msgs
)

if(WIN32)
  set(Boost_USE_STATIC_LIBS FALSE)
endif()

cmake_minimum_required(VERSION 2.8.12) 指定了项目所需的最低CMake版本。
project(cartographer_ros) 定义了项目的名称为"cartographer_ros"。
set(PACKAGE_DEPENDENCIES …) 定义了一组依赖项,这些依赖项是在构建和运行项目时所需的其他ROS软件包。其中PACKAGE_DEPENDENCIES 将所有的变量的集合用这个来代替。
if(WIN32) 用于判断当前操作系统是否为Windows。如果是Windows系统,就执行set(Boost_USE_STATIC_LIBS FALSE),将Boost库的静态链接标志设置为FALSE,以便在Windows系统上使用动态链接的Boost库。

find_package(Boost REQUIRED COMPONENTS system iostreams)
find_package(PCL REQUIRED COMPONENTS common io)

find_package(cartographer REQUIRED)
include("${CARTOGRAPHER_CMAKE_DIR}/functions.cmake")
option(BUILD_GRPC "build features that require Cartographer gRPC support" false)
google_initialize_cartographer_project()

find_package(Boost REQUIRED COMPONENTS system iostreams): 这行代码用于查找和配置Boost库。Boost是库的名称,REQUIRED表示Boost是必需的,如果找不到会产生错误。COMPONENTS后面列出了需要的Boost组件,包括system和iostreams。通过这行代码,CMake将查找并配置Boost库,并确保所需的组件可用。
find_package(PCL REQUIRED COMPONENTS common io): 这行代码用于查找和配置PCL库。PCL是库的名称,REQUIRED表示PCL是必需的,如果找不到会产生错误。COMPONENTS后面列出了需要的PCL组件,包括common和io。通过这行代码,CMake将查找并配置PCL库,并确保所需的组件可用。
find_package(cartographer REQUIRED): 这行代码用于查找和配置Cartographer库。cartographer是库的名称,REQUIRED表示Cartographer是必需的,如果找不到会产生错误。通过这行代码,CMake将查找并配置Cartographer库。
include(“${CARTOGRAPHER_CMAKE_DIR}/functions.cmake”): 这行代码包含了Cartographer的CMake函数定义文件。它会将functions.cmake文件包含到当前的CMakeLists.txt文件中,以便在构建过程中使用Cartographer定义的函数。
option(BUILD_GRPC “build features that require Cartographer gRPC support” false): 这行代码定义了一个名为BUILD_GRPC的CMake选项。它用于指定是否构建需要Cartographer gRPC支持的功能。false表示默认情况下不构建这些功能。通过这个选项,可以根据需要选择是否构建与gRPC相关的功能。
google_initialize_cartographer_project(): 这行代码用于初始化Cartographer项目。它会执行一些与Cartographer相关的初始化操作,确保项目正确配置和构建。

set(CARTOGRAPHER_GMOCK_LIBRARIES ${GMOCK_LIBRARIES})

find_package(catkin REQUIRED COMPONENTS ${PACKAGE_DEPENDENCIES})

include(FindPkgConfig)

find_package(absl REQUIRED)
find_package(LuaGoogle REQUIRED)
find_package(Eigen3 REQUIRED)

find_package(urdfdom_headers REQUIRED)
if(DEFINED urdfdom_headers_VERSION)
  if(${urdfdom_headers_VERSION} GREATER 0.4.1)
    add_definitions(-DURDFDOM_HEADERS_HAS_SHARED_PTR_DEFS)
  endif()
endif()

include_directories(
  ${urdfdom_headers_INCLUDE_DIRS}
)

set(CARTOGRAPHER_GMOCK_LIBRARIES G M O C K L I B R A R I E S ) :将变量 {GMOCK_LIBRARIES}):将变量 GMOCKLIBRARIES):将变量{GMOCK_LIBRARIES}的值赋给变量CARTOGRAPHER_GMOCK_LIBRARIES。这通常用于将库的路径或名称保存在变量中供后续使用。
find_package(catkin REQUIRED COMPONENTS P A C K A G E D E P E N D E N C I E S ) :使用 c a t k i n 包管理器查找和加载需要的组件和依赖项。 {PACKAGE_DEPENDENCIES}):使用catkin包管理器查找和加载需要的组件和依赖项。 PACKAGEDEPENDENCIES):使用catkin包管理器查找和加载需要的组件和依赖项。{PACKAGE_DEPENDENCIES}是一个包含所需组件的列表,catkin将确保这些组件可用。
include(FindPkgConfig):包含FindPkgConfig模块,该模块用于查找和配置通过pkg-config工具提供的库。
find_package(absl REQUIRED):使用absl包管理器查找并加载absl库。REQUIRED关键字表示该库是必需的,如果找不到将产生错误。
find_package(LuaGoogle REQUIRED):使用LuaGoogle包管理器查找并加载LuaGoogle库。同样,REQUIRED关键字表示该库是必需的。
find_package(Eigen3 REQUIRED):使用Eigen3包管理器查找并加载Eigen3库。同样,REQUIRED关键字表示该库是必需的。
find_package(urdfdom_headers REQUIRED):使用urdfdom_headers包管理器查找并加载urdfdom_headers库。同样,REQUIRED关键字表示该库是必需的。
if(DEFINED urdfdom_headers_VERSION):检查是否定义了变量urdfdom_headers_VERSION。
if(${urdfdom_headers_VERSION} GREATER 0.4.1):如果urdfdom_headers_VERSION的值大于0.4.1,则执行下面的语句块。
add_definitions(-DURDFDOM_HEADERS_HAS_SHARED_PTR_DEFS):添加一个定义,将URDFDOM_HEADERS_HAS_SHARED_PTR_DEFS设置为1,以便在编译期间启用特定的功能或选项。

set(GTEST_FOUND TRUE)
set(GTEST_INCLUDE_DIRS ${GMOCK_INCLUDE_DIRS})
set(GTEST_LIBRARIES ${CARTOGRAPHER_GMOCK_LIBRARIES})

catkin_package(
  CATKIN_DEPENDS
    ${PACKAGE_DEPENDENCIES}
  DEPENDS
    # TODO(damonkohler): This should be here but causes Catkin to abort because
    # protobuf specifies a library '-lpthread' instead of just 'pthread'.
    # CARTOGRAPHER
    PCL
    EIGEN3
    Boost
    urdfdom_headers
  INCLUDE_DIRS "."
  LIBRARIES ${PROJECT_NAME}
)

首先,通过set命令覆盖Catkin的GTest配置,将GTEST_FOUND设置为TRUE,将GTEST_INCLUDE_DIRS设置为GMOCK_INCLUDE_DIRS,将GTEST_LIBRARIES设置为CARTOGRAPHER_GMOCK_LIBRARIES。这样做是为了使用GMock而不是默认的GTest。

CATKIN_DEPENDS: 指定当前软件包对其他Catkin软件包的依赖关系。在这段代码中,使用 P A C K A G E D E P E N D E N C I E S 指定了一组依赖关系,其中包括 c a r t o g r a p h e r r o s m s g s 、 g e o m e t r y m s g s 、 m e s s a g e r u n t i m e 等。 D E P E N D S : 指定构建和安装当前软件包所需的其他依赖项。在这段代码中,使用 P C L 、 E I G E N 3 、 B o o s t 和 u r d f d o m h e a d e r s 作为其他依赖项。 I N C L U D E D I R S : 指定当前软件包的包含文件目录。在这里,使用 . 表示当前目录,即包含文件位于当前目录下。 L I B R A R I E S : 指定要链接到当前软件包的库。 {PACKAGE_DEPENDENCIES}指定了一组依赖关系,其中包括cartographer_ros_msgs、geometry_msgs、message_runtime等。 DEPENDS: 指定构建和安装当前软件包所需的其他依赖项。在这段代码中,使用PCL、EIGEN3、Boost和urdfdom_headers作为其他依赖项。 INCLUDE_DIRS: 指定当前软件包的包含文件目录。在这里,使用.表示当前目录,即包含文件位于当前目录下。 LIBRARIES: 指定要链接到当前软件包的库。 PACKAGEDEPENDENCIES指定了一组依赖关系,其中包括cartographerrosmsgsgeometrymsgsmessageruntime等。DEPENDS:指定构建和安装当前软件包所需的其他依赖项。在这段代码中,使用PCLEIGEN3Boosturdfdomheaders作为其他依赖项。INCLUDEDIRS:指定当前软件包的包含文件目录。在这里,使用.表示当前目录,即包含文件位于当前目录下。LIBRARIES:指定要链接到当前软件包的库。{PROJECT_NAME}表示当前软件包的名称,将该软件包作为库链接到最终的可执行文件中。

file(GLOB_RECURSE ALL_SRCS "cartographer_ros/*.cc" "cartographer_ros/*.h")
file(GLOB_RECURSE ALL_TESTS "cartographer_ros/*_test.cc")
file(GLOB_RECURSE ALL_EXECUTABLES "cartographer_ros/*_main.cc")
file(GLOB_RECURSE ALL_GRPC_FILES "cartographer_ros/cartographer_grpc/*")
list(REMOVE_ITEM ALL_SRCS ${ALL_TESTS})
list(REMOVE_ITEM ALL_SRCS ${ALL_EXECUTABLES})
if (NOT ${BUILD_GRPC})
  list(REMOVE_ITEM ALL_SRCS ${ALL_GRPC_FILES})
  list(REMOVE_ITEM ALL_TESTS ${ALL_GRPC_FILES})
  list(REMOVE_ITEM ALL_EXECUTABLES ${ALL_GRPC_FILES})
endif()

这行代码使用通配符模式匹配,将 cartographer_ros 目录及其子目录中所有以 .cc 和 .h 结尾的文件添加到 ALL_SRCS 列表中。
具体来说,file(GLOB_RECURSE …) 是 CMake 提供的一个命令,用于在构建过程中搜索和匹配文件。在这里,GLOB_RECURSE 表示递归地搜索目录及其子目录中的文件,并将匹配的文件添加到列表中。
ALL_SRCS 是一个变量名,你可以在后续的 CMake 脚本中使用该变量来引用这些文件列表。这个列表包含了项目中所有以 .cc 和 .h 结尾的文件。

list(REMOVE_ITEM …) 是 CMake 中的一个命令,用于从列表中移除指定的项。
在给定的列表中,使用 list(REMOVE_ITEM …) 命令可以将满足指定条件的项从列表中移除。具体而言,${ALL_TESTS} 是要被移除的项,而 ALL_SRCS 是待操作的列表。
在上述代码中,list(REMOVE_ITEM ALL_SRCS ${ALL_TESTS}) 的作用是从列表 ALL_SRCS 中移除所有与 ${ALL_TESTS} 匹配的项。
这个命令在上述代码中的目的可能是为了从 ALL_SRCS 列表中排除测试相关的文件,以便在后续的构建过程中只关注非测试的源代码文件。

# 生成library
add_library(${PROJECT_NAME} STATIC ${ALL_SRCS})

# 添加子目录,生成可执行文件
add_subdirectory("cartographer_ros")

# 连接到cartographer
target_link_libraries(${PROJECT_NAME} PUBLIC cartographer)

# Lua
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${LUA_INCLUDE_DIR})

# PCL
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${PCL_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PUBLIC ${PCL_LIBRARIES})

这段代码是用来生成库和可执行文件,并进行链接的。

首先,使用 add_library() 命令生成一个静态库,名称为 ${PROJECT_NAME},源文件为 ${ALL_SRCS} 中的文件。这个静态库用于存放工程的一些公共代码。
然后,使用 add_subdirectory() 命令添加子目录 “cartographer_ros”,在这个子目录中会生成可执行文件。
接下来,使用 target_link_libraries() 命令将 P R O J E C T N A M E 链接到 c a r t o g r a p h e r 库。这意味着在构建过程中, {PROJECT_NAME} 链接到 cartographer 库。这意味着在构建过程中, PROJECTNAME链接到cartographer库。这意味着在构建过程中,{PROJECT_NAME} 会使用 cartographer 库中的函数和资源。
接下来,使用 target_include_directories() 命令将 ${LUA_INCLUDE_DIR} 添加到 P R O J E C T N A M E 的包含目录中。这样,在编译时, {PROJECT_NAME} 的包含目录中。这样,在编译时, PROJECTNAME的包含目录中。这样,在编译时,{PROJECT_NAME} 可以找到 Lua 头文件。
最后,使用 target_include_directories() 命令将 ${PCL_INCLUDE_DIRS} 添加到 ${PROJECT_NAME} 的包含目录中,并使用 target_link_libraries() 命令将 ${PCL_LIBRARIES} 链接到 P R O J E C T N A M E 。这样,在编译时, {PROJECT_NAME}。这样,在编译时, PROJECTNAME。这样,在编译时,{PROJECT_NAME} 可以找到 PCL 头文件并链接 PCL 库。

set(BLACKLISTED_PCL_DEFINITIONS " -march=native -msse4.2 -mfpmath=sse ")
foreach(DEFINITION ${PCL_DEFINITIONS})
  list (FIND BLACKLISTED_PCL_DEFINITIONS "${DEFINITION}" DEFINITIONS_INDEX)
  if (${DEFINITIONS_INDEX} GREATER -1)
    continue()
  endif()
  set(TARGET_COMPILE_FLAGS "${TARGET_COMPILE_FLAGS} ${DEFINITION}")
endforeach()

这行代码定义了一个名为 BLACKLISTED_PCL_DEFINITIONS 的变量,并将字符串 " -march=native -msse4.2 -mfpmath=sse " 赋值给它。

在这个上下文中,这个变量用于存储一些特定的 PCL 定义,这些定义不希望出现在编译选项中。这些定义包含了特定的处理器架构和浮点数运算的选项。这些选项可能会与当前系统的处理器或编译器不兼容,因此被列入黑名单,以避免在编译时使用。

在后续的代码中,将遍历 P C L D E F I N I T I O N S 中的每个定义,并将它们与 B L A C K L I S T E D P C L D E F I N I T I O N S 进行比较。如果找到匹配的定义,将跳过该定义,不将其包含在编译选项中。这样可以确保在编译时使用适合当前系统的有效选项。 l i s t ( F I N D B L A C K L I S T E D P C L D E F I N I T I O N S " {PCL_DEFINITIONS} 中的每个定义,并将它们与 BLACKLISTED_PCL_DEFINITIONS 进行比较。如果找到匹配的定义,将跳过该定义,不将其包含在编译选项中。这样可以确保在编译时使用适合当前系统的有效选项。 list(FIND BLACKLISTED_PCL_DEFINITIONS " PCLDEFINITIONS中的每个定义,并将它们与BLACKLISTEDPCLDEFINITIONS进行比较。如果找到匹配的定义,将跳过该定义,不将其包含在编译选项中。这样可以确保在编译时使用适合当前系统的有效选项。list(FINDBLACKLISTEDPCLDEFINITIONS"{DEFINITION}" DEFINITIONS_INDEX):在 BLACKLISTED_PCL_DEFINITIONS 列表中查找 D E F I N I T I O N 的索引,并将结果存储在 D E F I N I T I O N S I N D E X 变量中。如果找到匹配的定义, D E F I N I T I O N S I N D E X 的值将大于 − 1 ,否则为 − 1 。 i f ( {DEFINITION} 的索引,并将结果存储在 DEFINITIONS_INDEX 变量中。如果找到匹配的定义,DEFINITIONS_INDEX 的值将大于 -1,否则为 -1。 if ( DEFINITION的索引,并将结果存储在DEFINITIONSINDEX变量中。如果找到匹配的定义,DEFINITIONSINDEX的值将大于1,否则为1if({DEFINITIONS_INDEX} GREATER -1):检查 DEFINITIONS_INDEX 的值是否大于 -1,即是否找到了匹配的定义。如果找到了匹配的定义,则执行 continue(),跳过当前迭代,并继续下一次迭代。
set(TARGET_COMPILE_FLAGS “${TARGET_COMPILE_FLAGS} ${DEFINITION}”):将 ${DEFINITION} 添加到 TARGET_COMPILE_FLAGS 变量中。这个变量用于存储目标的编译选项。每次迭代都会将一个有效的定义添加到该变量中,以便在后续步骤中将其应用于目标的编译过程。
通过以上操作,这段代码的目的是遍历 ${PCL_DEFINITIONS} 中的每个定义,并将非黑名单中的定义添加到 TARGET_COMPILE_FLAGS 中,以便在后续的编译过程中使用这些选项。这样可以确保编译时使用适合当前系统的有效选项,而忽略在黑名单中的不兼容选项。

# Eigen
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC
  "${EIGEN3_INCLUDE_DIR}")

# Boost
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC
  "${Boost_INCLUDE_DIRS}")
target_link_libraries(${PROJECT_NAME} PUBLIC ${Boost_LIBRARIES})

# Catkin
target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${catkin_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} PUBLIC ${catkin_LIBRARIES})
add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS})

target_include_directories( P R O J E C T N A M E S Y S T E M P U B L I C " {PROJECT_NAME} SYSTEM PUBLIC " PROJECTNAMESYSTEMPUBLIC"{EIGEN3_INCLUDE_DIR}"):将 ${EIGEN3_INCLUDE_DIR} 目录添加到 ${PROJECT_NAME} 目标库的包含目录中。这样做可以使目标库能够访问 Eigen 头文件。

target_include_directories( P R O J E C T N A M E S Y S T E M P U B L I C " {PROJECT_NAME} SYSTEM PUBLIC " PROJECTNAMESYSTEMPUBLIC"{Boost_INCLUDE_DIRS}"):将 ${Boost_INCLUDE_DIRS} 目录添加到 ${PROJECT_NAME} 目标库的包含目录中。这样做可以使目标库能够访问 Boost 头文件。

target_link_libraries(${PROJECT_NAME} PUBLIC ${Boost_LIBRARIES}):将 ${Boost_LIBRARIES} 库链接到 ${PROJECT_NAME} 目标库中。这样做可以使目标库能够使用 Boost 库的功能。

target_include_directories(${PROJECT_NAME} SYSTEM PUBLIC ${catkin_INCLUDE_DIRS}):将 ${catkin_INCLUDE_DIRS} 目录添加到 ${PROJECT_NAME} 目标库的包含目录中。这样做可以使目标库能够访问 Catkin 相关的头文件。

target_link_libraries(${PROJECT_NAME} PUBLIC ${catkin_LIBRARIES}):将 ${catkin_LIBRARIES} 库链接到 ${PROJECT_NAME} 目标库中。这样做可以使目标库能够使用 Catkin 相关的功能。

add_dependencies(${PROJECT_NAME} ${catkin_EXPORTED_TARGETS}):将 ${catkin_EXPORTED_TARGETS} 添加为 ${PROJECT_NAME} 目标库的依赖项。这样做可以确保在构建过程中先构建 ${catkin_EXPORTED_TARGETS} 相关的目标。

# Add the binary directory first, so that port.h is included after it has
# been generated.
target_include_directories(${PROJECT_NAME} PUBLIC
    $
    $
    $<INSTALL_INTERFACE:include>
)

set(TARGET_COMPILE_FLAGS "${TARGET_COMPILE_FLAGS} ${GOOG_CXX_FLAGS}")
set_target_properties(${PROJECT_NAME} PROPERTIES
  COMPILE_FLAGS ${TARGET_COMPILE_FLAGS})

这段代码主要是针对 ${PROJECT_NAME} 目标库进行一些设置和配置,包括:

target_include_directories(${PROJECT_NAME} PUBLIC …):将一些目录添加到 ${PROJECT_NAME} 目标库的包含目录中。这些目录包括:

< B U I L D I N T E R F A C E : <BUILDINTERFACE:{PROJECT_BINARY_DIR}>:构建过程中的二进制目录,这样可以确保在生成 port.h 文件后将其包含到编译中。
< B U I L D I N T E R F A C E : <BUILDINTERFACE:{PROJECT_SOURCE_DIR}>:项目源代码目录,这样可以访问项目中的其他源代码文件。
< I N S T A L L I N T E R F A C E : i n c l u d e > :安装目录中的 i n c l u d e 目录,这样在安装目标库时,用户可以访问库的头文件。 s e t ( T A R G E T C O M P I L E F L A G S " :安装目录中的 include 目录,这样在安装目标库时,用户可以访问库的头文件。 set(TARGET_COMPILE_FLAGS " <INSTALLINTERFACE:include>:安装目录中的include目录,这样在安装目标库时,用户可以访问库的头文件。set(TARGETCOMPILEFLAGS"{TARGET_COMPILE_FLAGS} ${GOOG_CXX_FLAGS}"):将 ${GOOG_CXX_FLAGS} 变量的内容添加到 T A R G E T C O M P I L E F L A G S 变量中。 {TARGET_COMPILE_FLAGS} 变量中。 TARGETCOMPILEFLAGS变量中。{GOOG_CXX_FLAGS} 可能是一些特定的编译选项或标志。

set_target_properties(${PROJECT_NAME} PROPERTIES COMPILE_FLAGS ${TARGET_COMPILE_FLAGS}):将 ${TARGET_COMPILE_FLAGS} 变量的内容作为 ${PROJECT_NAME} 目标库的编译选项。这样做可以确保在构建目标库时使用指定的编译选项。

install(DIRECTORY launch urdf configuration_files
  DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}
)

install(PROGRAMS scripts/tf_remove_frames.py
  DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}
)

install(TARGETS ${PROJECT_NAME}
  ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION}
  RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}
)
# Install source headers.
file(GLOB_RECURSE HDRS "cartographer_ros/*.h")
foreach(HDR ${HDRS})
  file(RELATIVE_PATH REL_FIL ${PROJECT_SOURCE_DIR} ${HDR})
  get_filename_component(INSTALL_DIR ${REL_FIL} DIRECTORY)
  install(
    FILES
      ${HDR}
    DESTINATION
      include/${INSTALL_DIR}
  )
endforeach()

这段代码是用于安装目标库和其他文件到特定目录。具体解释如下:

install(DIRECTORY launch urdf configuration_files DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}):将指定的目录 launch、urdf 和 configuration_files 完整地安装到 C A T K I N P A C K A G E S H A R E D E S T I N A T I O N 目录中。 {CATKIN_PACKAGE_SHARE_DESTINATION} 目录中。 CATKINPACKAGESHAREDESTINATION目录中。{CATKIN_PACKAGE_SHARE_DESTINATION} 是一个变量,表示 catkin 包的共享目录。

install(PROGRAMS scripts/tf_remove_frames.py DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION}):将 scripts/tf_remove_frames.py 文件安装为可执行程序到 C A T K I N P A C K A G E B I N D E S T I N A T I O N 目录中。 {CATKIN_PACKAGE_BIN_DESTINATION} 目录中。 CATKINPACKAGEBINDESTINATION目录中。{CATKIN_PACKAGE_BIN_DESTINATION} 是一个变量,表示 catkin 包的二进制目录。

install(TARGETS ${PROJECT_NAME} ARCHIVE DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} LIBRARY DESTINATION ${CATKIN_PACKAGE_LIB_DESTINATION} RUNTIME DESTINATION ${CATKIN_GLOBAL_BIN_DESTINATION}):将 P R O J E C T N A M E 目标库安装到指定的目录。 {PROJECT_NAME} 目标库安装到指定的目录。 PROJECTNAME目标库安装到指定的目录。{PROJECT_NAME} 是目标库的名称。ARCHIVE、LIBRARY 和 RUNTIME 是目标库的不同类型,分别表示静态库、动态库和可执行文件。${CATKIN_PACKAGE_LIB_DESTINATION} 和 ${CATKIN_GLOBAL_BIN_DESTINATION} 是变量,分别表示 catkin 包的库目录和全局二进制目录。

file(GLOB_RECURSE HDRS “cartographer_ros/*.h”):通过递归搜索,将 cartographer_ros 目录下的所有 .h 文件存储在 HDRS 变量中。

foreach(HDR ${HDRS}) … endforeach():对 HDRS 列表中的每个元素执行循环操作。

file(RELATIVE_PATH REL_FIL ${PROJECT_SOURCE_DIR} ${HDR}):计算 ${HDR} 相对于 ${PROJECT_SOURCE_DIR} 的相对路径,并将结果存储在 REL_FIL 变量中。

get_filename_component(INSTALL_DIR ${REL_FIL} DIRECTORY):从 REL_FIL 变量中提取目录部分,并将结果存储在 INSTALL_DIR 变量中。

install(FILES H D R D E S T I N A T I O N i n c l u d e / {HDR} DESTINATION include/ HDRDESTINATIONinclude/{INSTALL_DIR}):将 ${HDR} 文件安装到 P R O J E C T S O U R C E D I R / {PROJECT_SOURCE_DIR}/ PROJECTSOURCEDIR/{INSTALL_DIR} 目录中。这样做可以按照源代码目录结构,将头文件安装到相应的目录下。

附录:
gRPC是一种高性能、通用的开源远程过程调用(RPC)框架,由Google开发并开源。它基于HTTP/2协议,使用Protocol Buffers作为接口定义语言(IDL),支持多种编程语言和平台。

远程过程调用(RPC)是一种在分布式系统中不同进程或不同计算机之间进行通信的方式。它允许应用程序调用远程计算机上的函数或方法,就像调用本地函数一样,隐藏了底层通信细节。

gRPC的主要特点包括:
高性能:使用基于HTTP/2的协议,支持双向流、多路复用和流式处理等特性,提供了更高效的网络通信性能。
简单易用:使用Protocol Buffers定义服务接口和消息格式,通过自动生成的客户端和服务器端代码,使开发变得简单和高效。
多语言支持:提供了对多种编程语言的支持,包括C++、Java、Python、Go等,使开发人员可以在自己熟悉的编程语言中使用gRPC。
跨平台:可以在不同的操作系统和平台上运行,支持在移动设备、嵌入式设备和云环境等各种场景中使用。
安全性:支持基于SSL/TLS的安全传输,可以对通信进行加密和身份验证,保障数据的安全性。
可扩展性:提供了灵活的扩展机制,允许开发人员根据自己的需求添加自定义的拦截器、认证和授权等功能。
gRPC广泛应用于微服务架构、分布式系统、云原生应用等场景,使不同的组件和服务能够高效地进行通信和协作。它提供了一种简单、快速、可靠的方式来构建分布式系统,并促进了跨语言、跨平台的互操作性。

GMock和GTest是Google Test和Google Mock的简称,它们是用于C++的测试框架。

Google Test(GTest)是一个功能丰富的C++测试框架,用于编写单元测试、集成测试和功能测试。它提供了一组宏和类,用于编写和组织测试用例、断言和测试夹具。GTest的主要目标是提供一种简单而强大的方式来编写测试,并生成易于理解的测试报告。

Google Mock(GMock)是Google Test的扩展,用于编写C++的模拟和打桩测试。它提供了一组类和宏,用于创建模拟对象(Mocks)和设置预期行为。模拟对象用于模拟系统中的组件或外部依赖项,以便进行更轻松的测试。通过模拟对象,您可以定义其行为,使其返回预定义的值、引发特定的事件等。

这两个框架通常一起使用,GTest用于编写单元测试和功能测试,而GMock用于编写模拟和打桩测试。它们提供了丰富的功能和灵活性,使开发人员能够轻松编写和运行各种测试,并验证代码在各种情况下的行为和预期结果。
在软件测试中,打桩(Stubbing)是一种测试技术,用于模拟或替代软件中的外部依赖项或不可控因素的行为。打桩行为允许在测试中对这些外部依赖项进行控制,以便更好地控制测试环境和验证被测试代码的行为。

打桩行为的基本思想是将外部依赖项的实际行为替换为测试中定义的虚拟行为。通过打桩,测试可以模拟外部系统的各种情况和响应,包括成功、失败、异常等,以验证被测试代码在这些情况下的处理方式。

例如,假设正在编写一个涉及文件系统读取的函数,并且希望测试函数在不依赖实际文件系统的情况下工作。通过打桩文件系统读取函数,可以模拟文件的存在、文件内容的返回或特定的错误条件,而无需实际的文件系统交互。这样,可以更方便地编写各种测试用例,包括处理各种读取结果和错误情况的情况。

打桩行为通常通过使用模拟对象(Mocks)或特殊的测试工具函数来实现。这些工具提供了一种在测试中定义和配置外部依赖项行为的方式,以便更好地控制测试环境并模拟各种场景。
递归搜索是指在一个目录中查找目标文件时,同时搜索该目录下的所有子目录,以及子目录中的子目录,以此类推,直到找到所有满足条件的目标文件或搜索完所有的目录。

在代码中,使用 file(GLOB_RECURSE …) 命令进行递归搜索,它会遍历指定目录及其子目录中的文件,并根据指定的通配符模式进行匹配,将满足条件的文件添加到列表中。

递归搜索非常方便,可以帮助我们快速找到需要的文件,尤其是在大型项目中,文件分布在多个子目录中时特别有用。

你可能感兴趣的:(cartographer,学习,笔记)