opengl: Automatically insert virtualgl into opengl executables

This commit is contained in:
Tyson Whitehead
2018-07-12 00:28:01 -04:00
parent fb163ecb85
commit 115ac559ec
3 changed files with 198 additions and 0 deletions

View File

@@ -20,6 +20,8 @@ self: super: pkgs: with pkgs; {
#meraculous = callPackage ./meraculous.nix { };
inherit (callPackages ./opengl/default.nix { inherit super; }) mesa_noglu;
inherit (callPackages ./octopus/octopus.nix { }) octopus72;
octopus7 = octopus72;
octopus = octopus7;

160
pkgs/opengl/auto-virtualgl.sh Executable file
View File

@@ -0,0 +1,160 @@
#!/bin/bash
# Stream producers
#
# These produce a stream of escaped new-line separated items
#
# Stream the given arguments
#
VGL_sourceS() {
( printf '%q\n' "$@" ) || (( $? == 141 ))
}
# Stream the results of the given command
#
VGL_systemS() {
declare -a command=("$@")
( eval $(printf '%q ' "${command[@]}") ) || (( $? == 141 ))
}
# Stream the results of find (correctly escapes all filenames)
#
VGL_findS() {
declare -a options=("$@") file
VGL_systemS find "${options[@]}" -print0 |
while read -d '' -r file; do
VGL_sourceS "$file"
done
}
# Stream the closure of the list libraries from an elf file
#
VGL_elfLibsS() {
declare file=$1 line
VGL_systemS ldd "$file" |
while read line; do
line=${line#$'\t'}
case "$line" in
*' => not found')
line=${line% => not found}
;;
*' => '*' ('*')')
line=${line#* => }
line=${line% (*)}
;;
*' ('*')')
line=${line% (*)}
;;
esac
VGL_sourceS "$line"
done
}
# Stream transformers
#
# Take in a set of options and transform a stream of new-line separated items
#
# Group all items onto a single line separated by given deliminator (or space)
#
VGL_joinS() {
declare deliminator=${1- } next
if read next; then
printf '%q' "$next"
while read next; do
printf '%s%q' "$deliminator" "$next"
done
printf '\n'
fi
}
# Remove all items for which the given command returns false
#
VGL_filterS() {
declare command=("$@")
while read next; do
if eval $(printf '%q ' "${command[@]}" "$next"); then
VGL_sourceS "$next"
fi
done
}
# Stream consumers
#
# These consume a stream of escaped new-line separated items
#
VGL_anyS() {
declare command=("$@")
while read next; do
if eval $(printf '%q ' "${command[@]}" "$next"); then
return 0
fi
done
return 1
}
# Tests for the filter transformer
#
# Check for an elf file (binary or library)
#
VGL_isElfBin() {
declare file=$1
case "$(file -b -N --mime-type "$file")" in
application/x-executable | application/x-pie-executable)
return 0 ;;
*)
return 1 ;;
esac
}
# Check for libGL
#
VGL_isLibGL() {
declare file=$1
case "$file" in
libGL.so* | */libGL.so*)
return 0 ;;
*)
return 1 ;;
esac
}
# Setup hook
#
# Find all executables that depend on libGL and add a libvglfaker.so dependency
#
VGL_autoAddVGL() {
echo "Inserting VirtualGL into OpenGL executables in $prefix..." >&2
for output in $outputs; do
VGL_findS "${!output}" -type f | VGL_filterS VGL_isElfBin | {
declare file
while read file; do
VGL_elfLibsS "$file" |
if VGL_anyS VGL_isLibGL; then
VGL_sourceS "$file"
fi
done
} | {
declare file
while read file; do
printf 'patchelf --add-needed @virtualglLib@/lib/libvglfaker.so %q\n' "$file" >&2
patchelf --add-needed @virtualglLib@/lib/libvglfaker.so "$file"
done
}
done
}
postFixupHooks+=(VGL_autoAddVGL)

36
pkgs/opengl/default.nix Normal file
View File

@@ -0,0 +1,36 @@
# This override makes OpenGL just automagically work with VirtualGL
#
# Add a setup hook to the mesa_noglu package that automatically adds
# a libvglfaker.so dependency to executables that depend on libGL.so.
{ super, lib, buildEnv, makeSetupHook, file }:
let
autoVirtualGLHook =
let
mesa_noglu = super.mesa_noglu;
mesa_glu = super.mesa_glu.override { inherit mesa_noglu; };
mesa = buildEnv {
name = "mesa-${mesa_noglu.version}";
paths = [ mesa_noglu.dev mesa_noglu.out mesa_glu mesa_glu.dev ];
meta = {
platforms = lib.platforms.unix;
};
};
libGL = mesa_noglu;
libGLU = mesa_glu;
libGLU_combined = mesa;
virtualglLib = (super.virtualglLib.override { inherit libGLU_combined fltk; });
fltk = super.fltk.override { inherit libGLU_combined freeglut; };
freeglut = super.freeglut.override { inherit libGL libGLU; };
in
makeSetupHook {
deps = [ file virtualglLib ];
substitutions = { inherit virtualglLib; };
} ./auto-virtualgl.sh;
in {
mesa_noglu = super.mesa_noglu.overrideAttrs ( attrs: {
propagatedBuildInputs = attrs.propagatedBuildInputs or [] ++ [ autoVirtualGLHook ];
} );
}