neuralinkcorp / tsui

An (experimental) elegant TUI for configuring Tailscale.
https://neuralink.com/tsui
MIT License
261 stars 4 forks source link

fix: run with 'nix run' #20

Open guibou opened 2 months ago

guibou commented 2 months ago

The standard nix builds creates a binary which is reproducible with pinned shared libraries in /nix/store as well as a pinned library loader (also located in /nix/store).

However the preFixup phase is replacing the reproducible and pinned library loader by one which is hopefully located in /lib64/ld-linux-x86-64.so.2 (e.g. for x86-64 systems). I don't understand this fix because:

    linux-vdso.so.1 (0x00007f95bad0d000)
    libX11.so.6 => /nix/store/44q9wnzpgv77rl0yjszs0bac5apk2c83-libX11-1.8.9/lib/libX11.so.6 (0x00007f95babc2000)
    libpthread.so.0 => /nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libpthread.so.0 (0x00007f95babbd000)
    libresolv.so.2 => /nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libresolv.so.2 (0x00007f95babac000)
    libc.so.6 => /nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/libc.so.6 (0x00007f95ba9bf000)
    libxcb.so.1 => /nix/store/inw0qwiz9mq2748g0whfa43q2qs2ic60-libxcb-1.17.0/lib/libxcb.so.1 (0x00007f95ba992000)
    /nix/store/dbcw19dshdwnxdv5q2g6wldj6syyvq7l-glibc-2.39-52/lib/ld-linux-x86-64.so.2 => /nix/store/wlffq5p6mxxgfap10sav3ij936jzqm59-glibc-2.39-52/lib64/ld-linux-x86-64.so.2 (0x00007f95bad0f000)
    libXau.so.6 => /nix/store/wgzlxm5hzkpfzaa1qjc4pzzc9fhkwf2c-libXau-1.0.11/lib/libXau.so.6 (0x00007f95ba98d000)
    libXdmcp.so.6 => /nix/store/sg6xmva8xipj3mw1ip22n4f6vqmzb47r-libXdmcp-1.1.5/lib/libXdmcp.so.6 (0x00007f95ba985000)

Note that I don't really understand the comment:

Un-Nix the build so it can dlopen() X11 outside of Nix environments.

Alternates solutions:

Note that with this commit, users can directly run tsui using nix run 'github:neuralinkcorp/tsui' (once merged).

kognise commented 2 months ago

Hey! Thanks for the PR and for starting a discussion on this. I definitely want tsui to be easy to run on NixOS, if only because the build system is already flake-based and so there isn't much other work required.

You're right that the flake.nix is currently a little wonky in the context of running it on Nix systems. This is because we're actually primarily using Nix as a build system for the distributable binaries. They need to be able to run on non-Nix systems, which is why we have to patch the interp to one that real systems will actually have. The downside of this is that now, despite having a Nix flake, it doesn't actually support NixOS without FHS :)

Why not build the binary statically? The main dependency we care about here is X, which is used for the clipboard copying support. It probably isn't a great idea to statically link X into the binary.

I think there are two useful things that can both be done here:

  1. What you suggested is definitely the right path for a NixOS-friendly build: "Provide two builds artifacts, one (the default) which does not do the patch and can hence be run directly using nix run and one other which does this patching."
  2. Potentially rewrite clipboard_linux.c to dynamically load X. This would probably make the binary more portable. I think we tried this earlier and had some issues with getting the binary to work on Wayland systems when built with Nix, but those issues can probably be fixed.

Neither of these are truthfully my top priority at the moment, but if you are interested in either I will eagerly review and merge the changes!

guibou commented 2 months ago

Hi @kognise, thank you for your detailed answer! It is highly appreciated. (To be honest, I was expecting this MR and discussion to stale for years and was just publishing it in order to keep track and give visibility and a partial solution to the "I want to run that NOW on nixos" question).

Why not build the binary statically? The main dependency we care about here is X, which is used for the clipboard copying support. It probably isn't a great idea to statically link X into the binary.

Because of the licence or because you want the "self contained executable" to be able to use the "runtime" system X libraries versus the "buildtime" ones?

If that's about the licenses, my understanding is that with these MIT (-like) licences, you should be good.

If that's about the runtime vs buildtime, I think (but it should be confirmed) that X is perfectly able to work with some libraries discrepancy because it should only be an entrypoint for the X protocol (a bit like libc fopen is internally using the stable kernel API).

Anyway, I've added a commit to the MR which implements point 1: it provides two build artifacts:

So could be the best of both world. I set the "no-hack" as default so it allows users to run tsui from anywhere without really bothering, the variant with the hack being more of a dev specific entrypoint. Feel free to suggest a switch here.

I've also added a nix bundle command. In theory it could create a self-extracting self-contained bundle which can be easy to relocate on any other computer. Try it with nix bundle, and the result is in ./tsui. I said in theory, because that's not a simple task, but I had success with this multiples times on some complex programs. (tl;dr; the archive contains a copy of /nix/store with all the dependencies, it self extracts itself on a temporary filesystem namespace and runs). Other flavor of bundle are accessible, more here: https://nix.dev/manual/nix/2.18/command-ref/new-cli/nix3-bundle

The current point of this MR is that:

Tell me what to do next, in the meantime, enjoy your sunday ;)

ndom91 commented 1 month ago

This fixed the installation for me btw. Before and after updating my flake input to guibou's fork (thanks btw!):

image