工程管理方式之小技巧,小知识

CMAKE 知识点

  • add_dependencies
add_dependencies(<target> [<target-dependency>]...)

官方文档对此的解释为 :在顶级目标之间添加依赖关系。使顶层 target 依赖于其他顶层目标,以确保它们在 target 之前构建。顶级目标是由 add_executable(),add_library() 或 add_custom_target() 命令之一创建的。

#指定cmake最低版本
cmake_minimum_required(VERSION 3.14)

#指定头文件位置
include_directories(${PROJECT_SOURCE_DIR}/lib)

#设置可执行文件生成目录
set(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)

#生成可执行文件
add_executable(res ${PROJECT_SOURCE_DIR}/src/main.cpp)

#指定依赖
add_dependencies(res myLib)

#链接动态库
target_link_libraries(res ${PROJECT_BINARY_DIR}/bin/libmyLib.so)

添加add_dependencies(res myLib),意思就是告诉编译器,我知道生成res程序要链接myLib这个库文件,但是现在我还没有这个库文件,你先生成res,随后就把库文件myLib给你生成出来。

参考:https://blog.csdn.net/new9232/article/details/125831009

ros 知识点

ros工程是被一个一个package组成的,package可以说是ROS的细胞。在catkin_make的时候它会一个一个的去找package然后生成目标文件。一个package可以有多个节点。判断是否为Package :一个文件夹要被ROS认为是package的话,必须包含以下两个文件:CMakeList.txt和package.xml。
CMakeLists.txt规定catkin编译的规则。(例如:源文件,依赖项,目标文件)。而package.xml文件定义了package的属性。(例如:包名,版本号,作者,一来等等),相当于一个包的自我描述。

对于package.xml文件文件中的其他标签已经有很多说明文档了,package.xml文件定义了package的属性。(例如:包名,版本号,作者,一来等等),相当于一个包的自我描述。下面说一下build_depend标签。 当我在package.xml中屏蔽掉这个标签的内容,会报如下错误

CMake Error at /opt/ros/kinetic/share/catkin/cmake/catkin_package.cmake:198 (message):
  catkin_package() the catkin package 'roscpp' has been find_package()-ed but
  is not listed as a build dependency in the package.xml

从上面错误可以推断出是CMakeLists.txt文件中的catkin_package函数调用,需要查找package.xml文件中的依赖包并且buildtool_depend也需要添加上。如果没有列出来就会出现上面错误。
如果不需要导出本包依赖的依赖包。则可以屏蔽掉build_depend标签。

- catkin编译过程

  1. 执行catkin_make。
  2. 执行catkin_workspace。解析catkin_make的参数同时遍历整个工作空间把所有的有package.xml的文件夹添加进软件包列表里面。对每个软件包执行add_subdirectory。
  3. 执行每个软件包内部的CMakeList.txt文件。
  4. 执行 catkin_package。解析package.xml文件,载入对应的参数。根据依赖参数,载入对应的软件包参数。根据载入参数生成当前软件包的配置文件。

发现package.xml在第二步和第四步将会用到。

参考:https://blog.csdn.net/wangxiao7474/article/details/109840779

- catkin 之catkin_package

DEPENDS 和 CATKIN_DEPENDS 用来告诉 catkin 需要将你程序包的哪些依赖项传递给使用 find_package(…) 查找你的程序包的程序包。
例如,假设你 find_package(Boost REQUIRED),并在你的安装的头文件中 #include <boost/function.hpp>。为使一个依赖于你的程序包的程序包能构建和连接你的头文件,它们需要在自己的 include 路径中包含 Boost 的 include 目录,还需要连接 Boost 的库。由于你已经在头文件中导出了该依赖,它们应该能从你那里获得依赖。也就是它们不再需要 find_package(Boost REQUIRED) ,因为它们是使用你的包构建的,而不是直接使用 Boost。
你的程序包依赖于 Boost 这一事实是一个实现细节,因此当一些包通过 find_package(…) 查找你的包时,它们能间接获得对 Boost 的依赖。让这种机制起作用方法是在你的 catkin_package(…) 调用中加入 DEPENDS Boost。在内部,catkin 将 find_package(Boost),并向 ${your_pkg_LIBRARIES} 添加 ${Boost_LIBRARIES} ,向 ${your_pkg_INCLUDE_DIRS} 添加 ${Boost_INCLUDE_DIRS}。
我们应该注意,catkin 将 find_package() 你告诉它的确切的程序包名, 然后尝试使用该包的 _LIBRARIES 和 _INCLUDE_DIRS 变量。但是 find_package(…) 得到的结果变量的形式并不总是这样,因为 CMake 没有强制执行此操作。例如当 find_package(…) Python 时,find_package(PythonLibs REQUIRED) 的结果变量的形式为 PYTHON_INCLUDE_PATH,find_package(OpenGL REQUIRED) 的结果变量为 OPENGL_INCLUDE_DIR。除了变量前缀变得不一样(PythonLibs -> PYTHON),后缀也变得不标准(PYTHON_INCLUDE_PATH and OPENGL_INCLUDE_DIR vs *_INCLUDE_DIRS)。在这种情况下你就需要使用 INCLUDE_DIRS 选项和 LIBRARIES 选项了。
CATKIN_DEPENDS 选项和 DEPENDS 选项十分相似,但是你只能在其列表中放置 catkin 程序包。将 catkin 依赖设置为一个单独的选项的好处是可以让 catkin 执行一些额外的检查,然后警告你有什么不妥的做法。

