Skip to content
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

Loads qt plugin paths as registered... #44047

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions pkgs/development/libraries/qt-5/5.11/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ let
patches = {
qtbase = [
./qtbase.patch
./qtbase-additional.patch
./qtbase-darwin.patch
./qtbase-revert-no-macos10.10.patch
./qtbase-fixguicmake.patch
Expand Down
32 changes: 32 additions & 0 deletions pkgs/development/libraries/qt-5/5.11/qtbase-additional.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 5ae3fd62e5..ec3fccfc76 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2533,6 +2533,27 @@ QStringList QCoreApplication::libraryPaths()
QStringList *app_libpaths = new QStringList;
coreappdata()->app_libpaths.reset(app_libpaths);

+ {
+ // Start at the binary; this allows us to *always* start by stripping the last part.
+ QStringList components = applicationFilePath().split(QDir::separator());
+
+ // We don't care about /nix/store/nix-support, only /nix/store/*/nix-support
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am uncomfortable with searching upward from the executable in this way. Going up one level should be fine (from /nix/store/.../bin/foo to /nix/store/.../nix-support/). The part about components.length() > 3 smells fishy to me; what happens if Nix is built with a different store path, such as a user-mode installation?

+ // This is why we're checking for more than 3 parts. It will bail out once /nix/xtore/*/nix-support/qt-plugin-paths has been tested.
+ while (components.length() > 3) {
+ components.removeLast();
+ const QString support_plugin_paths = QDir::cleanPath(QDir::separator() + components.join(QDir::separator()) + QStringLiteral("/nix-support/qt-plugin-paths"));
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QtDeclarative-based applications also need QML2_IMPORT_PATH. Some Qt applications and all KDE applications need XDG_DATA_DIRS and XDG_CONFIG_DIRS. Could you extend this to cover those cases?

+ if (QFile::exists(support_plugin_paths)) {
+ QFile file(support_plugin_paths);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ app_libpaths->append(in.readLine());
+ }
+ }
+ }
+ }
+ }
+
// Add library paths derived from PATH
const QStringList paths = QFile::decodeName(qgetenv("PATH")).split(':');
const QString plugindir = QStringLiteral("../" NIXPKGS_QT_PLUGIN_PREFIX);
1 change: 1 addition & 0 deletions pkgs/development/libraries/qt-5/5.12/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ let
patches = {
qtbase = [
./qtbase.patch
./qtbase-additional.patch
./qtbase-darwin.patch
./qtbase-revert-no-macos10.10.patch
./qtbase-fixguicmake.patch
Expand Down
32 changes: 32 additions & 0 deletions pkgs/development/libraries/qt-5/5.12/qtbase-additional.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 5ae3fd62e5..ec3fccfc76 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2533,6 +2533,27 @@ QStringList QCoreApplication::libraryPaths()
QStringList *app_libpaths = new QStringList;
coreappdata()->app_libpaths.reset(app_libpaths);

+ {
+ // Start at the binary; this allows us to *always* start by stripping the last part.
+ QStringList components = applicationFilePath().split(QDir::separator());
+
+ // We don't care about /nix/store/nix-support, only /nix/store/*/nix-support
+ // This is why we're checking for more than 3 parts. It will bail out once /nix/xtore/*/nix-support/qt-plugin-paths has been tested.
+ while (components.length() > 3) {
+ components.removeLast();
+ const QString support_plugin_paths = QDir::cleanPath(QDir::separator() + components.join(QDir::separator()) + QStringLiteral("/nix-support/qt-plugin-paths"));
+ if (QFile::exists(support_plugin_paths)) {
+ QFile file(support_plugin_paths);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ app_libpaths->append(in.readLine());
+ }
+ }
+ }
+ }
+ }
+
// Add library paths derived from PATH
const QStringList paths = QFile::decodeName(qgetenv("PATH")).split(':');
const QString plugindir = QStringLiteral("../" NIXPKGS_QT_PLUGIN_PREFIX);
2 changes: 1 addition & 1 deletion pkgs/development/libraries/qt-5/5.9/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ let
srcs = import ./srcs.nix { inherit fetchurl; inherit mirror; };

