samcday / phrog

🐸 Mobile device greeter
GNU General Public License v3.0
10 stars 0 forks source link

Support for statically linked libphosh #37

Closed samcday closed 2 months ago

samcday commented 2 months ago

Everything that :frog: needs for an initial stable release is already upstream. I'd still like to continue iterating further after that, though. Prototyping new features and letting them soak in nightly builds would be much easier if a build with statically linked libphosh can be produced.

In the short/mid term, it might also still be reasonable to get versions of phrog with statically linked libphosh into (some) package repos, too. At least Fedora really doesn't like it but has exceptions, and I can imagine being able to make a successful case for it in Alpine. The fact that nobody (not even phosh-session itself) is yet consuming the proper versioned shared lib artifact makes for a compelling argument, IMO.

Anyway, I had this mostly working before in the existing libphosh+rs subtrees, but trampled all over that work when rebasing on the 0.41 changes. So I should be able to fish those commits back out of the history and re-apply them.

I'm assuming I can switch libphosh-rs crate dependency between crates.io and the local subtree via a cargo feature. The plan would be to toggle the usage of the non-upstreamed patches in phrog + libphosh-rs trees with cargo features.

I think all I'm really missing is digging the patches for phosh_init and the hacked up build.rs for libphosh.

Finally, I'd need to hack on phrog.spec with some bconds (or whatever? still hazy on RPM stuff), to enable the statically linked build + cargo features for the nightly COPR build.

agx commented 2 months ago

In the short/mid term, it might also still be reasonable to get versions of phrog with statically linked libphosh into (some) package repos, too

I think it would be good to only link against shared libphosh for release versions though as that would

samcday commented 2 months ago

Okay that's reasonable. I think my eyes are bigger than my stomach in terms of getting statically linked libphosh into big distro repos.

Ultimately, that implies shipping my ghetto WIP patches on top of libphosh straight to people's eyeballs. Inadvisable. :upside_down_face:

I still like the idea of any% speedrunning those WIP patches to a nightly package repo, though. So my nightly COPR for sure since that's already a thing. Maybe also in Phosh nightly repo, as something that is only enabled via a build profile, once #10 is done?

agx commented 2 months ago

I still like the idea of any% speedrunning those WIP patches to a nightly package repo

Having easy to grab builds with pending features available is certainly useful.

samcday commented 2 months ago

So as of now, the CI builds in main and PRs are testing :frog: with statically linked and vendored libphosh.

I manually configured phosh-nightly COPR to enable the static bcond, so I think those nightly packages (which I use in my local machines for dogfooding) should be using the statically linked vendored subtrees.

I could not see an immediately obvious way to configure Packit to enable the bcond for the chroots, so the per-branch COPR builds continue to be dynamically linked (as are the default RPM builds).

I think the way I hacked the support into libphosh-sys crate build.rs is quite nifty and maybe worth proposing upstream in some form.

The README is updated with instructions, assuming it works on other folks' machines as it has on two of my workstations so far, one can simply cargo run --features=static and run phrog with the local phosh/ subtree. Any changes in phosh/src will get picked up on the next cargo run.

samcday commented 2 months ago

The statically linked builds in phrog nightly COPR don't work:

$ phrog --version
phrog: error while loading shared libraries: libpulsecommon-16.1.so: cannot open shared object file: No such file or directory

For some reason libpulsecommon-16.1.so gets pulled in as a direct dependency in the resulting phrog binary:

$ readelf -d /usr/bin/phrog  | grep pul
 0x0000000000000001 (NEEDED)             Shared library: [libpulse-mainloop-glib.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libpulse.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libpulsecommon-16.1.so]

Interestingly, this doesn't happen for main phosh binary:

$ readelf -d /usr/libexec/phosh  | grep pul
 0x0000000000000001 (NEEDED)             Shared library: [libpulse.so.0]
 0x0000000000000001 (NEEDED)             Shared library: [libpulse-mainloop-glib.so.0]

But the end result is that libpulsecommon shows up in ldd output:

$ ldd /usr/libexec/phosh | grep pulse
    libpulse.so.0 => /lib64/libpulse.so.0 (0x00007f50d4c20000)
    libpulse-mainloop-glib.so.0 => /lib64/libpulse-mainloop-glib.so.0 (0x00007f50d55ee000)
    libpulsecommon-16.1.so => /usr/lib64/pulseaudio/libpulsecommon-16.1.so (0x00007f50d3728000)

And for phrog:

$ ldd /usr/bin/phrog | grep pulse
    libpulse-mainloop-glib.so.0 => /lib64/libpulse-mainloop-glib.so.0 (0x00007efe07680000)
    libpulse.so.0 => /lib64/libpulse.so.0 (0x00007efe0762f000)
    libpulsecommon-16.1.so => not found
    libpulsecommon-16.1.so => /usr/lib64/pulseaudio/libpulsecommon-16.1.so (0x00007efe0593c000)

I don't understand how this happens. Some kind of rpath magic?

So that makes me think that maybe the pkgconfig for libphosh is doing something to mix things up here. Or maybe the way I'm instructing Cargo to statically link libphosh is wrong.

@agx if you have some time to immerse yourself in this context and give me some clues I'd be very grateful!

I'm disabling static builds in the nightly COPR, and re-opening this issue. I don't consider this done until I have at least one release/distribution channel that makes static builds available.

agx commented 2 months ago

No idea. The fact that some libs use /lib/ but the other /usr/lib/ looks suspicious, as if libpulsecommon isn't found at one of the linking steps but then for a later one? I wouldn't worry and use the shared lib as we verify that with the examples in libphosh-rs. If you look at libphoshs .pc file it's not listed there so I assume it comes in via gvc.

Additionally supporting the static linking case is effort (due to all the dependencies we link in (e.g. here libphosh -> gvc -> pulse)) which I think is time better spent elsewhere (given the huge amount of things we want to do).

If you want a copr build with experimental features then using the shared lib with a LD_LIBRARY_PATH or rpath is likely more future proof (as that would use the same build steps we build for libphosh-rs)

samcday commented 2 months ago

Yep, fair enough. I suppose I agree that the static linking path is just not generally useful enough to pursue. For now, the builds work well enough with a quick cargo run --features=static for local development.

As you note, for the nightly repo use case there's other options available. I'll keep this issue open until I figure out that other option, if it's not to be statically linking.

I'm not quite done with it yet, since I think the static linking path is, at the very least, educational for myself ;) But also because the current approach is using system-deps crate to statically link the libphosh .pc, it stresses that stuff in interesting ways that might still lead to a more robust set of artifacts for libphosh.

samcday commented 2 months ago

So I think this might be a quirk of Fedora packaging somehow somewhere.

45 has enabled static builds for Alpine packages being pooped out of CI. I just installed the latest aarch64 build on my pmOS tablet, confirming that it works and doesn't add the explicit so dep on pulsecommon.

When that lands I'll be happy that I have one place producing packaged static builds, so I'll close this out.