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

[RFC] Declarative wrappers #85103

Closed
wants to merge 31 commits into from
Closed
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
242a7da
Write a prototype derivation that knows allInputs
doronbehar Apr 10, 2020
30f26fe
Now %out% is string replaced
doronbehar Apr 12, 2020
112882f
Make more stuff work
doronbehar Apr 12, 2020
9893944
Add more passthrus and make basic functionality work
doronbehar Apr 12, 2020
1e1464e
Create a very much working :) wrapGApps function
doronbehar Apr 12, 2020
78cbe77
fix gdk pixbuf module file env
doronbehar Apr 12, 2020
74a01b3
Replace _all_ occurences of %outname% in env's strings
doronbehar Apr 12, 2020
a18f521
prepare neowrap for XDG_DATA_DIRS=$out/share
doronbehar Apr 12, 2020
72d6478
teach it to deal with encyclopedia.wrapOut
doronbehar Apr 12, 2020
d0ed3a5
Prepare for a PR
doronbehar Apr 12, 2020
c0dab18
dumbly add passthrus to some qt packages
doronbehar Apr 12, 2020
6283f15
Make picard work perfectly with new wrapping method
doronbehar Apr 12, 2020
b4d3633
fix missing semicolon pkgs/development/libraries/gvfs/default.nix
ryantm Apr 12, 2020
ea9640a
Fix another ofborg error
doronbehar Apr 13, 2020
8074b9c
Stop using builtins.trace to avoid ofborg complaints
doronbehar Apr 13, 2020
f173b80
use @out@ and not %out%
doronbehar Apr 13, 2020
dda939a
Support single value env keys - for GDK_PIXBUF_MODULE_FILE
doronbehar Apr 13, 2020
8999768
Enable to refer to the unwrapped (real) drv of the wrapped drv
doronbehar Apr 13, 2020
2300445
some comments improvements
doronbehar Apr 14, 2020
32dd553
Use envInfo as was once envInfoFolded - for readability
doronbehar Apr 14, 2020
277ac54
Instead of using many values in env vars, enable to use a link argume…
doronbehar Apr 14, 2020
0ed98f4
Make it possible to lndir whole packages by env
doronbehar Apr 14, 2020
270ffc2
Test and make picard work as well with new features
doronbehar Apr 14, 2020
aea2b5a
Prepare support for python wrappings
doronbehar Apr 15, 2020
e6f9600
Improve getAllInputs recursiveness
doronbehar Apr 15, 2020
f50caf8
Make sure picard and arandr dont wrap python scripts, letting wrapGen…
doronbehar Apr 15, 2020
2ca4dc7
Add propagateEnv for more python deps of picard and arandr
doronbehar Apr 15, 2020
8c74d6a
Move wrapOut to wrapper arguments, out of encyclopedia
doronbehar Apr 15, 2020
3a8e032
Improve comments for debug statements / variables
doronbehar Apr 15, 2020
73bc870
sed 's/PYTHONPATH/NIX_PYTHONPATH/g' as @FRidh suggested
doronbehar Apr 16, 2020
2aacb90
Improve logic of linkPkg and encyclopedia vs wrapOut
doronbehar Apr 16, 2020
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
17 changes: 9 additions & 8 deletions pkgs/applications/audio/picard/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,15 @@ in pythonPackages.buildPythonApplication rec {
sha256 = "0xalg4dvaqb396h4s6gzxnplgv1lcvsczmmrlhyrj0kfj10amhsj";
};

nativeBuildInputs = [ gettext qt5.wrapQtAppsHook qt5.qtbase ]
nativeBuildInputs = [ gettext qt5.wrapQtAppsHook ];

