关于catkin_make xbo_face_msgs

可以catkin_make xbo_face_msgs_gencpp   单独编译生成

可以作为依莱库在后台生成。 http://answers.ros.org/question/52744/how-to-specify-dependencies-with-foo_msgs-catkin-packages/


How to specify dependencies with "foo_msgs" catkin packages

asked Jan 18 '13

cdellin gravatar image

updated Feb 7 '13

Say I have two catkin packages, foo and foo_msgs, in my workspace. Here's how I currently have them set up:

project(foo_msgs)
find_package(catkin REQUIRED COMPONENTS message_generation)
add_message_files(
  DIRECTORY msg
  FILES foomsg.msg
)
generate_messages()
catkin_package(CATKIN_DEPENDS message_runtime)
project(foo)
find_package(catkin REQUIRED COMPONENTS foo_msgs)
catkin_package()
include_directories(include ${catkin_INCLUDE_DIRS})
add_executable(foo foo.cpp)

I find that if I catkin_make foo, the message isn't generated. Indeed, catkin_make foo_msgs is a no-op. catkin_make foo_msgs_gencpp works, however. In order to get foo to build correctly, I must add the following line to its CMakeLists.txt:

add_dependencies(foo foo_msgs_gencpp)

Is this by design? I'd expect that building the package foo_msgs would automatically generate all its messages. Is there a way to make that happen?

Edit: I've approved WilliamWoodall's answer, although KruseT's was just as useful. (I also added the include_directories() line to foo's CMakeLists.txt, which I initially forgot.)

It turns out my solution is correct; the foo_msgs_gencpp auto-target should be added as a dependency of the foo target. Note that there is some disagreement about whether a different solution should be supported by catkin; KruseT started a discussion on the topic here.

Since this type of explicit dependency auto-target (_gencpp and _genpy) is necessary for using ROS messages/actions/services in any executable, library, or script, I think it should be better documented (I found no reference to it in catkin/migrating_from_rosbuild). KruseT opened a related rosdistro issue here.

3 answers

10

answered Feb 6 '13

WilliamWoodall gravatar image

updated Feb 28 '14

William gravatar image

Your projects are setup correctly (mostly), you just need to run catkin_make with no arguments.

First update foo:

cmake_minimum_required(VERSION 2.8.3)
project(foo)

find_package(catkin REQUIRED COMPONENTS foo_msgs)

catkin_package()

include_directories(include ${catkin_INCLUDE_DIRS})

add_executable(foo_node src/foo_node.cpp)
add_dependencies(foo_node foo_msgs_generate_messages_cpp)

Using add_dependencies(...) is by design or necessity, however you look at it, because we cannot know or assume that foo's targets (executables or libraries) use and therefore depend on the messages which are getting generated by foo_msgs.

Then just execute catkin_make with no arguments.

If you want to build foo_msgs explicitly (not the whole workspace) then as of pull request ros/catkin#352 you can do catkin_make --pkg foo_msgs.

Calling catkin_make foo_msgs is not sufficient because that is instructing catkin_make to invoke the foo_msgs make target which does not exist. tkruse's solution simply adds a foo_msgs target which depends on the foo_msgs_generate_messages_cpp target, allowing it to be callable and causing the foo_msgs_generate_messages_cpp target to be generated. This is not something we do by default because packages often define targets with the same name as the project which would immediately cause a conflict.

The only reliable way to build an entire package (including all of its targets) is to go to the package's build space and invoke make [all], which is what catkin_make --pkg does.

I setup an example repository here:

https://github.com/wjwwood/catkin_dem...

link

Comments

1

Hi WilliamWoodall, this is very helpful! Clearly the _gencpp dependency needs to go somewhere explicitly. You list it in foo's CMakeLists file. In that case, if foo_msgs is already installed (so catkin is only building foo), will the foo_msgs_gencpp dependency be correctly resolved by catkin?

