Running locally built Qt apps

I am new to Nix and want to use it for reproducible builds. Target is to use Nix for compilation of our own software and run it in the “host” Linux OS (mix of different Linux versions). Following tutorials, I could build now our C++ software as follows:

nix-shell -p package1 package2 .... 
> cmake ..
> make ...

# in host env, outside of nix-shell

The app would run and use libs in /nix. All is nice and as expected.

With Qt apps though, I have added libsForQt5.qt5.qtbase as a package for nix-shell which was sufficient for compiling and linking app-qt. However, running it fails with missing Qt platform message:

qt.qpa.plugin: Could not find the Qt platform plugin "xcb" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.

No platforms are listed either.

In corresponding threads over here and in Qt Wiki, I can see some wrapper wrapQtAppsHook. However, it is not clear how to use it in nix-shell when building executable.

Hence the question:

  • how could I compile Qt application in a way that would make it possible to use “outside of Nix” - running in Linux PC with Nix installed, but without entering nix-shell?

I admit that I haven’t had time to go through full tutorial and later sections on Nix language yet. Which maybe a reason why I struggle with this construction right now. Looking forward to pointers.

You also need to wrap the Qt App, see the appropriate section in the Nixpkgs manual: Nixpkgs 23.05 manual | Nix & NixOS

Thank you very much for your help! Is there a way to call that wrapper manually, when compiling an app inside nix-shell using cmake && make combination?

If you put

nativeBuildInputs = [ wrapQtAppsHook ];
dontWrapQtApps = true;

in your shell.nix, you should be able to call wrapQtApp "$out/bin/myapp" --prefix PATH : /path/to/bin manually.

But tbh., at this point it would be better to properly package the app.

1 Like

I am sure that you are right. I will look into how to package it properly - would have to read up on it. Will mark your reply as a solution while I didn’t make it work properly. But that’s mostly due to lack of time I took to learn Nix bits.

Thank you for your pointers!

As you already got it working in in a nix shell, packaging should be straightforward:

{ stdenv, lib, qtbase, cmake, wrapQtAppsHook, package1, package2, packageX }: 

    stdenv.mkDerivation {
      pname = "myapp";
      version = "1.0";

      src = ... ; # point this to your source using fetchgit or just "." while you are testing

      buildInputs = [ qtbase package1 package2 packageX ];
      nativeBuildInputs = [ cmake wrapQtAppsHook ]; 

      # no need to define the build steps, all done by magic behind the scenes
1 Like

Also have a look at Jacek’s blog where you can find a full example with explanations, including packing things up in a Nix flake:

1 Like

Thanks for the pointers!