patches = {
qtbase = [ ./qtbase.patch ./qtbase-fixguicmake.patch ] ++ optional stdenv.isDarwin ./qtbase-darwin.patch;
qtbase = [ ./qtbase.patch ./qtbase-additional.patch ./qtbase-fixguicmake.patch ] ++ optional stdenv.isDarwin ./qtbase-darwin.patch;
qtdeclarative = [ ./qtdeclarative.patch ];
qtscript = [ ./qtscript.patch ];
qtserialport = [ ./qtserialport.patch ];
Expand Down
32 changes: 32 additions & 0 deletions pkgs/development/libraries/qt-5/5.9/qtbase-additional.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
diff --git a/src/corelib/kernel/qcoreapplication.cpp b/src/corelib/kernel/qcoreapplication.cpp
index 5ae3fd62e5..ec3fccfc76 100644
--- a/src/corelib/kernel/qcoreapplication.cpp
+++ b/src/corelib/kernel/qcoreapplication.cpp
@@ -2533,6 +2533,27 @@ QStringList QCoreApplication::libraryPaths()
QStringList *app_libpaths = new QStringList;
coreappdata()->app_libpaths.reset(app_libpaths);

+ {
+ // Start at the binary; this allows us to *always* start by stripping the last part.
+ QStringList components = applicationFilePath().split(QDir::separator());
+
+ // We don't care about /nix/store/nix-support, only /nix/store/*/nix-support
+ // This is why we're checking for more than 3 parts. It will bail out once /nix/xtore/*/nix-support/qt-plugin-paths has been tested.
+ while (components.length() > 3) {
+ components.removeLast();
+ const QString support_plugin_paths = QDir::cleanPath(QDir::separator() + components.join(QDir::separator()) + QStringLiteral("/nix-support/qt-plugin-paths"));
+ if (QFile::exists(support_plugin_paths)) {
+ QFile file(support_plugin_paths);
+ if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
+ QTextStream in(&file);
+ while (!in.atEnd()) {
+ app_libpaths->append(in.readLine());
+ }
+ }
+ }
+ }
+ }
+
// Add library paths derived from PATH
const QStringList paths = QFile::decodeName(qgetenv("PATH")).split(':');
const QString plugindir = QStringLiteral("../" NIXPKGS_QT_PLUGIN_PREFIX);
56 changes: 56 additions & 0 deletions pkgs/development/libraries/qt-5/hooks/qtbase-setup-hook.sh
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,59 @@ postPatchMkspecs() {
if [ -z "$dontPatchMkspecs" ]; then
postPhases="${postPhases}${postPhases:+ }postPatchMkspecs"
fi

_Qt_sortless_uniq() {
# `uniq`, but keeps initial order.
# This is to remove risks of combinatorial explosion of plugin paths.
cat -n | sort -uk2 | sort -nk1 | cut -f2-
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks to exist at https://stackoverflow.com/a/20639730 - Stackoverflow links are sometimes worthwhile comments

}

_QtGetPluginPaths() {
# Lists all plugin paths for current Qt for given buildInputs and propagatedBuildInputs
local i
local _i
local o
local inputs

# FIXME : this causes output path cycles...
# I am unsure if it is even needed, though.
Copy link
Member Author

@samueldr samueldr Jul 24, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, and there's this...

I'm not sure I need to do this, but maybe I need, otherwise some parts may be missing.

The situation I'm thinking about is just like how qtbase has dev and bin. When you buildInputs = [ qt5.qtbase ] you get qt5.qtbase.dev. This is fine, except the plugins are in qt5.qtbase.bin, which won't get figured out. This is why I'm forcibly adding it to nix-support/qt-plugin-paths at build time.

I'll have to first wrap my mind around what the error is, then figure out something.

cycle detected in the references of '/nix/store/dkaprffmpi2aql8c0a2kxsid9pfvf5zj-qtsvg-5.11.1' from '/nix/store/v91n5pqk908brijpcd23wfrp4pkrg5g0-qtsvg-5.11.1-bin'

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The situation I'm thinking about is just like how qtbase has dev and bin.

This is the situation for almost all libraries. I noticed that you hardcoded the dependency on qtbase below; wouldn't we need to do this for all Qt libraries? (Missing the plugins from qtbase is the usually the only problem that is fatal, but missing the plugins from other libraries still leads to strange behavior and missing features.)

## Outputs self's plugins paths
#for o in $outputs; do
# o="${!o}/@qtPluginPrefix@"
# if [ -e "$o" ]; then
# echo "$o"
# fi
#done

inputs="$(
for i in $buildInputs $propagatedBuildInputs; do
echo "$i"
done | uniq
)"

for i in $inputs; do
_i="$i/@qtPluginPrefix@"
if [ -e "$_i" ]; then
echo "$_i"
fi
_i="$i/nix-support/qt-plugin-paths"
if [ -e "$_i" ]; then
cat "$_i"
fi
done
}

postAddPluginPaths() {
# Dumps all plugins paths to a nix-support file inside all outputs.
local o

for o in $outputs; do
o="${!o}/nix-support"
mkdir -p "$o"
_QtGetPluginPaths | _Qt_sortless_uniq > $o/qt-plugin-paths
done
}

if [ -z "$dontAddPluginPaths" ]; then
postPhases="${postPhases}${postPhases:+ }postAddPluginPaths"
fi
8 changes: 7 additions & 1 deletion pkgs/development/libraries/qt-5/modules/qtbase.nix
Original file line number Diff line number Diff line change
Expand Up @@ -386,7 +386,13 @@ stdenv.mkDerivation {
sed -i "$dev/lib/pkgconfig/Qt5Core.pc" \
-e "/^host_bins=/ c host_bins=$dev/bin"
''
);
)
+ ''
# Adds `qtbase-bin` as a basic dependency to *all* qtbase builds.
mkdir -p $dev/nix-support
echo "$bin/$qtPluginPrefix" >> $dev/nix-support/qt-plugin-paths
''
;

setupHook = ../hooks/qtbase-setup-hook.sh;

Expand Down