Environment created with buildEnv behaves differently as a system package

I am new to Nix with less than a week of experience, so don’t be afraid to over-explain things to me.

I am working on a little robotics project to see if I can develop robot software on my desktop, run it in a local environment there for quick testing, but then export it to a Raspberry Pi. I can export to the pi by generating an SD card image or updating an already running pi over ssh. So far I’m loving this development workflow.

Here’s my repository. It’s mostly working. I need to write proper documentation.

My environment.nix behaves correctly when used by mkShell, all expected libraries and executable are available in the shell it creates.

When exporting to my Raspberry Pi I don’t use mkShell, but instead use the output of environment.nix as a system package. For some reason only ROS packages are available in that environment. None of the ones provided by nixpkgs or my custom one used for a voice model are available on the Pi.

In my experiments I’ve made two observations that I think are hints to what I’m doing wrong.

  1. Even though the packages aren’t available, I can find them in the nix store on the pi. It seems they were uploaded during the deployment but the needed environment variables weren’t defined.
  2. If I take those packages and place their names directly into the system packages list, they’ll be included on the Raspberry Pi as expected.

Some things to note that are special about this repository:

  • That’s not the normal buildEnv, it’s a special one provided for ROS packages. To not use it results in the opposite issue: Normal packages are available but ROS packages are not.
  • I haven’t found an example of using buildEnv but it was suggested I should be using it in this issue.
  • I have found examples of ROS packages depending on nixpkgs.

I’m not sure whether what you were trying to achieve is for reuse or mostly for self-education, but at least for the reuse case, I would consider collaborating with others who have focused on this device, such as @proofconstruction to see whether you could contribute to a single project and learn from each other.

I’m happy to work with people who know more than me. :grinning:

My goal is that I want to take ROS and integrate it into the Home Assistant platform the way ESPHome has integrated the Arduino ecosystem into Home Assistant. ESPHome enables people to make nifty IoT gadgets. ROS would enable people to make full on robots.

If you look into ESPHome, the first thing you’ll notice is that the whole system is very declarative (each device is defined with a yaml file). The other thing is that while you have to initially flash your microcontrollers, updating over wifi is easy.

I want both of these things but for ROS. I’m using the Raspberry Pi because I expect it to be a popular device for this use case, but I also expect small x86 machines, RISCV, and other single board computers to be popular. Cross compiling is a valuable feature.

This project here is just the proof of concept, and I’m not even writing good quality nodes for it. I plan to just make a clock that speaks the time.

I finally found a solution. I don’t think it’s a great solution, but none the less, it does work.
The key issue was that XDG_DATA_DIRS was not having the path to my package’s share directory appended to it. I suspect the reason is that nix-ros-overlay is not properly sourcing my setup-hook file. I have mentioned this in an issue I opened with the maintainer of that repository.

My solution was to just do as the Romans do while in Rome. I made my package into a ROS package.
Here’s my implementation

Nix is cool, ROS is clunky. Hope someone suffering like I did finds this and finds the answer helpful.