opengl: Automatically insert virtualgl into opengl executables
This commit is contained in:
@@ -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
160
pkgs/opengl/auto-virtualgl.sh
Executable 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
36
pkgs/opengl/default.nix
Normal 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 ];
|
||||
} );
|
||||
}
|
||||
Reference in New Issue
Block a user