Skip to content
This repository has been archived by the owner on Dec 14, 2021. It is now read-only.

2020.1.117 cannot find "/lib/libQt5Gui.so.5" #954

Open
jubalh opened this issue Mar 31, 2020 · 20 comments
Open

2020.1.117 cannot find "/lib/libQt5Gui.so.5" #954

jubalh opened this issue Mar 31, 2020 · 20 comments
Labels

Comments

@jubalh
Copy link
Contributor

jubalh commented Mar 31, 2020

With the new release I get:

[  924s] -- Installing: /home/abuild/rpmbuild/BUILDROOT/sourcetrail-2020.1.117-0.x86_64/usr/Sourcetrail/data/fonts/Roboto_License.txt                         
[  924s] -- Installing: /home/abuild/rpmbuild/BUILDROOT/sourcetrail-2020.1.117-0.x86_64/usr/Sourcetrail/data/fallback                                         
[  924s] -- Installing: /home/abuild/rpmbuild/BUILDROOT/sourcetrail-2020.1.117-0.x86_64/usr/Sourcetrail/data/fallback/ApplicationSettings.xml                 
[  924s] -- Installing: /home/abuild/rpmbuild/BUILDROOT/sourcetrail-2020.1.117-0.x86_64/usr/Sourcetrail/data/fallback/window_settings.ini                     
[  924s] CMake Error at cmake_install.cmake:45 (file):                                                                                                        
[  924s]   file INSTALL cannot find "/lib/libQt5Gui.so.5": No such file or directory.   

I don't see that file anywhere.
But in my opinion it still shouldn't need to install this at all! I think that has been mentioned in #808 already.

@egraether
Copy link
Contributor

Are you using the new 'AppImage' package? Or the tarball?
Which operating system do you use?

@jubalh
Copy link
Contributor Author

jubalh commented Mar 31, 2020

Like last time I'm building the package for openSUSE.
So I'm using the tarball.
Running Linux. openSUSE Tumbleweed.

Our package is build here: https://build.opensuse.org/package/show/devel:tools/sourcetrail
This was the state in which it still worked: https://build.opensuse.org/request/show/751059

With the update to 2020.1.117 the above happened.
This is our build recipe.

@egraether
Copy link
Contributor

I just checked and the libraries shipped in the tarball are still the same, the file /lib/libQt5Gui.so.5 is also still in the package. However, we updated to Qt 5.12.6 here. This change was already released with Sourcetrail 2019.4.102. Does that version work?

@jubalh
Copy link
Contributor Author

jubalh commented Mar 31, 2020

2019.4.102. Does that version work?

I skipped that one. May I ask why you ship Qt libraries in the first place? It would be better to use the system libraries. I think this is mentioned in the FHS bug above.

Note that I built with -DBoost_USE_STATIC_LIBS=OFF -DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_STATIC_LIBS:BOOL=ON.

@egraether
Copy link
Contributor

2019.4.102. Does that version work?

I skipped that one. May I ask why you ship Qt libraries in the first place? It would be better to use the system libraries. I think this is mentioned in the FHS bug above.

The tarball package was started about 4 years ago by a developer who was more experienced with Linux. Since about 2 years it is maintained by me. As such I don't fully understand and know why things are the way they are.

The tarball is made with the Cmake script linux_package.cmake that relies on CPack. It adds some scripts to the package located in setup/Linux, most notably Sourcetrail.sh, which fixes a lot of issues for certain Linux distributions.

Since the tarball continues to cause a lot of problems, I now created the AppImage package, new in release 2020.1.117. The AppImage is created using the createAppImage.sh script, which uses linuxdeployqt. It was already tested by a couple users and it seems to work fine.

The great thing about linuxdeployqt is, that it takes care of which libraries need to be shipped. It can also be used to create just an AppDir directory structure, that is FHS compliant as far as I understand it. My plan is to rewrite how the tarball package is created using linuxdeployqt for our next release.

What do you think about that?
It would be awesome if you could help me on that, to make sure it's done right.

@jubalh
Copy link
Contributor Author

jubalh commented Apr 1, 2020

Having an AppImage is great of course.
But having a CMake file well enough written that distributions can include Sourcetrail in their repositories additionally is even better :)

For me it will be hard to find the time to do this right now. But I will set it on the todo.

I suggest you read

