tl;dr: compare the CMakeLists.txt
/ package.xml
situation with GNU Makefiles / Debian control
files: both (partly) contain the same information, but neither covers everything needed to be able to successfully build packages. To facilitate automated build systems and information extraction, machine readable file formats are highly preferable to the complex dynamic constructs allowed in most build scripts. Additionally, dependency declaration and resolution can benefit from a slightly higher level of abstraction, especially when dealing with from-source builds on multiple different platforms and OSs.
longer:
For a package all the link-time and run-time dependencies are already described inside the CMakeLists.txt, so why do we need to re-state these dependencies inside the package.xml?
First: CMakeLists.txt
is a build script, it does not explicitly express the run dependencies of the targets that get built. Yes, it's likely that you'll need at least the (dynamic) libraries that you linked to, but that doesn't tell you where those libraries can be found. Also, some libraries are header only and will not be needed any more after compilation. CMake has no system in place to express that kind of information.
The wiki/catkin/CMakeLists.txt page, under the Finding Dependent CMake Packages section also hints at this:
NB: You should only find_package components for which you want build flags. You should not add runtime dependencies.
package.xml
contains meta-data (in addition to the dependency declarations you identified): things not necessarily needed for building (or even running) a package, but still nice to have around in a central place. Examples would be author
, maintainer
, url
, description
and license
. These are used on the ROS wiki, and are displayed on a page that uses the PackageHeader(..)
macro. See REP-127 for more info.
Firstly the information seems redundant and secondly when is the information inside package.xml used? What is it used for?
Where CMakeLists.txt
and package.xml
seem to overlap, is the declaration of build, run and test dependencies. The thing to understand though, is that a 1-to-1 relationship between things you need to build and things you need to run does not necessarily exist. This - coupled with the fact that the CMake language is a rather complex language to parse (because of branching, conditional includes, macros, functions, etc), no standardised naming scheme for files, libraries or their distribution archives, differences between platforms and coding styles - makes it all very hard to reliably extract the necessary information from build scripts alone.
Because of this, systems like the ROS buildfarm require extra (and more machine readable) information to be able to install all the right dependencies while setting up a working build environment. And - after a successful build - to correctly list all run dependencies in the debians (or RPMs on Fedora) that you install using apt-get
. That is where package.xml
comes in.
Another important benefit of having that information in a format other than a build script is that it allows a certain amount of abstraction, making cross-platform support easier. For some more comments on that, please see why rosdep instead of others?.
Edit: clarified why a machine readable file format is highly preferable to parsing complex, dynamic CMake build scripts.
Edit2:
Now there is still something I am missing: the package.xml page states that
If they are missing or incorrect, you may be able to build from source and run tests on your own machine, but your package will not work correctly when released to the ROS community.
Now I am not sure I understand how this mechanism works. Does it mean that the dependencies normally delt with the CMakeLists.txt when I am on my local machine are handled by ROS when I deploy my packages to the outside world?
There is no 'mechanism', it simply means that if you don't declare your dependencies properly, the package may build on your own machine (because you've manually installed whatever pkgs you need to create your nodes), but as the buildfarm doesn't know about those dependencies it will fail.
Originally posted by gvdhoorn with karma: 86574 on 2015-09-11
This answer was ACCEPTED on the original site
Post score: 24
Original comments
Comment by Dirk Thomas on 2015-09-11:
Another reason is that the CMake file is not "machine readable". It can contain arbitrary logic in CMake and can't be read without interpreting the CMake code. The XML on the other hand can easily be read.
Comment by gvdhoorn on 2015-09-11:
Yeah. I think that was partly what I was trying to express with the libfoo.so
, package Bar example. I added some clarification. Thanks.
Comment by arennuit on 2015-09-15:
Thanks for clarifying things!
Comment by 2ROS0 on 2016-08-18:
We need wiki pages for conceptual/design-choice/architecture based answers like these. Or an option to transform particular ROS answer pages into wikis (ala Stack Exchange websites).
Comment by gvdhoorn on 2016-08-18:
I'd encourage you to post these kind of sentiments/observations on discourse.ros.org and to start a discussion there. Posting them as comments on old(er) questions will lead to very few ppl reading them, as visibility is low here.