![]() The purpose of ROS-specific version of buildEnv in this overlay is to reduce the length of environment variables when using many ROS packages. However, currently it works only for ROS 1 and not for ROS 2. This commit is an attempt to fix that. Although the change looks trivial, it took me multiple full days to figure out what to change and how. The following is my understanding of how handling of environment variables works in ROS 2 and in nix-ros-overlay and why the change in this commit works. I'm not completely sure that it's all correct so feel free to complain if not. - Every ament_cmake ROS package contains a $out/share/*/local_setup.sh script, generated by ament CMake macros, which is responsible for setting environment variables required for proper function of the package under ROS 2. Every package extends AMENT_PREFIX_PATH and it may extend other variables such as PATH. The default prefix used for extending the variables is specified at compile time and is equal to package's Nix store path ($out). - local_setup.sh files are sourced when building dependent ROS packages. In nix-ros-overlay, this is accomplished by ament-cmake-core-setup-hook, which is automatically propagated to all dependents. - ROS-specific buildEnv ensures that ROS packages are not further propagated downstream but non-ROS packages are. ament-cmake-core-setup-hook is a non-ROS package (it's a Nix native package) so if any package in the buildEnv depends on it, it is propagated out of buildEnv. Therefore dependents of the buildEnv source all local_setup.sh files from the buildEnv (and from other ROS packages outside of buildEnv, if there are any). - The problem when sourcing local_setup.sh files now is the default prefix built into them, which causes every package to have a separate entry in the extended variables. However, if the file is sourced with AMENT_CURRENT_PREFIX variable set, its value overrides the default prefix. That's what we do in this commit. We set AMENT_CURRENT_PREFIX to the store path of the sourced package; in case of normal ROS packages it's equal to the default builtin prefix, but in case of buildEnv, it's different and all packages in the environment share the same prefix. I'm testing this change with the following flake.nix: { inputs = { nix-ros-overlay.url = "/path/to/repo/with/this/commit"; nixpkgs.follows = "nix-ros-overlay/nixpkgs"; }; outputs = { self, nixpkgs, nix-ros-overlay }: let pkgs = import nixpkgs { system = "x86_64-linux"; overlays = [ nix-ros-overlay.overlays.default ]; }; rosDistro = pkgs.rosPackages.humble; buildEnv = rosDistro.buildEnv { paths = with rosDistro; [ demo-nodes-cpp ]; }; in { devShells.x86_64-linux.default = pkgs.mkShell { name = "ros-env-test"; packages = [ buildEnv ]; }; packages.x86_64-linux = { default = buildEnv; inherit (rosDistro) demo-nodes-cpp; }; }; } Running `nix develop` and then: echo $AMENT_PREFIX_PATH | tr : \\n | wc -l without this commit returns 71 entries, while with this commit the result in a single entry! |
||
---|---|---|
.github | ||
distros | ||
docs | ||
examples | ||
lib | ||
modules | ||
pkgs | ||
.gitignore | ||
default.nix | ||
flake.lock | ||
flake.nix | ||
LICENSE | ||
overlay.nix | ||
README.md | ||
release.nix |
ROS overlay for the Nix package manager
Easily install the Robot Operating System (ROS) on any Linux distribution
Want to use ROS, but don't want to run Ubuntu? This project uses the power of Nix make to it possible to develop and run ROS packages in the same way on any Linux machine.
Nix is a distro agnostic package manager that uses a purely functional programming language to reliably and reproducibly build software. These qualities have the potential to make it one of the easiest ways to run ROS on any machine, no matter the operating system.
This overlay is still experimental, so you may encounter some issues. Feel free to file a bug.
Setup
- Install Nix: https://nixos.org/nix/download.html
- (Optional) configure Nix to use ROS Cachix binary cache
- Try one of the examples
Examples
Turtlebot 3 simulation in Gazebo:
nix-shell \
-I nix-ros-overlay=https://github.com/lopsided98/nix-ros-overlay/archive/master.tar.gz \
--option extra-substituters 'https://ros.cachix.org' \
--option trusted-public-keys 'cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ros.cachix.org-1:dSyZxI8geDCJrwgvCOHDoAfOm5sV1wCPjBkKL+38Rvo=' \
'<nix-ros-overlay/examples/turtlebot3-gazebo.nix>'
# If not on NixOS, nixGL (https://github.com/guibou/nixGL) is needed for OpenGL support
roslaunch turtlebot3_gazebo turtlebot3_world.launch
# Spawn a new nix-shell in a new terminal and then:
roslaunch turtlebot3_teleop turtlebot3_teleop_key.launch
With Flakes enabled, the equivalent of the above is:
nix develop github:lopsided98/nix-ros-overlay#example-turtlebot3-gazebo
# Then use roslaunch commands as above
Current status
What works:
- More than 1400 packages successfully built for ROS Noetic
- Fully functional ROS development environment using
nix-shell
- Automated generation of Nix package definitions using standard ROS tools (superflore)
What still needs to be done:
- Upstream changes to nixpkgs and ROS tools
- Test on more Linux distributions
- aarch64 binary cache
- macOS support
Configure Binary Cache
Prebuilt ROS packages are hosted on Cachix and built using GitHub Actions on public infrastructure.
To use this binary cache, either run cachix use ros
or manually set the following options in nix.conf
:
substituters = https://cache.nixos.org https://ros.cachix.org
trusted-public-keys = cache.nixos.org-1:6NCHdD59X431o0gWypbMrAURkbJ16ZPMQFGspcDShjY= ros.cachix.org-1:dSyZxI8geDCJrwgvCOHDoAfOm5sV1wCPjBkKL+38Rvo=
Frequently Asked Questions
Q: Why are some packages missing?
A: All ROS packages published in the package index are potentially available in this overlay. If a package is missing, that probably means one of its system dependencies is not packaged. To determine the offending dependency, find the last "rosdistro sync" PR in this repository and search the missing dependencies list for your package's dependencies. In some cases, you may only need to add a mapping between the rosdep key and the nixpkgs attribute to the rosdistro YAML files. If there is no Nix expression for the package, you should try to package it and submit it upstream to nixpkgs. In some cases it may be appropriate to add the package to this overlay instead, but this should be avoided if possible.
Q: Why do some packages fail to evaluate?
A: Some packages fail to evaluate with a error like the following:
at: (69:16) in file: /nix/store/7cy8wbxh0jmsy00219hi9pkrqm9lsh5j-source/lib/customisation.nix
68| let
69| result = f origArgs;
| ^
70|
anonymous function at nix-ros-overlay/distros/<distro>/<package>/default.nix:5:1 called without required argument '<dependency>'
This means all the system dependencies of <package>
were available, so its Nix expression was generated, but some of <dependency>
's system dependencies were missing. See the question above for what to do next.
Q: Why do some packages fail to build?
There are thousands of ROS packages, so it is infeasible to make sure every package builds. I generally aim to keep at least 80-90% of the packages in a distribution successfully building, but this percentage tends to decrease as distributions get older and develop incompatibilities with newer software. If a package you need does not build, please open an issue or try to fix it yourself. In many cases, build failures occur due to bugs in the packages themselves, and should be fixed upstream. In other cases, overrides may need to be added to this overlay to fix the auto-generated expressions.