And looking at other open source Qt applications that use CMake: https://github.com/lxqt/lxqt-config/blob/master/CMakeLists.txt#L33

It would be good if we could make the Cmake behave so it uses the system libraries (if a certain switch is provided), otherwise this will never get into the official repositories of Linux distributions.

@egraether egraether added the Linux label Apr 2, 2020
@LouisStAmour
Copy link
Contributor

LouisStAmour commented Apr 9, 2020

Given how official repositories tend to freeze packages at very old releases intentionally, I'm not entirely sure traditional repo-compatibility should be a target for rapidly evolving software like Sourcetrail. It's not like we can just arbitrarily pick a version and suggest everyone use it. We're not yet as stable as GNU utils, for example. I'd suggest that there's a difference between software an operating system ships which should be stable and reliable for years, and software users want to put on top of that stable OS, things like app images, flatpacks, snaps, and so on. Effectively, containers without system dependencies are becoming the new way to ship binary apps to end users because it's the simplest way to ensure that your app runs. The alternative might be to end up like the maintainer of xscreensaver, forced to deal with bugs fixed long ago but in versions the upstream OS is not shipping: https://www.jwz.org/blog/2016/04/i-would-like-debian-to-stop-shipping-xscreensaver/

Note: I'm not objecting to CMake using system libraries. And we can definitely take a look. I'd draw a distinction between making it easier for developers to build vs making it easy for end users to install and run it. Having CMake optionally use system libraries is a convenience for developers, while asking developers to build inside a Docker image would be a different sort of convenience for developers, let's say. The first means every dependency we use has to ship in your OS, in the versions we require (or we force the dependency breakage down the chain to some poor OS maintainer), while the second means we maintain container images of dependency files that can be cleanly installed and removed when no longer necessary. The latter, containers, is the bulletproof approach, while the former, package dependencies, is the distro-friendly approach.

I'm writing this after having to install almost a dozen dependencies and manually compiling things over a series of days in order to get builds running under Windows, and as such, I can completely appreciate a containers-based approach where your dependencies for build or runtime are neatly packaged and shrinkwrapped so that you can download binaries within a tarball container image and run them and not have to worry about updating paths everywhere to support your particular system's non-portable APIs, file system peculiarities (drive letters?!), etc.

Also I don't see this as an app-container or build-container vs distro story. After all, someone should be checking containers for security vulnerabilities, making sure containers include only the minimum required, coming up with new standards to break containers down into smaller containers that could run as "pods", ensuring containers write logs correctly and in the right places, that they understand the runtime environment, etc.

Containers aren't magic and distros can help manage them, but the traditional approach that all software can be built using older APIs packaged via the distro... that's slowly dying in the Internet era as hermeticity and reliability gain popularity. You see this everywhere, from .NET Framework or Java being something you installed to run an app, to pre-packaging .NET or Java apps to include their own known-good JVM or the popularity of static compiled apps such as Golang, where it would be rare if not impossible to suggest an operating system keep Github repos of code in their package managers. Monorepos are another form of this, where all dependencies are copied into the monorepo and thus any commit can be built from a checkout without any extra effort. https://bazel.build/ is another example of this kind of thinking.

@jubalh
Copy link
Contributor Author

jubalh commented Apr 9, 2020

I'm not sure why you make the connection between system libraries and "years old software". Not everyone runs an ancient OS.

Quite the opposite is true. If Sourcetrail ship it's own Qt (etc) libraries the user relies on Sourcetrail to update it immediately if there is a (security) update.
If we can use the system packages the security fixes for all applications that rely on this library will be done at one single point.
This is why Linux evolved to prefer this approach compared to static linking in the first place.

It's perfectly understood that there are use cases where containerized solutions make sense.

But in this case I think the problem does not apply at all, and this is just a mistake on how to package software.

There are various open source projects out there that build AppImages (so have every library put inside), Flatpacks or snaps and at the same time can build with the regular system libraries.

@LouisStAmour
Copy link
Contributor

LouisStAmour commented Apr 9, 2020

So, my suggestion would be to in fact set up a CI process for Sourcetrail in which we do publish new versions tied directly to automatic PRs from upstream, assuming it passes our automated CI checks which might include screenshots, and that it passes our code review. (Less of an issue here, more of an issue for web projects with hundreds of dependencies.)

