Source directory is being cleaned when no cleaning function is called (CraneLib)

I’m having some trouble packaging my desktop Rust app with CraneLib. I initialized the flake with Crane’s quick-start template, then added the desktopItem attribute to the craneLib.buildPackage arguments in order to add a desktop entry for my app to the user’s system. Of course, a necessary step when adding a desktop entry is to also install an icon image somewhere on the system. I borrowed from a previous iteration of the flake that was written by someone else, and added this line to the buildPackage arguments:

postInstall = "install -Dm644 NuhxBoard.png $out/share/icons/hicolor/128x128/apps/NuhxBoard.png";

However, this doesn’t work. The install command throws an error, claming that NuhxBoard.png doesn’t exist. I tried again, updating the path to $src/NuhxBoard.png. I was then able to inspect the source directory, only to find that it had been cleaned of everything but the src directory, Cargo.toml, and Cargo.lock.
This is pretty simple: the quick-start template uses craneLib.cleanCargoSource to clear out the source directory before building. However, it became not so simple when I removed the call to that function, only to find that the source directory was still being cleaned in the same manner.
To complicate things further, this image file is being include_bytes!()ed in my code, which means that when the code compiles, the image file is accessible, but during the postInstall, it isn’t.
What’s going on here? Is there some automatic source cleaning that craneLib does that I’m unaware of? Should I use something other than postInstall to install the app icon?
Here’s a link to the repo if you want to inspect the flake. The last commit with the old flake was 3c9b5947.

I don’t know anything about crane, but it’s certainly possible that it’s doing such cleaning. If that’s the case, using ${src} would work - and per my testing, applying this patch seems to work.
I also noticed your package wasn’t installing the desktop file, and the icon value was incorrect, so I fixed that as well.

diff --git a/flake.nix b/flake.nix
index 76d5358..de888b5 100644
--- a/flake.nix
+++ b/flake.nix
@@ -73,20 +73,22 @@
             pkgs.libiconv
           ];
 
-        nativeBuildInputs = with pkgs; [pkg-config];
+        nativeBuildInputs = with pkgs; [copyDesktopItems pkg-config];
 
-        desktopItem = pkgs.makeDesktopItem {
+        desktopItems = [(pkgs.makeDesktopItem {
           name = "NuhxBoard";
           desktopName = "NuhxBoard";
           comment = "Cross-platform input visualizer";
-          icon = "NuhxBoard.png";
+          icon = "NuhxBoard";
           exec = "nuhxboard";
           terminal = false;
           keywords = ["Keyboard"];
           startupWMClass = "NuhxBoard";
-        };
+        })];
 
-        postInstall = "install -Dm644 $src/NuhxBoard.png $out/share/icons/hicolor/128x128/apps/NuhxBoard.png";
+        postInstall = ''
+          install -Dm644 ${src}/NuhxBoard.png $out/share/icons/hicolor/128x128/apps/NuhxBoard.png
+        '';
       };
 
       craneLibLLvmTools =
1 Like

always the littlest tweaks that I never think of…
I can confirm that this works. I’m curious: is the addition of copyDesktopItems in nativeBuildInputs required for desktopItems to work?

Yes, see example 268 Nixpkgs Reference Manual

Yeah, it’s because ${src} refers to the nix binding that’s in scope - which you defined directly.
Whereas $src refers to the bash envvar which could be redefined by whatever crane is doing in its builder

1 Like