fjvallarino / monomer

An easy to use, cross platform, GUI library for writing Haskell applications.
BSD 3-Clause "New" or "Revised" License
596 stars 44 forks source link

Add support for Nix #12

Closed smunix closed 3 years ago

smunix commented 3 years ago

To make reproducible builds possible for users, should we add support for Nix? I'm sitting ready to push a PR if this is a feature users would want to have.

Also thanks for putting this up, I've been waiting on such a framework for a long time now.

fjvallarino commented 3 years ago

Hi @smunix!

It would be great to have it! I prefer to make it optional with nix: enable: false. Users who want to build with Nix would then use stack --nix build.

The reason for this is to avoid imposing an extra requirement on users. My main objective with the library is that it should be easy to use, and Stack allows for a simple setup process that is mostly equal in Windows, Linux, and macOS. On the other hand, in my experience:

Thanks!

smunix commented 3 years ago

I'd like to suggest that we don't touch on stack configuration builds at all (we shouldn't force Nix users to use stack, or force Stack users to use stack --nix). Essentially, users will continue to use whatever they currently use, so it is not intrusive at all.

However, Nix users will be able to do the following:

List apps

~/P/u/monomer (fix.nvidia) ∫ nix flake show                                                                                                                                                              [13:06:29] 
git+file:///home/smunix/Programming/ui/monomer?ref=fix.nvidia&rev=eb5f695e86b9819127b8985f23de14c49741be5a
├───apps
│   └───x86_64-linux
│       ├───books: app
│       ├───generative: app
│       ├───ticker: app
│       ├───todo: app
│       └───tutorial: app
├───defaultApp
│   └───x86_64-linux: app
├───defaultPackage
│   └───x86_64-linux: package 'monomer-1.0.0.2.20210819.eb5f695'
└───packages
    └───x86_64-linux
        └───monomer: package 'monomer-1.0.0.2.20210819.eb5f695'

Build (with Nix)

~/P/u/monomer (fix.nvidia) ∫ nix build 

Build and Run an app (ticker for example)

~/P/u/monomer (fix.nvidia) ∫ nix run .#ticker                                                                                                                                                            [13:08:44] 
[1/0/1 built, 0.0 MiB DL] building monomer-1.0.0.2.20210819.eb5f695 (compileBuildDriverPhase): 
[...]

Ticker

fjvallarino commented 3 years ago

@smunix I'm testing your PR, but I won't be able to finish validating it today. My VM ran out of space while running Nix and, after expanding the assigned hard disk, it won't start again, so I'll have to rebuild it.

Curious: how is the maintenance process for this? Since this library was released recently, there will be bug fixes and improvements in the near future.

Thanks!

smunix commented 3 years ago

I do work on NixOs (for Linux) essentially (and use Nix on MacOSX also), so it is pretty straightforward for me. Whenever I make changes, I simply run nix build to build, or nix run .#tutorial to start one of the apps.

I could have used a VM as well, but the odds for breaking my setup with Nix are close to zero, so I don't need to start VMs. I just use my host station.

With Nix, you can write an expression that will automate the whole process: build a new VM (from scratch or reuse the existing one - these are called NixOS containers), and then run Monomer inside of it. This way, everything becomes 100% reproducible (even the process of setting up and configuring the VM). I can write you one if you'd like to have it.

Next up (once you've merge this PR), I'm looking to add Github actions with Nix to this repo, so we can ensure all PRs are always validated before they are merged.

fjvallarino commented 3 years ago

Nice! I have to take a deeper look at Nix.

In my previous comment, I wanted to ask about the flakes.nix file (I assume the lock file is generated automatically from the nix file). Is there a way to automatically update flakes.nix, or should I manually input the hash of the corresponding Monomer commit when a new version is released?

smunix commented 3 years ago

I'm planning on automating this as well; but it needs nanovg-hs to be "flakesified" (See cocreature/nanovg-hs#15). After cocreature/nanovg-hs#15 is merged, all you'd have to do is nix flake update --commit-lock-file to pick up any new changes (yes, the lock file is auto-generated).

The other option I tried was to link flakes.nix to the nanovg-0.8.0.0 on hackage, but it's not Nix friendly apparently:

tar: */nanovg/0.8.0.0/nanovg.json: Not found in archive
tar: */nanovg/0.8.0.0/nanovg.cabal: Not found in archive
tar: Exiting with failure status due to previous errors

This means that nanovg-0.8.0.0 on hackage is still broken on Nix. It would need to be fixed so users can point at it directly, instead of pulling from github:cocreature/nanovg-hs commits as I do here.

smunix commented 3 years ago

@fjvallarino I have now added a command to start a VM (with an X11 windowing system) on which all the executables from monomer are pre-installed. It uses QEmu for Linux (I'm not sure it would work on macosx or Windows) and you can take a glimpse at it by running the following:

> nix run github:smunix/monomer/fix.linux#nixos

After #13 is merged, it will then be possible to run the VM with all executables with the following instead:

> nix run github:fjvallarino/monomer#nixos

Log in the VM with the following:

vm-starting

vm-login

It takes a little long the first time you start the VM as it has to load all the dependencies (KDE, plasma, awesome-wm, ...), then compiles monomer and finally installs the executables in PATH.

Once you've logged in, you can start a terminal vm-open-terminal

Let's launch one of the examples found in monomer, generative (it comes pre-installed in the VM) vm-launch-generative

Et voila!

vm-gui-generative

This is an opt-in feature, so users having issues with Nix or those not having Nix shouldn't be impacted at all.

You shouldn't need nixGL within this VM, I believe.

In the PR #13 , you will also see that I have changed the .cabal file so the font files can be distributed and loaded from outside of the project. I hit an issue while deploying the examples in Monomer; the executables were failing to locate the font files. We should fix it everywhere in monomer in a separate ticket (to be filed later). I've only fixed on the generative example for now.

That's it for now.

fjvallarino commented 3 years ago

@smunix this is really nice! I tried the latest changes from your PR, and I could run the examples without any issues. Thanks!

smunix commented 3 years ago

fixed by #13

Clindbergh commented 1 year ago

@smunix Is nix run .#ticker still working out of the box for you with the current master? I'm not successful with NixOS 22.11:

❯ nix run .#todo                                                                                                     
error: unable to execute '/nix/store/pak3ikab94jlfqg7ymm9h6xn8mg3vjb7-monomer-1.5.0.0.20221206.c233aba/bin/todo': No such file or directory