0
$\begingroup$

Rosanswers logo

Summary

Using $ catkin build my_node, the reconfigure headers are not generated on some computer (even though the build works on others). It just seems like generate_dynamic_reconfigure_options() is ignored.

More details

I have a node using catkin and a CMakeLists.txt (i.e. not rosbuild), successfully building from an Ubuntu 16.04 docker container. When I follow exactly all the steps of the "working" Dockerfile into a brand new Ubuntu 16.04 install in VirtualBox, catkin fails with the following error:

Errors     << my_node:make /root/catkin_ws/logs/my_node/build.make.008.log                                          
In file included from /root/catkin_ws/src/my_node/src/nodes/path_handler_node.cpp:1:0:
/root/catkin_ws/src/my_node/src/nodes/path_handler_node.h:16:50: fatal error: my_node/PathHandlerNodeConfig.h: No such file or directory
compilation terminated.
make[2]: * * * [CMakeFiles/path_handler_node.dir/src/nodes/path_handler_node.cpp.o] Error 1
make[1]: * * * [CMakeFiles/path_handler_node.dir/all] Error 2
make: * * * [all] Error 2

From what I observe in the working config (the docker container), I expect PathHandlerNodeConfig.h to be generated in devel/my_node/PathHandlerNodeConfig.h, but it is not. However, cfg/path_handle_node.cfg is present in the generate_dynamic_reconfigure_options(...) in the CMakeLists.txt of my_node, and there are dynamic_reconfigure build_depend and run_depend in "package.xml". Again, it works on other computers.

One could be the reason for the config file to not get generated? How could I get more information about what is happening? The error I get says that the config header is missing, but there is no complaint at the time of generating it (if generation is ever started). $ catkin build --verbose my_node doesn't seem to say anything about the dynamic_reconfigure generation, either.

I have created a small test node following this tutorial and the header file is correctly generated, which makes me even more confused: my code works on other platforms, and this platform that fails with my code works for a small example...

UPDATE:

After a lot of testing, I realized that the config headers are generated when I remove the last two commands of the CMakeLists.txt:

add_executable(path_handler_node src/nodes/path_handler_node.cpp)
target_link_libraries(path_handler_node ${catkin_LIBRARIES})

I would expect the config headers to be generated before path_handler_node gets compiled (I guess that's the whole point, right?). And because they are not, I get the build error above.

And the problem is really that somehow, the headers are not generated at the right time: if I comment out the two lines above and build, I get the headers generated. Then, if put back the two lines above and compile again, it works...


Originally posted by JonasVautherin on ROS Answers with karma: 3 on 2018-03-18

Post score: 0

$\endgroup$

1 Answer 1

0
$\begingroup$

Rosanswers logo

As you haven't posted your CMakeLists.txt, we can only guess.

But what you describe sounds like a race condition. The effect being that sometimes the dynamic reconfigure headers are created before, and sometimes after your node is being built. Thus, the build fails or succeeds on some platforms. Actually, both could happen in the same Workspace.

You need to tell cmake that your executable requires the headers. This can be done easily with the following line

add_dependencies(path_handler_node ${${PROJECT_NAME}_EXPORTED_TARGETS} ${catkin_EXPORTED_TARGETS})    

(the ${catkin_EXPORTED_TARGETS} is actually not for your specific problem, but it is something that could help in resolving some other sporadic build issues).

This obviously fits what you found out, i.e. if you generate the headers before (by uncommenting the executable), the build after that works.

See also the catkin documentation on dynamic_reconfigure.


Originally posted by mgruhler with karma: 12390 on 2018-03-19

This answer was ACCEPTED on the original site

Post score: 3


Original comments

Comment by gvdhoorn on 2018-03-19:
re: adding catkin_EXPORTED_TARGETS: that's a bit cargo cult-ish. I wouldn't add that unless it's needed.

Otherwise +1.

Comment by gvdhoorn on 2018-03-19:
Note that having to use add_dependencies(..) is also explained in the tutorial linked, in the Use the cfg File section at the end of the page.

Comment by mgruhler on 2018-03-19:
@gvdhoorn: I muss confess, I never really understood what catkin_EXPORTED_TARGETS is for. Nobody was able to really provide a nice explanation. So if you could shed some light on this, I'd be happy to learn.

As I just learned a new phrase: "cargo cult-ish" :-D

Comment by JonasVautherin on 2018-03-19:
@gvdhoom is right in that there is mention of add_dependencies(my_node ${PROJECT_NAME}_gencfg) in my tutorial, but I must say I did not understand it. I thought it meant that I needed to do further operations (like add_executable) after the line generating the files.

Comment by JonasVautherin on 2018-03-19:
As often, documentation is clearer once the problem is solved :-). This answer solves my problem, and my_node_gencfg is part of ${${PROJECT_NAME}_EXPORTED_TARGETS}, indeed. Now I know it :-).

Comment by gvdhoorn on 2018-03-19:
It's a bit of a standard reponse to this sort of thing, but: the ROS wiki is just that, a wiki. You, as a beginner, have a unique perspective on things and are in the best position to suggest better ways to document this. Please register for an account and update the tutorial if possible.

Comment by JonasVautherin on 2018-03-21:
I have been trying of a better way to document that, but I think if I had been the one writing the CMakeLists.txt from the beginning, I would have understood the documentation. In my situation, I was trying to debug an already existing system, so anyway it is not easy for a beginner...

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.