To that end, my preference would be shipping containers that can ship very compact change updates, so instead of downloading an entire Sourcetrail app for a few minor changes, you'd get a binary diff of at most a few megabytes or less that would keep the app up-to-date without your notice. Think of how Flash ships security updates via browsers, for example.

That said, I agree having an option to use system libraries is possible and changing the current behaviour is desirable but I wouldn't want to start forking code to support older releases manually.

It's worth clarifying, I'm just an OSS contributor here, commenting in my spare time. I don't speak for the project, though I would like to continue contributing to it! :)

@jubalh
Copy link
Contributor Author

jubalh commented Apr 9, 2020

That said, I agree having an option to use system libraries is possible but I wouldn't want to start forking code to support older releases manually.

Again. This issue is not at all about supporting older code. And I'm not sure why you always mention this. I assume it's that you only have experience with older distributions and thus have made these experiences.

One software that currently comes to mind is tiled.
It's also written using Qt also uses CMake. It ships a Flatpak for easy installation, but at the same time it supports building using system libraries.
And it definitely doesn't ship it's own set of Qt libraries in such a case. This is very bad practise imho. And this is what this issue is about. Please stop changing the intended purpose of this issue.

We have tiled in openSUSE since years. It's spec is clean an easy to write. No special stuff needed. All because they used CMake properly.

Also it's hard to answer to your comments if you post, and then edit 5 times. Maybe it would be an idea to first think about what you want to say.

Cheers.

@jubalh
Copy link
Contributor Author

jubalh commented Apr 9, 2020

By the way, my distribution uses Qt 5.14.1. I don't think this is outdated.
Also based on what you are saying I assume that you are not aware of how the packaging process works. Otherwise you wouldn't keep on saying that Sourcetrail would have to support older versions of dependencies. This is absolutely not what this issue is about.

It's about the ability to use system libraries dynamically for building Sourcetrail, instead of Sourcetrail trying to ship it's own version of dependencies.

This is all that upstream has to worry about, and should definitely be a goal.

@LouisStAmour
Copy link
Contributor

Let me start by saying, I'll try not to edit this post, and this will be the last post I make tonight, as it's getting late in my time zone.

I'll clarify my point around supporting older versions of dependencies:

The example I had in mind for backwards compatibility forking was not Qt, which is very stable, but Clang, more properly known as LLVM, which is very unstable as it ships new breaking major versions every 6 months. I just recently upgraded our support from LLVM 9 to LLVM 10, and while the changes were relatively minimal, if we were to then tell people they can compile using system dependencies exclusively, they would be stuck on older releases of Sourcetrail unless we helped them by supporting multiple versions of dependencies.

From one perspective this is like supporting glibc and musl libc, or Windows/Mac/Linux/BSD, it's a portability problem. From another perspective, it restricts us from using any new features or APIs released in newer versions and restricts end users from doing so as well.

Don't get me wrong, I'm not saying there's a right or wrong answer that's 100% containers or 100% system. I can understand, for instance, if a dependency like LLVM is something we expect users to use the version we prefer, while a dependency like boost, Qt, or even what compiler you choose to use, is something left up to the user. I agree that developers compiling should always be free to use whatever version is on their system, at their own risk, and we should make it as easy and risk-free as we can to do so.

But I'm emphasizing risk here because there's always the chance that if you download (as I did) LLVM v10 instead of LLVM v9, Boost 1.72 instead of Boost 1.67 and Qt 5.15 instead of Qt 5.12 that what you'll get isn't what was intended -- and it likely includes compiler errors or warnings. In my case I had to make 3 PRs to update things to work better on Windows (platform support) but also to support Clang v10 (dependency upgrade support).

I don't think we're disagreeing here with the main point, and the only edits I made earlier were to try and emphasize this. Also, because it's OSS, you can contribute compatibility fixes, I recognize this, as I did so. I've just been on too many projects which didn't recognize the resulting complexity from supporting too many platform versions, because you then need test suites in each one to ensure you don't have regressions or folks will say that version X compiled, when X+1 failed to compile on their system. There's a support cost and a code complexity cost to greater platform support.

@LouisStAmour
Copy link
Contributor

LouisStAmour commented Apr 9, 2020