propagatedBuildInputs = with pythonPackages; [
qt5.qtbase
pyqt5
mutagen
chromaprint
discid
]
++ stdenv.lib.optionals (pyqt5.multimediaEnabled) [
qt5.qtmultimedia.bin
gst_all_1.gstreamer
Expand All @@ -32,13 +40,6 @@ in pythonPackages.buildPythonApplication rec {
]
;

propagatedBuildInputs = with pythonPackages; [
pyqt5
mutagen
chromaprint
discid
];

prePatch = ''
# Pesky unicode punctuation.
substituteInPlace setup.cfg --replace "‘" "'"
Expand Down
129 changes: 129 additions & 0 deletions pkgs/build-support/neowrap.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
{ lib
, symlinkJoin
, makeWrapper
, extraPkgsByOverride ? []
}:

pkgList:

let
wrapper = {
extraPkgs ? [],
extraMakeWrapperArgs ? ""
}:
Copy link
Member

Choose a reason for hiding this comment

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

I wonder if you consider targetting wrappers in-scope? For example, fwupd needs to exclude EFI files from being wrapped; gjs only wants to wrap installed tests…

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Am I to understand you are concerned that wrapGeneric can't be instructed to wrap only some executables and not others?

Copy link
Member

@jtojnar jtojnar Aug 17, 2020

Choose a reason for hiding this comment

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

Yes. Ideally, it should be able to handle multiple disjoint wrappers.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Definitely we need to have that ability and it shouldn't be that hard to implement. I still don't have an idea though as to how this interface should look like. I'll update this PR or the RFC once I'll think about something, suggestions are welcome.

let
# Where we keep general knowledge about known to be used environmental variables
encyclopedia = {
# Here we write the separator string between values of every env var, the
# default is ":"
separators = {
# XDG_DATA_DIRS = ":";
};
# If we want the wrapping to also include an environmental variable in
# out, we list here for every env var what path to add to the wrapper's
# args. You can put a list as a value as well.
wrapOut = {
XDG_DATA_DIRS = "$out/share";
};
};
# recursive function that goes deep through the dependency graph of a given
# list of packages and creates a list of all buildInputs they all depend
# on. The 2nd argument pkgsFound is used internally and it's expected to be
# [] at the first call.
getAllInputs =
pkgs:
pkgsFound:
map (
pkg:
if (builtins.typeOf pkg) == "set" then
if builtins.hasAttr "buildInputs" pkg || builtins.hasAttr "propagatedBuildInputs" pkg then
# builtins.trace "pkg is of type ${builtins.typeOf pkg} and it's ${builtins.toJSON pkg}, with inputs: ${builtins.toJSON (pkg.buildInputs ++ pkg.propagatedBuildInputs)}" (getAllInputs (pkg.buildInputs ++ pkg.propagatedBuildInputs) (pkgsFound ++ [ pkg ]))
(getAllInputs (pkg.buildInputs ++ pkg.propagatedBuildInputs) (pkgsFound ++ [ pkg ]))
else
pkgsFound ++ [ pkg ]
else
# builtins.trace "pkg is not a set but a ${builtins.typeOf pkg} at ${builtins.toJSON pkg}, current pkgsFound is ${builtins.toJSON pkgsFound}" pkgsFound
pkgsFound
) pkgs;
allPkgs = (lib.lists.flatten pkgList) ++ extraPkgsByOverride ++ extraPkgs;
allInputs = lib.lists.unique (lib.lists.flatten (getAllInputs allPkgs []));
allInputs_ = builtins.trace "${builtins.toJSON allInputs}" allInputs;
# filter out of all the inputs the packages with the propagateEnv attribute
envPkgs = builtins.filter (
pkg:
(builtins.hasAttr "propagateEnv" pkg)
) allInputs;
# Given a package, it's outputs and an envStr such as found in the values
# of passthru's `propagateEnv`, it replaces all occurences of %<outname>%
# from envStr according to the pkg.outputs
replaceAllOutputs = {
pkg,
envStr,
outputs,
outname ? "out",
}:
let
outname = builtins.elemAt outputs 0;
in
if (builtins.length outputs) == 0 then
envStr
else
replaceAllOutputs {
inherit pkg;
outputs = lib.lists.subtractLists [outname] outputs;
envStr = builtins.replaceStrings
[ "%${outname}%" ]
[ "${pkg.${outname}}" ]
envStr;
}
;
envInfo = map (
pkg:
(lib.attrsets.mapAttrs (
name:
value:
replaceAllOutputs {
inherit pkg;
outputs = pkg.outputs;
envStr = value;
}
) pkg.propagateEnv)
) envPkgs;
envInfo_ = builtins.trace "envInfo is ${(builtins.toJSON envInfo)}" envInfo;
envInfoFolded = lib.attrsets.foldAttrs (n: a: [n] ++ a) [] envInfo;
envInfoFolded_ = builtins.trace "envInfoFolded is ${(builtins.toJSON envInfoFolded)}" envInfoFolded;
# Where we add stuff according to encyclopedia.wrapOut
envInfoWithLocal = lib.attrsets.mapAttrs (
name:
values:
if builtins.hasAttr name encyclopedia.wrapOut then
values ++ (lib.lists.flatten encyclopedia.wrapOut.${name})
else
values
) envInfoFolded;
envInfoWithLocal_ = builtins.trace "envInfoWithLocal is ${(builtins.toJSON envInfoWithLocal)}" envInfoWithLocal;
makeWrapperArgs = lib.attrsets.mapAttrsToList (
key:
value:
(let
# TODO: make sure this works with any separator according to encyclopedia.separators
sep = encyclopedia.separators.${key} or ":"; # default separator used for most wrappings
in
"--prefix ${key} ${sep} ${builtins.concatStringsSep sep value}"
)
) envInfoWithLocal;
makeWrapperArgs_ = builtins.trace "makeWrapperArgs is ${(builtins.toJSON makeWrapperArgs)}" makeWrapperArgs;
in
symlinkJoin {
Copy link
Member

@jtojnar jtojnar Aug 16, 2020

Choose a reason for hiding this comment

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

One disadvantage of symlinkJoin is that when absolute path is used in an entry point (e.g. desktop files, systemd services…), it will launch the unwrapped program.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Right.. Extra commands should be at postBuild for that to work. I wonder whether it'd be worth the effort to write something generic, or make wrapGeneric accept a extraBuildCommands string.

name = "runtime-env";
Copy link
Member

Choose a reason for hiding this comment

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

Perhaps this should inherit the name of the parent derivation.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Not always there's a single parent derivation, but certainly for most purposes, this would be nicer.

paths = pkgList;

buildInputs = [ makeWrapper ];
postBuild = ''
for i in $out/bin/*; do
wrapProgram "$i" ${(builtins.concatStringsSep " " makeWrapperArgs_)}
done
'';
};
in
lib.makeOverridable wrapper
3 changes: 3 additions & 0 deletions pkgs/development/libraries/atk/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ stdenv.mkDerivation rec {
updateScript = gnome3.updateScript {
packageName = pname;
};
propagateEnv = {
GI_TYPELIB_PATH = "%out%/lib/girepository-1.0";
};
};

meta = {
Expand Down
3 changes: 3 additions & 0 deletions pkgs/development/libraries/dconf/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,9 @@ stdenv.mkDerivation rec {
updateScript = gnome3.updateScript {
packageName = pname;
};
propagateEnv = {
GIO_EXTRA_MODULES = "%lib%/lib/gio/modules";
};
};

meta = with stdenv.lib; {
Expand Down
4 changes: 4 additions & 0 deletions pkgs/development/libraries/gdk-pixbuf/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,10 @@ in stdenv.mkDerivation rec {

# gdk_pixbuf_moduledir variable from gdk-pixbuf-2.0.pc
moduleDir = "lib/gdk-pixbuf-2.0/2.10.0/loaders";
cacheFile = "lib/gdk-pixbuf-2.0/2.10.0/loaders.cache";
propagateEnv = {
GI_TYPELIB_PATH = "%out%/lib/girepository-1.0";
};
};

meta = with stdenv.lib; {
Expand Down
3 changes: 3 additions & 0 deletions pkgs/development/libraries/gobject-introspection/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,9 @@ stdenv.mkDerivation rec {
updateScript = gnome3.updateScript {
packageName = pname;
};
propagateEnv = {
GI_TYPELIB_PATH = "%out%/lib/girepository-1.0";
};
};

meta = with stdenv.lib; {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,10 @@ stdenv.mkDerivation rec {

passthru = {
updateScript = gnome3.updateScript { packageName = "gsettings-desktop-schemas"; };
propagateEnv = {
XDG_DATA_DIRS = "%out%/share/gsettings-schemas/${pname}-${version}";
GI_TYPELIB_PATH = "%out%/lib/girepository-1.0";
};
};

# meson installs the schemas to share/glib-2.0/schemas
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/libraries/gstreamer/bad/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,12 @@ in stdenv.mkDerivation rec {
# that trip up clang with format security enabled.
hardeningDisable = [ "format" ];

passthru = {
propagateEnv = {
GST_PLUGIN_SYSTEM_PATH_1_0 = "%out%/lib/gstreamer-1.0";
};
};

doCheck = false; # fails 20 out of 58 tests, expensive

meta = with stdenv.lib; {
Expand Down
3 changes: 3 additions & 0 deletions pkgs/development/libraries/gstreamer/base/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ stdenv.mkDerivation rec {
doCheck = false; # fails, wants DRI access for OpenGL

passthru = {
propagateEnv = {
GST_PLUGIN_SYSTEM_PATH_1_0 = "%out%/lib/gstreamer-1.0";
};
# Downstream `gst-*` packages depending on `gst-plugins-base`
# have meson build options like 'gl' etc. that depend
# on these features being built in `-base`.
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/libraries/gstreamer/core/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,12 @@ stdenv.mkDerivation rec {
moveToOutput "share/bash-completion" "$dev"
'';

passthru = {
propagateEnv = {
GST_PLUGIN_SYSTEM_PATH_1_0 = "%out%/lib/gstreamer-1.0";
};
};

setupHook = ./setup-hook.sh;

meta = with lib ;{
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/libraries/gstreamer/ges/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ stdenv.mkDerivation rec {
sed -i -r -e 's/p(bad|good) = .*/p\1 = pbase/' tests/check/meson.build
'';

passthru = {
propagateEnv = {
GST_PLUGIN_SYSTEM_PATH_1_0 = "%out%/lib/gstreamer-1.0";
};
};

meta = with stdenv.lib; {
description = "Library for creation of audio/video non-linear editors";
homepage = "https://gstreamer.freedesktop.org";
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/libraries/gstreamer/good/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,12 @@ stdenv.mkDerivation rec {
# fails 1 tests with "Unexpected critical/warning: g_object_set_is_valid_property: object class 'GstRtpStorage' has no property named ''"
doCheck = false;

passthru = {
propagateEnv = {
GST_PLUGIN_SYSTEM_PATH_1_0 = "%out%/lib/gstreamer-1.0";
};
};

meta = with stdenv.lib; {
description = "GStreamer Good Plugins";
homepage = "https://gstreamer.freedesktop.org";
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/libraries/gstreamer/libav/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ stdenv.mkDerivation rec {
libav
];

passthru = {
propagateEnv = {
GST_PLUGIN_SYSTEM_PATH_1_0 = "%out%/lib/gstreamer-1.0";
};
};

meta = with lib; {
description = "FFmpeg/libav plugin for GStreamer";
homepage = "https://gstreamer.freedesktop.org";
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/libraries/gstreamer/ugly/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,12 @@ stdenv.mkDerivation rec {
DiskArbitration
]);

passthru = {
propagateEnv = {
GST_PLUGIN_SYSTEM_PATH_1_0 = "%out%/lib/gstreamer-1.0";
};
};

mesonFlags = [
"-Dexamples=disabled" # requires many dependencies and probably not useful for our users
"-Dsidplay=disabled" # sidplay / sidplay/player.h isn't packaged in nixpkgs as of writing
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/libraries/gstreamer/vaapi/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ stdenv.mkDerivation rec {
"-Dexamples=disabled" # requires many dependencies and probably not useful for our users
];

passthru = {
propagateEnv = {
GST_PLUGIN_SYSTEM_PATH_1_0 = "%out%/lib/gstreamer-1.0";
};
};

meta = with stdenv.lib; {
description = "Set of VAAPI GStreamer Plug-ins";
homepage = "https://gstreamer.freedesktop.org";
Expand Down
4 changes: 4 additions & 0 deletions pkgs/development/libraries/gtk/3.x.nix
Original file line number Diff line number Diff line change
Expand Up @@ -189,6 +189,10 @@ stdenv.mkDerivation rec {
packageName = "gtk+";
attrPath = "gtk3";
};
propagateEnv = {
XDG_DATA_DIRS = "%out%/share/gsettings-schemas/${pname}-${version}";
GI_TYPELIB_PATH = "%out%/lib/girepository-1.0";
};
};

meta = {
Expand Down
3 changes: 3 additions & 0 deletions pkgs/development/libraries/gvfs/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,9 @@ stdenv.mkDerivation rec {
updateScript = gnome3.updateScript {
packageName = pname;
};
propagateEnv = {
GIO_EXTRA_MODULES = "%out%/lib/gio/modules"
ryantm marked this conversation as resolved.
Show resolved Hide resolved
};
};

meta = with stdenv.lib; {
Expand Down
4 changes: 4 additions & 0 deletions pkgs/development/libraries/librsvg/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,10 @@ stdenv.mkDerivation rec {
updateScript = gnome3.updateScript {
packageName = pname;
};
propagateEnv = {
GDK_PIXBUF_MODULE_FILE = "%out%/${gdk-pixbuf.cacheFile}";
GI_TYPELIB_PATH = "%out%/lib/girepository-1.0";
};
};

meta = with stdenv.lib; {
Expand Down
3 changes: 3 additions & 0 deletions pkgs/development/libraries/pango/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,9 @@ in stdenv.mkDerivation rec {
updateScript = gnome3.updateScript {
packageName = pname;
};
propagateEnv = {
GI_TYPELIB_PATH = "%out%/lib/girepository-1.0";
};
};

meta = with stdenv.lib; {
Expand Down
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 @@ -35,7 +35,7 @@ let
if compareVersion "5.12.4" < 0 then ".qmake.cache" else ".qmake.stash";
in

stdenv.mkDerivation {
stdenv.mkDerivation rec {

name = "qtbase-${version}";
inherit qtCompatVersion src version;
Expand Down Expand Up @@ -161,6 +161,12 @@ stdenv.mkDerivation {
qtPluginPrefix = "lib/qt-${qtCompatVersion}/plugins";
qtQmlPrefix = "lib/qt-${qtCompatVersion}/qml";
qtDocPrefix = "share/doc/qt-${qtCompatVersion}";
passthru = {
propagateEnv = {
QT_PLUGIN_PATH = "%bin%/${qtPluginPrefix}";
# QML2_IMPORT_PATH = "%bin%/${qtQmlPrefix}";
};
};

setOutputFlags = false;
preConfigure = ''
Expand Down
6 changes: 6 additions & 0 deletions pkgs/development/libraries/qt-5/modules/qtcharts.nix
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,10 @@ qtModule {
name = "qtcharts";
qtInputs = [ qtbase qtdeclarative ];
outputs = [ "out" "dev" "bin" ];
passthru = {
propagateEnv = {
QT_PLUGIN_PATH = "%bin%/${qtbase.qtPluginPrefix}";
QML2_IMPORT_PATH = "%bin%/${qtbase.qtQmlPrefix}";
};
};
}
6 changes: 6 additions & 0 deletions pkgs/development/libraries/qt-5/modules/qtdeclarative.nix
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,10 @@ qtModule {
"bin/qmlscene"
"bin/qmltestrunner"
];
passthru = {
propagateEnv = {
QT_PLUGIN_PATH = "%bin%/${qtbase.qtPluginPrefix}";
QML2_IMPORT_PATH = "%bin%/${qtbase.qtQmlPrefix}";
};
};
}
Loading