-
Notifications
You must be signed in to change notification settings - Fork 1.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow building fish as self-installable #10367
base: master
Are you sure you want to change the base?
Conversation
One annoyance of this solution: You have to rerun It might be possible to write a file with the version that was installed and check that on startup instead. |
Would be prudent to double-check performance of the statically linked version. Four-ish years ago, statically linking with musl could have tanked your performance due to musl's |
Pure "--no-config" startup is faster, our other benchmarks are 10-70% slower (memory usage is ~25% less). Of course those are specifically written to mostly measure time spent in fish. Realistically, this is an entirely usable build and it's hard to notice a difference when just running it. Performance in shells is weird, very often most of the time is spent waiting for external commands. It's "possible" to link glibc statically, but that will crash when you attempt to do The alternative is to offer a self-installable build dynamically linked against glibc, but that obviously requires a compatible (i.e. same version or newer) glibc to what it was built against. This would still be better than the appimage, because that needs libfuse2 and glibc on the host. These are also simple enough to build that we could do both. This talk is of course secondary to whether having fish self-installable is useful - it would enable |
Binaries built with newer glibc isn't necessarily incompatible with older glibc. glibc uses symbol versioning to indicate compatibility. I pulled your branch and ran |
So if I had a fleet of 100 servers on varying versions of Ubuntu LTS I could build it on the oldest server and it should be able to be copied to any of the same version server or higher and it would simply run? |
If you build dynamically against glibc, yes. If you build statically against musl you can build it anywhere (probably even cross-compile it from macos), at the cost of some performance. This will give you a per-user fish that needs to install its datafiles by running |
Alright, after a rebase this now crashes on startup - do Backtrace is:
|
debug build might help. This is still pre-fork so that should rule out a class of problems |
Debug build gives an empty backtrace (only Edit: Okay, I'm reasonably sure it's some dependency locking issue. If I run |
Okay I'm reasonably sure |
The thing that bites people when using |
It currently installs into ~/.local/share/fish/install, so there's the binaries in the cargo binary dir and exactly one directory. That means uninstallation is A versioned directory could lead to multiple of these being left behind instead of simply overwritten on upgrade. (plus the biggest issue left here is that installing via git like |
That's fine, but in that case the destination directory should be removed before the extraction starts - it doesn't look like this happens at present. Otherwise, files that are present in one version but not the next will be left behind. |
Good point, done. |
Alright, those last two commits are a bit weird. The immediate issue is that
which will break a lot of uses of $FISH_VERSION - there is no version there, only the commit sha. So this detects that case and turns it into
instead, by using the crate version (in Cargo.toml). I'm unsure if that is also needed for packages on crates.io. I changed the crate version (which was still at 0.1.0!) for testing. The version I picked is arbitrary and preliminary, and I am fine with removing it again. Tho I suppose it's not harmful to keep it in? I would like to try to get some more people to test this - and therefore the next fish version. We still have more regressions remaining than I would like, especially in corners we don't visit as often and this is really easy to get going as a separate version of fish without breaking your main install. It would also show if people like this way of installing it, and if anyone has an idea for getting the install/upgrade experience working. |
Not sure how much work it would be but getting some form of CI running would be good. We could publish the crates as pre-release versions. I think it makes sense to do that with a tagged tarball as well? |
This shells out to __fish_describe_command, but if the install is incomplete that will trigger the command-not-found handler.
This applies to `cargo install`, cmake should override it by setting $PREFIX. This together with the previous change makes `cargo install` sort-of work-ish - you'll have to copy the assets manually, and you'll be responsible for upgrading them together with fish.
When built with the default "installable" feature: Run `fish --install` or `fish --install=noconfirm` (for non-interactive use) CMake disables the default features so nothing changes for that, but this allows installing via `cargo install`, and even making a static binary that you can then just upload and have extract itself.
This used to create ~/.local/share/etc/fish, which makes no sense
Otherwise you have all the gunk next to the history etc. So we isolate it in ~/.local/share/fish/install/.
`cargo build --git` clones a git repo without any tags, so you get a version like ``` fish, version f3fc743 ``` which is *just* the commit hash and missing the "3.7.1-NUM-g" part. So, if we hit that case (detected because it has no ".", under the assumption that we'll never make a version that's just "4" instead of "4.0"), we prepend the version from Cargo.toml.
Mostly to test the previous commit
Should work nicer with how rust tooling interprets the version
Description
Here's the teaser:
This is how you can get a running fish without root permissions.
You can also use it to build a 100% statically linked fish that you can then copy to another system (with the same architecture and operating system). I've been able to do that for x86_64 linux, and cross-compile one for aarch64 linux. (using musl because glibc doesn't do static linking)
I believe it would be possible to allow this as an option, and to add a static build to fishshell.com so people can just download a fish, without compilation.
I believe this is superior to appimages, which I have recently discovered require libfuse2, which I didn't have installed, along with other dependencies like a compatible libc (so you would have to build on an old glibc system, and additionally a musl one, and that for each architecture)
Supersedes #6475.
What this does is embed the entirety of share/ - all the functions, completions and fish_config, and then write it out when you run
fish --install
(orfish --install=noconfirm
to skip the confirmation).It writes them out to ~/.local/share/fish/install, so uninstallation is
cargo uninstall fish; rm -r ~/.local/share/fish/install
.Technically, this is done by adding a Cargo feature, "installable", that's enabled by default (so
cargo install
will do it by default). When it is enabled, rust_embed will be added as a dependency. Default features are disabled in the cmake build so nothing changes there. (a slight wrinkle is that, if we did add another feature, we would have to turn it on in cmake)This about doubles the fish binary size (6M to 12M unstripped, 4M to 8.7M stripped). I have run benchmarks where it had little impact (7% increase in
--no-config
startup time). I do not think this is important. Binaries of similar size on my system: ctest, emacs, agg, gdb, perf. Bigger binaries include: kitten, clang-tidy, qemu, clangd. I have never thought of the size of any of them.TODO:
The following are more "future directions" than things I feel must be included now for this to be useful:
HTML isn't possible (it needs fish_indent to do the syntax highlighting), but
help
is always available and will simply open the online version.