Well, I went hunting for the code that does this, and while the Windows version captures DLLs within the top-level CMake script, the linux version seems to capture these over here: https://github.com/CoatiSoftware/Sourcetrail/blob/master/cmake/linux_package.cmake#L65-L65 along with a long list of other dependencies captured at whatever version they were compiled at. That's ... definitely not a productive way to do this long-term, as you're both being too specific (what if a library depends on another library, but we don't know this?) and too vague (we don't specify exact versions of dependencies here). So the code definitely needs to be fixed and rewritten. We appear to be confusing compilation concerns with deployment concerns. It's important when making redistributables to include necessary libraries, but that should be done as part of packaging, not building, and ideally in a completely dynamic fashion such that dependencies are specified up-front before compilation, and then whatever ended up getting linked against is copied after compilation, when packaging is required and in the form required by packaging.

I suppose I'm suggesting partly undoing work like 38581f9 - any thoughts @mlangkabel ?

@jubalh
Copy link
Contributor Author

jubalh commented Apr 9, 2020

The gentoo guys seem to remove the shipped libs by hand and later create a shell script as a launcher: https://gitweb.gentoo.org/repo/gentoo.git/tree/dev-cpp/sourcetrail/sourcetrail-2019.3.46-r2.ebuild

Nixos guys seem to have found a problem regarding the config file that apparantly is tried to put in the home directory: https://github.com/NixOS/nixpkgs/blob/release-19.09/pkgs/development/tools/sourcetrail/default.nix#L72

Best would be if this manual removal of libs wouldnt be necessary.
And Sourcetrail could check a global config option in case the one in XDG_HOME is not available. So distributions could ship a default config but user can edit their own.

@LouisStAmour
Copy link
Contributor

Since we mentioned Windows and Linux, for completeness, I went hunting for Mac. Turns out, it's the best of the lot -- it uses a dedicated command at

$QT_DIR/bin/macdeployqt $BUNDLE_PATH
called macdeployqt which uses otool to determine dependencies via some complicated parsing logic. https://code.qt.io/cgit/qt/qttools.git/tree/src/macdeployqt/shared/shared.cpp#n166 otool is explained here: https://github.com/PureDarwin/PureDarwin/wiki/otool

@jubalh
Copy link
Contributor Author

jubalh commented Apr 9, 2020

called macdeployqt

Looks like the equivalent of linuxdeployqt. So that doesn't help us.

@LouisStAmour
Copy link
Contributor

LouisStAmour commented Apr 9, 2020

Well, it does, because it highlights that packaging and compile should be two different steps and it's better if CMake (compilation) isn't also doing packaging.

Since we're already using linuxdeployqt, it makes copying the DLLs as part of the build entirely unnecessary for Linux, just as it's entirely unnecessary for Mac. There's also windeployqt for windows, which has its own baked in elfreader code to determine dependencies, and what appears to be extra code to handle Qt dependencies, though it's a fair bit more complicated than macdeployqt. https://code.qt.io/cgit/qt/qttools.git/tree/src/windeployqt/elfreader.cpp?h=5.6#n394

So we can leave copying of Qt dependencies out of cmake entirely if we use these *deployqt scripts as part of a later, optional packaging step.

Edit: CPack is the packaging tool supported by CMake, it runs as a separate step:

image

Source: https://blog.usejournal.com/creating-debian-packages-cmake-e519a0186e87

@jubalh
Copy link
Contributor Author

jubalh commented Apr 9, 2020

AFAIk so far there are various switches like:

-DBoost_USE_STATIC_LIBS=OFF -DBUILD_SHARED_LIBS:BOOL=OFF -DBUILD_STATIC_LIBS:BOOL=ON

I think the whole InstallQtModule and GetAndInstallLibrary should be omitted if one uses a switch that sais "dont use libs shipped with sourcetrail".

Well, it does, because it highlights that packaging and compile should be two different steps and it's better if CMake (compilation) isn't also doing packaging.

Yes, or depend it on the switches.

@jubalh
Copy link
Contributor Author

jubalh commented Apr 9, 2020

Edit: CPack is the packaging tool supported by CMake, it runs as a separate step:

CPack creates packages itself. We don't want that either. Distributions need to build and create the package. Otherwise it won't get into official repos.

@jubalh
Copy link
Contributor Author

jubalh commented Apr 9, 2020

For this specific case of not installing the libs. I now went the Gentoo route and adapted the cmake.
Still would be good to have upstream cmake behave a bit different.

My changes.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants