Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Proposal: remove major version number from gazebo package names #1244

Open
scpeters opened this issue Jan 22, 2025 · 9 comments
Open

Proposal: remove major version number from gazebo package names #1244

scpeters opened this issue Jan 22, 2025 · 9 comments

Comments

@scpeters
Copy link
Contributor

scpeters commented Jan 22, 2025

Background

Currently we include the major version number of a Gazebo package in its package name. This allows multiple versions of packages to be installed side-by-side but induces churn each year when releasing new versions and when users upgrade to new versions.

Proposal

Remove the major version from Gazebo package names, including the following places:

  • The first argument to cmake project() invocations in the root CMakeLists.txt should not include the major version number. For example: project(gz-utils4 VERSION 4.0.0) should instead be project(gz-utils VERSION 4.0.0)
  • The //package/name field in package.xml files should not include the major version number. For example: <name>gz-utils4</name> should instead be <name>gz-utils</name>
  • The major version number should not be used when finding a package with cmake’s find_package() function. For example: find_package(gz-utils4 REQUIRED COMPONENTS log) should instead be find_package(gz-utils REQUIRED COMPONENTS log)
  • The debian package names should not include the major version: sudo apt install libgz-utils-dev
  • One Homebrew formula shall be defined without a major version; versioned formulae may be defined with an @ character preceding the version number
    • brew install gz-utils
    • brew install gz-utils@3
  • Python import statements should not include the package major version. For example: import gz.math9 should instead be import gz.math

A consequence of this is that multiple versions of a gazebo package will no longer be side-by-side installable in the same prefix. To support multiple versions of Gazebo on the same system, they can be installed in different prefixes in several ways:

  • Similar to ROS, build binaries that install to /opt (such as /opt/gazebo/jetty)
  • Build gazebo in colcon workspaces

Not all instances of a string containing a package name with major version necessarily need to be changed. For example, release branch names (like gz-utils3) and gazebodistro files (like gz-utils3.yaml) may be ok as is.

Alternatives considered

Continue with the current naming scheme.

@traversaro
Copy link

I am really in favor of this proposal. Side-by-side installation of major version is a really cool feature, but it requires a non-trivial amount of work both on the gazebo maintainers, and (and that is probably the biggest problem) in downside usage of the library.

