From f93918bdc387d353285f458c06c6a111ae90b7b2 Mon Sep 17 00:00:00 2001 From: Doron Behar Date: Fri, 22 May 2020 20:27:38 +0300 Subject: [PATCH] mpv: Move all wrappings to a single wrapper Nix function Inspired by `wrapNeovim`, write a wrapMpv Nix function that creates a derivation that has all of the environment that was added if needed at the unwrapped version. Add derivations to all-packages.nix in an almost compatible way and make `mpv-with-scripts` throw a message implying to switch to `wrapMpv` which has an incompatible signature. Add to vapoursynth a new passthru attribute `python3` that is used in passed down to the wrapper to ensure ABI compatibility with `PYTHONPATH`. --- pkgs/applications/video/mpv/default.nix | 41 ++++----- pkgs/applications/video/mpv/wrapper.nix | 89 ++++++++++++++++--- .../libraries/vapoursynth/default.nix | 8 ++ pkgs/top-level/aliases.nix | 1 + pkgs/top-level/all-packages.nix | 6 +- 5 files changed, 109 insertions(+), 36 deletions(-) diff --git a/pkgs/applications/video/mpv/default.nix b/pkgs/applications/video/mpv/default.nix index 8bb5d5aca1f..9cb39d68140 100644 --- a/pkgs/applications/video/mpv/default.nix +++ b/pkgs/applications/video/mpv/default.nix @@ -1,4 +1,4 @@ -{ config, stdenv, fetchurl, fetchFromGitHub, makeWrapper, fetchpatch +{ config, stdenv, fetchurl, fetchFromGitHub, fetchpatch , addOpenGLRunpath, docutils, perl, pkgconfig, python3, wafHook, which , ffmpeg_4, freefont_ttf, freetype, libass, libpthreadstubs, mujs , nv-codec-headers, lua, libuchardet, libiconv ? null @@ -50,7 +50,6 @@ , vdpauSupport ? true, libvdpau ? null , xineramaSupport ? stdenv.isLinux, libXinerama ? null , xvSupport ? stdenv.isLinux, libXv ? null -, youtubeSupport ? true, youtube-dl ? null , zimgSupport ? true, zimg ? null , archiveSupport ? true, libarchive ? null , jackaudioSupport ? false, libjack2 ? null @@ -91,7 +90,6 @@ assert waylandSupport -> all available [ wayland wayland-protocols libxkbcom assert x11Support -> all available [ libGLU libGL libX11 libXext libXxf86vm libXrandr ]; assert xineramaSupport -> x11Support && available libXinerama; assert xvSupport -> x11Support && available libXv; -assert youtubeSupport -> available youtube-dl; assert zimgSupport -> available zimg; let @@ -112,6 +110,20 @@ in stdenv.mkDerivation rec { patchShebangs ./TOOLS/ ''; + passthru = { + inherit + # The wrapper consults luaEnv and lua.version + luaEnv + lua + # In the wrapper, we want to reference vapoursynth which has the + # `python3` passthru attribute (which has the `sitePrefix` + # attribute). This way we'll be sure that in the wrapper we'll + # use the same python3.sitePrefix used to build vapoursynth. + vapoursynthSupport + vapoursynth + ; + }; + NIX_LDFLAGS = optionalString x11Support "-lX11 -lXext " + optionalString stdenv.isDarwin "-framework CoreFoundation"; @@ -135,7 +147,7 @@ in stdenv.mkDerivation rec { ++ stdenv.lib.optional (!swiftSupport) "--disable-macos-cocoa-cb"; nativeBuildInputs = [ - addOpenGLRunpath docutils makeWrapper perl pkgconfig python3 wafHook which + addOpenGLRunpath docutils perl pkgconfig python3 wafHook which ] ++ optional swiftSupport swift; @@ -164,7 +176,6 @@ in stdenv.mkDerivation rec { ++ optional vdpauSupport libvdpau ++ optional xineramaSupport libXinerama ++ optional xvSupport libXv - ++ optional youtubeSupport youtube-dl ++ optional zimgSupport zimg ++ optional stdenv.isDarwin libiconv ++ optional stdenv.isLinux nv-codec-headers @@ -182,17 +193,6 @@ in stdenv.mkDerivation rec { python3 TOOLS/osxbundle.py -s build/mpv ''; - # Ensure youtube-dl is available in $PATH for mpv - wrapperFlags = - ''--prefix LUA_CPATH ';' "${luaEnv}/lib/lua/${lua.luaversion}/?.so" \'' + - ''--prefix LUA_PATH ';' "${luaEnv}/share/lua/${lua.luaversion}/?.lua" \'' + - ''--prefix PATH : "${luaEnv}/bin" \'' - + optionalString youtubeSupport '' - --prefix PATH : "${youtube-dl}/bin" \ - '' + optionalString vapoursynthSupport '' - --prefix PYTHONPATH : "${vapoursynth}/lib/${python3.libPrefix}/site-packages:$PYTHONPATH" - ''; - patches = stdenv.lib.optionals stdenv.isDarwin [ # Fix cocoa backend. Remove with the next release (fetchpatch { @@ -205,24 +205,17 @@ in stdenv.mkDerivation rec { # Use a standard font mkdir -p $out/share/mpv ln -s ${freefont_ttf}/share/fonts/truetype/FreeSans.ttf $out/share/mpv/subfont.ttf - wrapProgram "$out/bin/mpv" \ - ${wrapperFlags} cp TOOLS/umpv $out/bin - wrapProgram $out/bin/umpv \ - --set MPV "$out/bin/mpv" - '' + optionalString stdenv.isDarwin '' mkdir -p $out/Applications cp -r build/mpv.app $out/Applications - wrapProgram "$out/Applications/mpv.app/Contents/MacOS/mpv" \ - ${wrapperFlags} ''; # Set RUNPATH so that libcuda in /run/opengl-driver(-32)/lib can be found. # See the explanation in addOpenGLRunpath. postFixup = optionalString stdenv.isLinux '' - addOpenGLRunpath $out/bin/.mpv-wrapped + addOpenGLRunpath $out/bin/mpv ''; meta = with stdenv.lib; { diff --git a/pkgs/applications/video/mpv/wrapper.nix b/pkgs/applications/video/mpv/wrapper.nix index 53def80e7da..1658f922ab3 100644 --- a/pkgs/applications/video/mpv/wrapper.nix +++ b/pkgs/applications/video/mpv/wrapper.nix @@ -1,14 +1,83 @@ -{ stdenv, symlinkJoin, makeWrapper, mpv, scripts ? [] }: +# Arguments that this derivation gets when it is created with `callPackage` +{ stdenv +, lib +, symlinkJoin +, makeWrapper +, youtube-dl +}: -symlinkJoin { - name = "mpv-with-scripts-${mpv.version}"; +# the unwrapped mpv derivation - 1st argument to `wrapMpv` +mpv: - paths = [ mpv ]; +let + # arguments to the function (called `wrapMpv` in all-packages.nix) + wrapper = { + extraMakeWrapperArgs ? [], + youtubeSupport ? true, + # a set of derivations (probably from `mpvScripts`) where each is + # expected to have a `scriptName` passthru attribute that points to the + # name of the script that would reside in the script's derivation's + # `$out/share/mpv/scripts/`. + scripts ? [], + extraUmpvWrapperArgs ? [] + }: + let + binPath = lib.makeBinPath ([ + mpv.luaEnv + ] ++ lib.optionals youtubeSupport [ + youtube-dl + ] ++ lib.optionals mpv.vapoursynthSupport [ + mpv.vapoursynth.python3 + ]); + # All arguments besides the input and output binaries (${mpv}/bin/mpv and + # $out/bin/mpv). These are used by the darwin specific makeWrapper call + # used to wrap $out/Applications/mpv.app/Contents/MacOS/mpv as well. + mostMakeWrapperArgs = builtins.concatStringsSep " " ([ "--argv0" "'$0'" + # These are always needed (TODO: Explain why) + "--prefix" "LUA_CPATH" "\\;" "${mpv.luaEnv}/lib/lua/${mpv.lua.luaversion}/\\?.so" + "--prefix" "LUA_PATH" "\\;" "${mpv.luaEnv}/share/lua/${mpv.lua.luaversion}/\\?.lua" + ] ++ lib.optionals mpv.vapoursynthSupport [ + "--prefix" "PYTHONPATH" ":" "${mpv.vapoursynth}/lib/${mpv.vapoursynth.python3.sitePackages}" + ] ++ lib.optionals (binPath != "") [ + "--prefix" "PATH" ":" binPath + ] ++ (lib.lists.flatten (map + # For every script in the `scripts` argument, add the necessary flags to the wrapper + (script: + [ + "--add-flags" + # Here we rely on the existence of the `scriptName` passthru + # attribute of the script derivation from the `scripts` + "--script=${script}/share/mpv/scripts/${script.scriptName}" + ] + ) scripts + )) ++ extraMakeWrapperArgs) + ; + umpvWrapperArgs = builtins.concatStringsSep " " ([ + "--argv0" "'$0'" + "--set" "MPV" "$out/bin/mpv" + ] ++ extraUmpvWrapperArgs) + ; + in + symlinkJoin { + name = "mpv-with-scripts-${mpv.version}"; - buildInputs = [ makeWrapper ]; + paths = [ mpv ]; - postBuild = '' - wrapProgram $out/bin/mpv \ - --add-flags "${stdenv.lib.concatMapStringsSep " " (x: "--script=${x}/share/mpv/scripts/${x.scriptName}") scripts}" - ''; -} + buildInputs = [ makeWrapper ]; + + passthru.unwrapped = mpv; + + postBuild = '' + # wrapProgram can't operate on symlinks + rm "$out/bin/mpv" + makeWrapper "${mpv}/bin/mpv" "$out/bin/mpv" ${mostMakeWrapperArgs} + rm "$out/bin/umpv" + makeWrapper "${mpv}/bin/umpv" "$out/bin/umpv" ${umpvWrapperArgs} + '' + lib.optionalString stdenv.isDarwin '' + # wrapProgram can't operate on symlinks + rm "$out/Applications/mpv.app/Contents/MacOS/mpv" + makeWrapper "${mpv}/Applications/mpv.app/Contents/MacOS/mpv" "$out/Applications/mpv.app/Contents/MacOS/mpv" ${mostMakeWrapperArgs} + ''; + }; +in + lib.makeOverridable wrapper diff --git a/pkgs/development/libraries/vapoursynth/default.nix b/pkgs/development/libraries/vapoursynth/default.nix index 043bfb007a3..87f35fbf60c 100644 --- a/pkgs/development/libraries/vapoursynth/default.nix +++ b/pkgs/development/libraries/vapoursynth/default.nix @@ -36,6 +36,14 @@ stdenv.mkDerivation rec { enableParallelBuilding = true; + passthru = { + # If vapoursynth is added to the build inputs of mpv and then + # used in the wrapping of it, we want to know once inside the + # wrapper, what python3 version was used to build vapoursynth so + # the right python3.sitePackages will be used there. + inherit python3; + }; + postInstall = '' wrapProgram $out/bin/vspipe \ --prefix PYTHONPATH : $out/${python3.sitePackages} diff --git a/pkgs/top-level/aliases.nix b/pkgs/top-level/aliases.nix index 1ef754ccba0..f19c7318172 100644 --- a/pkgs/top-level/aliases.nix +++ b/pkgs/top-level/aliases.nix @@ -302,6 +302,7 @@ mapAliases ({ msf = metasploit; # added 2018-04-25 libmsgpack = msgpack; # added 2018-08-17 mssys = ms-sys; # added 2015-12-13 + mpv-with-scripts = throw "Use wrapMpv for editing the environment of mpv"; # added 2012-05-22 multipath_tools = multipath-tools; # added 2016-01-21 mupen64plus1_5 = mupen64plus; # added 2016-02-12 mysqlWorkbench = mysql-workbench; # added 2017-01-19 diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 4cfd71b806c..3206632041e 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -20862,12 +20862,14 @@ in libdvdnav = libdvdnav_4_2_1; } // (config.mplayer or {})); - mpv = callPackage ../applications/video/mpv { + mpv-unwrapped = callPackage ../applications/video/mpv { inherit lua; inherit (darwin.apple_sdk.frameworks) CoreFoundation Cocoa CoreAudio MediaPlayer; }; - mpv-with-scripts = callPackage ../applications/video/mpv/wrapper.nix { }; + # Wraps without trigerring a rebuild + wrapMpv = callPackage ../applications/video/mpv/wrapper.nix { }; + mpv = wrapMpv mpv-unwrapped {}; mpvScripts = recurseIntoAttrs { convert = callPackage ../applications/video/mpv/scripts/convert.nix {};