cmake_minimum_required(VERSION 2.8.3)
project(foo)

find_package(Boost REQUIRED COMPONENTS
  system
  thread
)

find_package(PythonLibs REQUIRED)
find_package(OpenGL REQUIRED)

find_package(catkin REQUIRED COMPONENTS
  rosconsole
  roscpp
)

include_directories(
  include
  ${catkin_INCLUDE_DIRS}
  ${OPENGL_INCLUDE_DIR}
  ${PYTHON_INCLUDE_PATH}
)

catkin_package(
  INCLUDE_DIRS include ${OPENGL_INCLUDE_DIR}
  LIBRARIES foo ${OPENGL_LIBRARIES}
  CATKIN_DEPENDS roscpp
  DEPENDS Boost
)

此例中你可以看到我 find_package(Boost…) 并将它传递给 catkin_package() 的 DEPENDS 部分,因为它生成的是兼容 CMake 的变量。我 find_package(PythonLibs…) 并在内部使用它,但是不用将它传递给 catkin_package(),因为我没有在我任何导出的头文件中包含它。我 find_package(OpenGL…) ,由于它不是兼容 CMake 的变量,所以我将其显示地传递给 catkin_package() 的 NCLUDE_DIRS 和 LIBRARIES 部分。最后,我 find_package(catkin … rosconsole roscpp,并在内部使用,但是我可能只在 .c* 文件中使用了 rosconsole,因此我不用传递它,所以 catkin_package() 的 CATKIN_DEPENDS 部分我只需放入 roscpp。
最后要说明但是,如果一个程序包有直接使用像 Boost 这样的依赖项,那么它们应该确保用 find_package(…) 显示地查找它,而不是通过其他包隐式地依赖于它。举个这样的例子,如果程序包 foo 将 Boost 作为依赖项导出,又有程序包 bar 依赖于 foo,但也在内部使用 Boost,那么 bar 即使在没有显示依赖 Boost 的情况下也能编译正常。 但后来 foo 可能决定重构并删除了它对 Boost 的依赖,那么现在 bar 将无法编译,因为它不再具有通过 foo 传递来的对 Boost 的隐式依赖。

总结:
catkin_package 就是导出本功能包所依赖的功能包 供给外部功能包查找本功能包时使用。
depend_package 本功能包依赖的功能包
current_package 本功能包
father_package 父功能包依赖本功能包

当本功能包中
catkin_package(
  DEPENDS depend_package
)
在父功能包中查找本功能包就间接能找到本功能包依赖的依赖功能包.
find_package(catkin REQUIRED COMPONENTS current_package)

参考:https://blog.csdn.net/lcc816/article/details/82962561

- catkin 之launch文件

<node pkg="lslidar_c32_driver" type="lslidar_c32_driver_node" name="lslidar_c32_driver" output="screen" >

package可以说是ROS的细胞,pkg就(文件夹)细胞的名字,lslidar_c32_driver,type就是可执行文件的名字lslidar_c32_driver_node,name可以自己取,仍然取lslidar_c32_driver

- catkin 之urdf文件

<?xml version="1.0"?>
<robot name="origins">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0"/>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin xyz="0 0 1"/>                                                                                        
  </joint>

</robot>

link 代表刚体
joint 代表关节
joint origin 部分:0 0 1 代表子坐标沿着父坐标方向偏移多少。实际图形如下:
在这里插入图片描述

<?xml version="1.0"?>
<robot name="origins">
  <link name="base_link">
    <visual>
      <geometry>
        <cylinder length="0.6" radius="0.2"/>
      </geometry>
    </visual>
  </link>

  <link name="right_leg">
    <visual>
      <geometry>
        <box size="0.6 0.1 0.2"/>
      </geometry>
      <origin rpy="0 0 0" xyz="0 0 0"/>
    </visual>
  </link>

  <joint name="base_to_right_leg" type="fixed">
    <parent link="base_link"/>
    <child link="right_leg"/>
    <origin rpy="0 0 0" xyz="0 0.2 0.3"/>                                                                        
  </joint>

</robot>

在这里插入图片描述上面可以看出ros rviz的坐标系: 左右 是y轴, 前后是x轴,上下是z轴

Makefile 知识点

Makefile中的%表示通配符,而*表示任意字符
举例,%.o表示匹配所有的.o文件,注意是用于匹配的。
*.o是表示所有的.o文件。

%.o:%.cpp
	g++ -c $< -o $@

用途方面:前者一般用作目标,后者一般用作删除
注意:
$@: 表示规则中的目标
$<: 表示规则中的第一个条件
$^: 表示规则中的所有条件, 组成一个列表, 以空格隔开,如果这个列表中有重复的项则消除重复项。

  • Makefile之wildcard
    src = $(wildcard *.c) //找到当前目录下所有后缀为.c的文件,赋值给src
  • Makefile之patsubst
    obj = $(patsubst %.c,%.o, $(src)) //把src变量里所有后缀为.c的文件替换成.o
  • Makefile之 @
    “-”此条命令出错,make也会继续执行后续的命令。如:“-rm main.o”
    “@”不显示命令本身,只显示结果。如:“@echo clean done”
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值