cdellin gravatar image cdellin  (Feb 6 '13)
1

Yes, CMake will ignore targets which are not defined, you could add add_dependencies(foo_node bar_does_not_exist) and it will build with no warnings.

WilliamWoodall gravatar image WilliamWoodall  (Feb 6 '13)

Great! This is my favorite solution, since it doesn't introduce new targets (foo_msgs), and explicitly encodes the dependency between the foo (binary) target and the generated cpp messages.

cdellin gravatar image cdellin  (Feb 7 '13)

Also, I want to stress about catkin_make arguments: (a) sometimes it is useful to build only particular targets (yes, targets, not packages), and (b) running catkin_make with no arguments doesn't help here; the _gencpp target is still required to ensure targets are built in the correct order.

cdellin gravatar image cdellin  (Feb 7 '13)

(a) building specific target is already supported by "catkin_make", any argument without a special meaning is passed straight forward to "make", see "catkin_make --help" for details.

Dirk Thomas gravatar image Dirk Thomas  (Feb 7 '13)

Hi Dirk! I understand this, I just wanted to correct the answer. I believe that WilliamWoodall's assertion that "running catkin_make with no arguments" would somehow fix my problem is incorrect.

cdellin gravatar image cdellin  (Feb 7 '13)
11

answered Aug 29 '13

updated Aug 29 '13

I believe the modern way of doing this is to add a dependency on ${catkin_EXPORTED_TARGETS}, as specified on this documentation page. It should look something like this:

find_package(catkin REQUIRED COMPONENTS foo_msgs)

add_dependencies(your_program ${catkin_EXPORTED_TARGETS})
add_dependencies(your_library ${catkin_EXPORTED_TARGETS})
link

Comments

You should check that `${catkin_EXPORTED_TARGETS}` is set to something before passing it to `add_dependencies(...)`.

William gravatar image William  (Aug 29 '13)

https://gist.github.com/wjwwood-snippets/5979727

William gravatar image William  (Aug 29 '13)

Doesn't the fix for this issue make this check redundant? https://github.com/ros/catkin/issues/453

kalakris gravatar image kalakris  (Aug 29 '13)

Ah yes, I forgot we added that.

William gravatar image William  (Aug 29 '13)
2

The documentation link above is broken. The page can be found here.

Neil Traft gravatar image Neil Traft  (Aug 8 '14)
2

answered Jan 18 '13

KruseT gravatar image

updated Feb 7 '13

catkin_make with an argument just passes that argument to make. That a make target for the package exists is more by chance than design, I'd guess it is added by cmake for each subfolder (but not with nested folders). Maybe you can open a ticket on github to add the feature of a dedicated target to make. However a small problem exists, frequently a package named foo defines an executable named foo, so the target names overlap each other. Not sure whether any clean solution is possible. At least it wont be straightforward.

What you can do to cause "make foo_msgs" not be a noop is in package foo_msg, add a dependency like this:

add_custom_target(${PROJECT_NAME} DEPENDS ${PROJECT_NAME}_gencpp)

which is equivalent to

# add_custom_target(foo_msgs DEPENDS foo_msgs_gencpp)

but easier for copy&paste

[Update3: this is wrong:

Update: add_dependencies is definitely the wrong way to go, the way you use it (in foo, add dependency to foomsg). add_dependency should never cross catkin project boundaries. For you it only works coincidentally (because catkin cheats cmake conventions), it will break build in other cases or when building the projects in isolation.]

Update3: So it seems that indeed currently, calling add_dependencies accross package boundaries it currently the only recommendable way to achieve that the headers generated by foo_msg exist before they are being consumed by a target in foo.

We'll discuss this in the buildsystem SIG and maybe there will be a cleaner solution in the future.Discussion here: https://groups.google.com/d/topic/ros-sig-buildsystem/dvVO5QCHBLM/discussion

link

Comments

Ok, so the add_dependencies(foo foo_msgs_gencpp) solution is the right way to go?

cdellin gravatar image cdellin  (Jan 18 '13)

Apologies kruset, I'm still confused. What exactly should I add to my CMakeLists file(s) for this example? I haven't found anything but the _gencpp dependency (across catkin project boundaries) to work.

cdellin gravatar image cdellin  (Feb 6 '13)

There is no reason to call catkin_make with arguments... You are not telling catkin_make what packages you want to build you are just passing targets to make, and the project target and executable/library targets can overlap. It is better to just invoke catkin_make with no arguments.

WilliamWoodall gravatar image WilliamWoodall  (Feb 6 '13)

I partially agree and partiall disagree, WilliamWoodall. Yes, clearly the user of catkin should be aware that catkin_make targets correspond directly with executable/library targets. I've found it very useful to only make/remake particular targets during development for compilation time purposes.

cdellin gravatar image cdellin  (Feb 6 '13)
1

kruset, thanks for the clarification; this appears to be the best solution I've found. Perhaps it should go in a tutorial? Setting up this type of package structure (foo and foo_msgs) seems to be a very standard practice, and that I had such a hard time getting it to work properly is unfortunate.

cdellin gravatar image cdellin  (Feb 6 '13)

The reason caktin_make foo_msgs is a no-op is that there is no make target for a package by default. In stead there is a Makefile for each time project(...) is called in CMake. The correct thing to do in order to build a package is to go to its location in the build folder and invoke make.

WilliamWoodall gravatar image WilliamWoodall  (Feb 6 '13)

In my example, if I run: cd build/catkin_demos/foo_msgs && make all of the messages are generated. This is basically what catkin_make --pkg foo_msgs will do: https://github.com/ros/catkin/pull/352

WilliamWoodall gravatar image WilliamWoodall  (Feb 6 '13)

Regarding documentation, I opened https://github.com/ros/rosdistro/issues/439.

KruseT gravatar image KruseT  (Feb 7 '13)


<think>嗯,用户想优化和加速catkin_make的构建时间。首先,我需要回忆一下关于catkin_make的相关知识。根据引用[4],catkin_make_isolated是按顺序处理所有包,速度较慢,但更可靠。而catkin_make可能没有充分利用并行构建。那优化的话,首先应该考虑并行编译。 对了,用户可能已经知道使用`-j`参数来指定并行任务数,比如`catkin_make -j4`,但需要根据CPU核心数调整。这个应该是比较基础的优化方法,需要提到。另外,如果项目中有很多包,可以单独编译修改过的包,避免每次都全量构建,这样也能节省时间。比如用`catkin_make --pkg package_name`,这部分在引用[5]提到过重新编译整个工作空间,但单独编译可能更高效。 然后是依赖管理。如果工作空间中的包依赖关系混乱,catkin_make可能会重复构建不必要的包。用户应该确保每个包的package.xml正确声明依赖,这样可以减少重复构建。引用[2]里提到catkin_make会按依赖关系正确构建,所以正确声明依赖很重要。 另外,清理中间文件也是个办法。有时候旧的构建残留可能导致不必要的重新编译,定期清理build和devel目录可能有效。不过要注意这会触发全量重建,所以可能更适合在确定需要的时候使用。 还有,使用更高效的构建工具。比如catkin_tools,它支持并行构建和选择性编译,可能比catkin_make更快。引用[4]提到catkin_tools是更现代的替代品,支持并行构建。用户可以考虑迁移到catkin build,这样可以提升速度。不过用户可能需要学习新工具的使用方法。 硬件方面,使用SSD或者增加内存也能加快编译速度,尤其是涉及大量IO操作的时候。这个虽然和软件优化无关,但也是实际可行的建议。 另外,禁用调试符号,比如在catkin_make时添加`-DCMAKE_BUILD_TYPE=Release`,可以减少编译时间和生成的文件大小。不过可能会影响调试能力,需要权衡。 还有,检查是否有大型未优化的包,比如某些第三方库可能编译时间很长,可以考虑预编译好的二进制包来替代源码编译。这样也能节省时间。 最后,保持ROS版本和依赖项的更新,可能修复了某些构建效率的问题。定期更新系统也是有帮助的。 总结下来,可能的优化方法包括并行编译、单独编译修改的包、正确管理依赖、清理中间文件、使用catkin_tools、硬件升级、调整编译选项、预编译依赖库以及保持系统更新。需要把这些整理成步骤,用中文清晰表达,并生成相关问题。</think>### 如何优化和加速 `catkin_make` 构建时间 #### 1. **启用并行编译** `catkin_make` 默认使用单线程编译。通过添加 `-j` 参数指定并行任务数,可显著缩短构建时间。例如,若CPU有4个核心,可使用: ```bash catkin_make -j4 ``` 注意:任务数不应超过CPU核心数,避免资源争用[^4]。 #### 2. **仅编译修改的包** 若仅修改了特定包,可单独编译该包而非整个工作空间: ```bash catkin_make --pkg <package_name> ``` 此方法跳过未修改的包,减少冗余编译[^5]。 #### 3. **清理中间文件** 定期清理 `build` 和 `devel` 目录中的中间文件,避免旧文件干扰: ```bash rm -rf build devel catkin_make ``` 但全量清理会触发完整重建,建议在依赖关系混乱时使用[^2]。 #### 4. **优化依赖管理** 确保每个包的 `package.xml` 正确声明依赖,避免因依赖缺失导致重复构建。例如: ```xml <depend>roscpp</depend> ``` 清晰的依赖关系可帮助构建系统跳过不必要的包[^2]。 #### 5. **使用 `catkin_tools` 替代** `catkin_tools` 支持并行构建和增量编译,效率更高。安装后使用: ```bash catkin build ``` 其按依赖关系并行编译包,且支持选择性构建。 #### 6. **调整编译选项** 禁用调试符号以减少编译时间: ```bash catkin_make -DCMAKE_BUILD_TYPE=Release ``` 或在 `CMakeLists.txt` 中设置优化级别[^5]。 #### 7. **预编译第三方依赖** 若项目包含大型第三方库(如PCL、OpenCV),优先使用系统预编译的二进制包: ```bash sudo apt install ros-<distro>-<package> ``` 避免从源码构建耗时[^3]。 #### 8. **硬件优化** - 使用SSD替代机械硬盘,加速文件读写。 - 增加内存容量,避免交换分区拖慢速度。 #### 9. **分離开发环境** 将高频修改的包与稳定包分到不同工作空间,减少无关构建。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值