nixpkgs-suyu/pkgs/development/libraries/vapoursynth/plugin-interface.nix
Simon Bruder 9b3a2e66b1
vapoursynth: improve plugin dependency resolution
Some python packages (e.g. functools32) are conditionally disabled for
certain interpreter versions by having them return null instead of a
derivation. `getRecursivePropagatedBuildInputs` fails if such a package
is part of the dependency tree. This commit makes it only recurse into
derivations and ignore everything else.

This also deduplicates the final plugin list to improve startup time.
2021-05-16 16:55:51 +02:00

113 lines
3.4 KiB
Nix

{ lib, python3, buildEnv, writeText, runCommandCC, stdenv, runCommand
, vapoursynth, makeWrapper, withPlugins }:
plugins: let
pythonEnvironment = python3.buildEnv.override {
extraLibs = plugins;
};
getRecursivePropagatedBuildInputs = pkgs: lib.flatten
(map
(pkg: let cleanPropagatedBuildInputs = lib.filter lib.isDerivation pkg.propagatedBuildInputs;
in cleanPropagatedBuildInputs ++ (getRecursivePropagatedBuildInputs cleanPropagatedBuildInputs))
pkgs);
deepPlugins = lib.unique (plugins ++ (getRecursivePropagatedBuildInputs plugins));
pluginsEnv = buildEnv {
name = "vapoursynth-plugins-env";
pathsToLink = [ "/lib/vapoursynth" ];
paths = deepPlugins;
};
pluginLoader = let
source = writeText "vapoursynth-nix-plugins.c" ''
void VSLoadPluginsNix(void (*load)(void *data, const char *path), void *data) {
${lib.concatMapStringsSep "" (path: "load(data, \"${path}/lib/vapoursynth\");") deepPlugins}
}
'';
in
runCommandCC "vapoursynth-plugin-loader" {
executable = true;
preferLocalBuild = true;
allowSubstitutes = false;
} ''
mkdir -p $out/lib
$CC -shared -fPIC ${source} -o "$out/lib/libvapoursynth-nix-plugins${ext}"
'';
ext = stdenv.targetPlatform.extensions.sharedLibrary;
in
runCommand "${vapoursynth.name}-with-plugins" {
nativeBuildInputs = [ makeWrapper ];
passthru = {
inherit python3;
withPlugins = plugins': withPlugins (plugins ++ plugins');
};
} ''
mkdir -p \
$out/bin \
$out/lib/pkgconfig \
$out/lib/vapoursynth \
$out/${python3.sitePackages}
for textFile in \
lib/pkgconfig/vapoursynth{,-script}.pc \
lib/libvapoursynth.la \
lib/libvapoursynth-script.la \
${python3.sitePackages}/vapoursynth.la
do
substitute ${vapoursynth}/$textFile $out/$textFile \
--replace "${vapoursynth}" "$out"
done
for binaryPlugin in ${pluginsEnv}/lib/vapoursynth/*; do
ln -s $binaryPlugin $out/''${binaryPlugin#"${pluginsEnv}/"}
done
for pythonPlugin in ${pythonEnvironment}/${python3.sitePackages}/*; do
ln -s $pythonPlugin $out/''${pythonPlugin#"${pythonEnvironment}/"}
done
for binaryFile in \
lib/libvapoursynth${ext} \
lib/libvapoursynth-script${ext}.0.0.0
do
old_rpath=$(patchelf --print-rpath ${vapoursynth}/$binaryFile)
new_rpath="$old_rpath:$out/lib"
patchelf \
--set-rpath "$new_rpath" \
--output $out/$binaryFile \
${vapoursynth}/$binaryFile
patchelf \
--add-needed libvapoursynth-nix-plugins${ext} \
$out/$binaryFile
done
for binaryFile in \
${python3.sitePackages}/vapoursynth${ext} \
bin/.vspipe-wrapped
do
old_rpath=$(patchelf --print-rpath ${vapoursynth}/$binaryFile)
new_rpath="''${old_rpath//"${vapoursynth}"/"$out"}"
patchelf \
--set-rpath "$new_rpath" \
--output $out/$binaryFile \
${vapoursynth}/$binaryFile
done
ln -s \
${pluginLoader}/lib/libvapoursynth-nix-plugins${ext} \
$out/lib/libvapoursynth-nix-plugins${ext}
ln -s ${vapoursynth}/include $out/include
ln -s ${vapoursynth}/lib/vapoursynth/* $out/lib/vapoursynth
ln -s \
libvapoursynth-script${ext}.0.0.0 \
$out/lib/libvapoursynth-script${ext}
ln -s \
libvapoursynth-script${ext}.0.0.0 \
$out/lib/libvapoursynth-script${ext}.0
makeWrapper $out/bin/.vspipe-wrapped $out/bin/vspipe \
--prefix PYTHONPATH : $out/${python3.sitePackages}
''