That’s a pretty good summary of the immediate pros and cons. When I think about these decisions there are a few other higher level things I think about as well.
My top priority is to maintain compatibility with the goal of minimizing overall work. For any of these cases we can either choose to modify the dependency, or change our code to be backwards/downwards compatible. In this case with the package on the cusp of being packaged upstream both approaches would work. However if the package in question was a lower level dependency with several packages depending on it if we choose to upgrade the package in a non-abi compatible way we would either have to choose to conflict with all it’s dependencies or else rebuild replacement versions of them, greatly increasing the required work.
Thus we generally have a policy that if a package is released upstream we use the version there. This make sure we’re compatible with everything else in that distro. This is the point of having distros so that things are known compatible.
It is typically relatively easy to release a package that builds a rosdistro specific version into
/opt/ros/. As you mention we’d need to make sure that all symbols and headers do not collide and would get appended in the right order. With appropriate patches this is not too much work. But in a case like this it’s making work both for this version and future versions as any changes needed will need to be planned to roll back/future compatible as we expect to go back to the upstream version in the future.
The biggest trap that we can fall into is to diverge from the upstream release roadmap. If we want a very specific feature and patch to add it to a custom packaged version but upstream chooses not to take the patch or implements it differently we can end up in a state where we need to maintain a diverged package continuing going forward. We’ve run into this for a couple of 3rd party packages in the past, such as xmlrpcpp and Bullet Physics Linear Math libraries, which we still maintain forks of due to diverging early in the history of ROS. Now they’re baked in deep enough that converging them on the upstream packages is more work than anyone is willing to do.
To avoid diverging we generally only repackage upstream packages by backporting newer versions. This is an example of that where we are building the version we expect to be in yakkety for xenial. This way ROS developers will not need to write their code to be compatible using fewer ifdefs or other mechanisms for multi version support. If they cannot do less comapatibility support we should not be building the custom version. Really we’re trading work patching or upgrading the upstream package and making sure it’s available on all platforms to save the ROS developers from needing to support the upstream version across the multiple platforms that rosdistros support.
The easiest cases are the backports where the package does not exist but the upstream package exists for a newer distro. Backporting it will not collide with an existing package, and the backported version should match conveniently for the developers building on top. This is the case that covers most of the custom packages we’ve pushed into the ROS repository.
In this case we were a little behind. Optimally we would have been looking ahead enough to make sure that the version of the fcl package would have been in xenial. If you pay attention early in the debian/ubuntu cycle and make sure that upstream releases are made early enough we have successfully helped make sure that debian/ubuntu has the versions of packages that we need, and that is compatible. (Many thanks to @dirk-thomas and @jrivero for their work on this front. Such as a CMake upgrade for xenail) Ultimately we don’t want to be building our own parallel distro, but want to be as closely integrated with the upstream distros as possible. Every time we choose something different causes a lot of work and adds to the ongoing maintenance burden.