ROS Resources: Documentation | Support | Discussion Forum | Service Status | Q&A

Release package requiring custom version of system dependency

I am about to start working through releasing packages provided under the ROS-Industrial Consortium GitHub Organization, but one repository in particular depends on package versions that are not release on 20.04 like FCL 0.6.0 and Bullet built with double precision. What is the recommend approach for releasing ROS packages that depend on a custom version?

It looks like this may be a good approach. They have release the latest version of FCL and I could do the same for bullet.

Isn’t that dangerous? Users can have their own code in the workspace that counts with FCL 0.5… If you pull in FCL 0.6 from your project, they wouldn’t be very happy… I guess there are two correct ways - “backport” your packages to work with the released versions (not always possible), or static linking. But never export the non-released dependencies to be visible outside your package (I hope they are build-only dependencies, because if they’re build-export dependecies, it seems pretty much impossible).

I don’t necessarily think it dangerous. Several widely used packages like vtk, llvm and others release their packages in versioned namespaces. As you pointed out if you build a package that links against two different versions of the library this will cause weird runtime failures, but CMake during the linking stage will produce warnings letting you know that it has found two of the same libraries which should not be ignored.

I believe I may be able to get away with static linking but not sure how to go about accomplishing this during the ROS release process. Currently these dependencies are included leveraging CMake’s ExternalProject_Add. Does any one know if this will cause issues during release process?

Hey, is the “particular” repository you are using as an example public? Could you give us a link? It’s always easier to have something specific to talk about :wink:

Static linking: Well, if you link the entire third-party library statically into your targets and you only have executable targets, everything should be bullet-proof. Whether you build the third-party stuff using ExternalProject or some other magic should not matter. The release process just takes the produced binaries and puts them into distro packages.

If you export libraries that are statically linked against your custom library, you might encounter problems when other packages link to it. You are right, versioned namespaces should mitigate these problems, but few libraries have those…

To start off at the top level response. In general you should not override or replace system dependencies from the distribution. This is part of the software engineering process of maintaining the distribution that all developers can rely on specific versions of software to be available and remain consistent withing the distribution. If you need newer versions of underlying libraries the you should either target newer versions with the minimum version available or if that’s not available help and encourage the upstream process to move forward to at least your minimum version for the next release of the distribution.

Obviously this is a slow process and doesn’t fix things immediately for a short term there are workarounds, however if you want to release packages which build on the workarounds you must make sure not to break other users who are expecting the system version.

To release an overlay it must:

  • Install side by side with the system one, with a different name.
  • Not cause compile errors for any packages including downstream ones
  • Not cause linking errors or crashes at runtime for yours or any downstream packages, including ones that use the system version.

The release pipeline will only catch the first issue automatically. Manual review is required for the latter two. But in general if you want to do this without being disruptive you need to adjust paths to avoid installation collisions. Change all namespaces to avoid symbol collisions. And change header paths to not collide with the system ones if you export the include directories.

Embedding a copy inside your package, potentially a statically linking a version into your executables is also a potential way to do it as well. It’s going to require a non-trivial amount of engineering and modifications to make this possible and most people decide it’s not worth it.

In many situations a common approach for this is to not actually release it onto the public distro and distribute it separately through a side channel. This will allow people to opt into the potentially disruptive change. An example of this is Ubuntu’s PPAs or just instructions for end users to compile from source.

1 Like