For example, if you want to support both Harmonic and Ionic in CMake in a project, you need some really non-trivial CMake code (like https://github.com/robotology/gz-sim-yarp-plugins/blob/c1654a9f65a535c353c5486e2a5445a4c4a2f268/CMakeLists.txt#L10-L40), and the situation gets even trickier if you directly use many gz-* libraries. Even worse, the major version even leaks in Python code:

import gz.math8

print("PI in degrees = {}\n".format(gz.math8.Angle.PI.degree()))

a1 = gz.math8.Angle(1.5707)
a2 = gz.math8.Angle(0.7854)

so, even in Python you need a non-trivial amount of import logic to support multiple major versions of the same time.

To support multiple versions of Gazebo on the same system, they can be installed in different prefixes in several ways:

  • Similar to ROS, build binaries that install to /opt (such as /opt/gazebo/jetty)
  • Build gazebo in colcon workspaces

They are not an official supported installation method for gz-* libraries, but just to mention using environment or project oriented package managers like conda, pixi or nix can also be useful to have multiple versions of Gazebo in the same system. With this proposal, we just remove the possibility of installing multiple gazebo versions in the same environment or project, but that is not a particularly useful feature in my experience.

@scpeters
Copy link
Contributor Author

Even worse, the major version even leaks in Python code:

import gz.math8

print("PI in degrees = {}\n".format(gz.math8.Angle.PI.degree()))

a1 = gz.math8.Angle(1.5707)
a2 = gz.math8.Angle(0.7854)

so, even in Python you need a non-trivial amount of import logic to support multiple major versions of the same time.

excellent point; I'll add the python import statements as a place that should be changed as well

@scpeters
Copy link
Contributor Author

I've added this proposal to the agenda for the next weekly Gazebo PMC meeting for discussion

As a proof of concept, I will try implementing these changes for the main branches of gz-sim and gz-launch

@j-rivero
Copy link
Contributor

Thanks for the proposal. I think that it is a good moment to re-think about it since it will approach Gazebo to a more standard or common way of handling software versions.

Side-by-side installation of major version is a really cool feature, but it requires a non-trivial amount of work both on the gazebo maintainers, and (and that is probably the biggest problem) in downside usage of the library.

Let's try to figure out what are the goals of making such movement. As @traversaro mentions here, there is a clear benefit from the maintenance point of view. That is a nice indirect benefit for the users but if I'm not wrong we are reducing the number of options available for the majority of the .deb users out there.

With this proposal, we just remove the possibility of installing multiple gazebo versions in the same environment or project, but that is not a particularly useful feature in my experience.

A consequence of this is that multiple versions of a gazebo package will no longer be side-by-side installable in the same prefix.

If I'm not missing something, this change implies that with the current Filesystem Hierarchy Standard (FHS) approach of installing the assets in the different system directories our Gazebo releases needs to be Unique per Linux version. So if Gazebo Ionic is on Noble we can not release Gazebo Jetty on Noble.

So removing the side-by-side installation also removes the option of upgrading the base system (Jammy to Noble) without having to change the Gazebo version. Not the end of the world (the approach is common in the software world) but a reduction in the number of features that Gazebo installation support.

I assume that also this 1 to 1 relationship between Gazebo Releases and Ubuntu versions would need to be in sync with ROS 2 so both installation options (via ROS or via .debs) brings the same Gazebo version into a given Ubuntu version.

Other random notes:

  • release.py logic would need to be updated heavily
  • We would need new -release repositories (or other kind metadata repositories)
  • Stability in Brew: if users or other formulas relies on using the non versioned formulas, at some point an update will bring new incompatible API/ABI gz libs to their system in an standard update?

As a final thought: I think that one of the strong points for Gazebo is that users can install it easily and through different and modern packaging systems. This includes using .deb packages directly, ROS packages for ROS users, Conda packages for Conda users (and also as a wildcard in many other platforms) and we probably need to start looking into Bazel and Nix. Reducing the work needed to make Gazebo to work in new packaging systems should probably be a priority and would bring new ways of installing alternative Gazebo releases in a single platform.

@scpeters
Copy link
Contributor Author

With this proposal, we just remove the possibility of installing multiple gazebo versions in the same environment or project, but that is not a particularly useful feature in my experience.

A consequence of this is that multiple versions of a gazebo package will no longer be side-by-side installable in the same prefix.

If I'm not missing something, this change implies that with the current Filesystem Hierarchy Standard (FHS) approach of installing the assets in the different system directories our Gazebo releases needs to be Unique per Linux version. So if Gazebo Ionic is on Noble we can not release Gazebo Jetty on Noble.

So removing the side-by-side installation also removes the option of upgrading the base system (Jammy to Noble) without having to change the Gazebo version. Not the end of the world (the approach is common in the software world) but a reduction in the number of features that Gazebo installation support.

This is a good point to raise; I think it was one of the main points I made in the past when advocating for supporting side-by-side installations.

One option that preserves the FHS approach would be more complicated would be to provide separate apt sources for each Gazebo collection (Harmonic, Ionic, etc). Users would need to choose the correct apt source, and assuming they have the same package names, the newest version would be installed.

@scpeters
Copy link
Contributor Author

I assume that also this 1 to 1 relationship between Gazebo Releases and Ubuntu versions would need to be in sync with ROS 2 so both installation options (via ROS or via .debs) brings the same Gazebo version into a given Ubuntu version.

yes, I think we should coordinate with ROS to plan compatibility. Currently ROS is using vendor packages for Gazebo; do they want to go back to using libgz-* packages?

@scpeters
Copy link
Contributor Author

A short list of user-facing issues regarding installation:

  • Where to install
    • /usr (FHS approach currently used by Gazebo)
    • /opt (ROS approach)
  • How many versions of Gazebo are installable on a given Ubuntu distro
    • Usually more than 1 (current Gazebo approach)
    • Only 1
  • How many versions can be installed simultaneously on a system
    • More than 1 (current Gazebo approach)
    • Only 1

It might help to make a table to compare different approaches with one column for each of these aspects

@peci1
Copy link
Contributor

peci1 commented Feb 4, 2025

I see this in the latest PMC meeting notes:

@scpeters We could get into situations where we support multiple versions of a library and have to put in a lot of ifdefs.

I don't see how this is relevant. Even when you drop package versions from their install directories, you will still use CMake to make sure you have the proper versions.

The decision to support multiple versions of a dependency is orthogonal to this proposal.

@scpeters
Copy link
Contributor Author

scpeters commented Feb 7, 2025

@scpeters We could get into situations where we support multiple versions of a library and have to put in a lot of ifdefs.

I don't see how this is relevant. Even when you drop package versions from their install directories, you will still use CMake to make sure you have the proper versions.

The decision to support multiple versions of a dependency is orthogonal to this proposal.

That note of mine is a shortened version of me thinking out loud during the meeting about compatibility between different versions. Currently gazebosim/gz-jetty#2, searches for gz-launch without a version number, so it could now find any version that is installed. One could still specify the major version as the second argument (find_package(gz-launch 9) with whitespace instead of find_package(gz-launch9)) to clarify version compatibility, but this keeps some of the upgrade churn when bumping version numbers, just with extra whitespace.

I then thought about what happens if we don't include explicit versions in the find_package calls and thought of two cases:

  • We implicitly only support a single version, but don't enumerate that in the find_package call, but try to express it elsewhere in our packaging metadata. This could lead to more ambiguous errors related to version compatibility if people are building a workspace from source with an incompatible set of branches. Perhaps using uniform branch names (ionic, jetty, etc) like ROS would help resolve this.
  • If we don't restrict which version we find through find_package, we could try to support multiple versions, which may require #ifdefs or other version-based logic. A current example of this is gz-tools2 supporting both gz-cmake3 and gz-cmake4. This certainly adds complexity, so we'd likely need a compelling reason to do so.

In either case, I think we need to be clear about our plan for version compatibility and how to minimize confusion if we decide to relax the find_package calls to not include explicit version numbers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants