#!/bin/sh # Forked from eselect opengl Gentoo module - this is reaaaaaaaaaally faster # this is used only at Live time, to avoid the use of Portage # Copyright 2006-2008 Fabio Erculiani # Our data ENV_FILE="/etc/env.d/03opengl" PREFIX="/usr" DST_PREFIX="/usr" USE_PROFILE_HEADERS="no" ES_VALID_MULTILIB_DIRS="lib lib32 lib64" # list_libdirs PUBLIC # Returns a space separated list of libdirs available on this machine list_libdirs() { local dir libdirs libdirs="" for dir in ${ES_VALID_MULTILIB_DIRS} ; do if grep -q "^/${dir}\(\|/\)$" /etc/ld.so.conf &> /dev/null ; then libdirs=( ${libdirs[@]} ${dir} ) fi done if [[ -z ${libdirs[@]} ]] ; then # Broken or non-existing ld.so.conf libdirs=( /lib* ) libdirs=( ${libdirs[@]/\/lib/lib} ) fi echo "${libdirs[@]}" } # has test list # Return true if list contains test has() { local test=${1} item shift for item in $@ ; do [[ ${item} == ${test} ]] && return 0 done return 1 } # is_function function PUBLIC # Test whether function exists is_function() { [[ $(type -t "${1}" ) == "function" ]] } # is_number PUBLIC # Returns true if and only if $1 is a positive whole number is_number() { [[ -n ${1} ]] && [[ -z ${1//[[:digit:]]} ]] } get_current_implementation() { local ret local ldpath=$(cat ${ENV_FILE} | grep LDPATH | cut -d'"' -f 2) local opengl_profile=$(cat ${ENV_FILE} | grep OPENGL_PROFILE | cut -d'"' -f 2) if [[ -n ${opengl_profile} ]] ; then ret="${opengl_profile}" elif [[ -n ${ldpath} ]] ; then ret="${ldpath%%:*}" ret="${ret##*opengl/}" ret="${ret%/lib*}" fi echo ${ret} } get_implementations() { local ret dir for x in $(list_libdirs) ; do for dir in "${PREFIX}/${x}"/opengl/* ; do [[ -d ${dir} && $(basename "${dir}") != "global" ]] || continue has $(basename "${dir}") ${ret} && continue ret=${ret:+${ret} }$(basename "${dir}") done done echo ${ret} } setup_lib_symlinks() { local profile_libdir=${1} local libdir=${2} local file local rootfile mkdir -p "${libdir}" || echo "Failed to create ${libdir}" pushd "${libdir}" &> /dev/null # First remove old symlinks for file in libGL{,core}.{a,so,la} ; do rm -f "${file}" || echo -q "Failed to delete ${file}" done # Note that we don't do .so*, just .so on purpose. The # loader knows to look in the profile dir, and the # linked just needs the .so for file in ${profile_libdir}/libGL{,core}.{so,a,la}; do rootfile="${file}" [[ -f ${file} ]] || continue if [[ -f $(basename "${file}") ]] ; then rm -f "$(basename "${file}")" || echo -q "Failed to delete ${libdir}/$(basename "${file}")" fi # Fix libtool archives (#48297) if [[ ${file%.la} != ${file} ]] ; then sed "s:${profile_libdir}:${libdir}:g" "${file}" > "$(basename "${file}")" || echo "Failed to create ${libdir}/$(basename "${file}")" else ln -s "${rootfile}" || echo "Failed to create ${libdir}/$(basename "${file}")" fi done popd &> /dev/null } set_new_implementation() { local gl_implem=${1} local avail_implems=$(get_implementations) # Set a sane umask... bug #83115 umask 022 if ! has ${gl_implem} ${avail_implems}; then echo "Invalid profile selected." exit 1 fi echo -n "Switching to ${gl_implem} OpenGL interface..." local libdir for libdir in $(list_libdirs); do [[ ${ROOT} != / ]] && libdir=${libdir//${ROOT}} # First make sure we have an opengl directory and this is a real lib dir, not a symlink [[ -d ${PREFIX}/${libdir}/opengl && ! -h ${PREFIX}/${libdir} ]] || continue # Fallback on xorg-x11 if we don't have this implementation for this libdir. local gl_local if [[ ! -d ${PREFIX}/${libdir}/opengl/"${gl_implem}" ]] ; then gl_local="xorg-x11" else gl_local="${gl_implem}" fi setup_lib_symlinks "${PREFIX}/${libdir}/opengl/${gl_local}/lib" "${DST_PREFIX}/${libdir}" if [[ -e ${PREFIX}/${libdir}/opengl/${gl_local}/lib/tls ]] ; then setup_lib_symlinks "${PREFIX}/${libdir}/opengl/${gl_local}/lib/tls" "${DST_PREFIX}/${libdir}/tls" fi local moduledir if [[ -e ${DST_PREFIX}/${libdir}/xorg/modules ]] ; then moduledir="xorg/modules" else moduledir="modules" fi if [[ -e ${PREFIX}/${libdir}/opengl/${gl_local}/extensions ]] ; then mkdir -p "${DST_PREFIX}/${libdir}/${moduledir}/extensions" || echo "Failed to create ${DST_PREFIX}/${libdir}/${moduledir}/extensions" pushd "${DST_PREFIX}/${libdir}/${moduledir}/extensions" &> /dev/null # First remove old symlinks for file in lib{wfb,glx,dri,dri2}.{a,so,la}; do rm -f "${file}" || echo "Failed to delete ${DST_PREFIX}/${libdir}/${moduledir}/extensions/${file}" done for file in ${PREFIX}/${libdir}/opengl/${gl_local}/extensions/*.{so,a,la}; do [[ -f ${file} ]] || continue if [[ -f $(basename "${file}") ]] ; then rm -f "$(basename "${file}")" || echo "Failed to delete ${DST_PREFIX}/${libdir}/${moduledir}/extensions/$(basename "${file}")" fi # Fix libtool archives (#48297) if [[ ${file%.la} != ${file} ]] ; then sed "s:${PREFIX}/[^/]*/opengl/[^/]*/lib:${DST_PREFIX}/${libdir}:g" "${file}" > "$(basename "${file}")" || echo "Failed to create ${DST_PREFIX}/${libdir}/${moduledir}/extensions/$(basename "${file}")" else ln -s "${file}" || echo "Failed to create ${libdir}/$(basename "${file}")" fi done popd &> /dev/null fi # Setup the includes mkdir -p "${DST_PREFIX}/include/GL" || echo "Failed to create ${DST_PREFIX}/include/GL" pushd "${DST_PREFIX}/include/GL" &> /dev/null for file in gl.h glx.h glxtokens.h glext.h glxext.h glxmd.h glxproto.h; do # IMPORTANT # It is preferable currently to use the standard glext.h file # however if an OpenGL provider must use a self produced glext.h # then it should be installed to ${gl_implem}/include and the user # can add the --impl-headers option to select it. if [[ "${USE_PROFILE_HEADERS}" == "yes" ]] ; then # Check the profile first. if [[ -e ${PREFIX}/${libdir}/opengl/${gl_implem}/include/${file} ]] ; then if [[ -f ${file} || ( -L ${file} && ! -e ${file} ) ]] ; then rm -f "${file}" || echo "Failed to delete ${DST_PREFIX}/include/GL/$(basename "${file}")" fi ln -s ${PREFIX}/${libdir}/opengl/${gl_implem}/include/${file} || echo "Failed to create ${DST_PREFIX}/include/GL/$(basename "${file}")" continue fi fi if [[ -e ${PREFIX}/${libdir}/opengl/global/include/${file} ]] ; then if [[ -f ${file} || ( -L ${file} && ! -e ${file} ) ]] ; then rm -f "${file}" || echo "Failed to delete ${DST_PREFIX}/include/GL/$(basename "${file}")" fi ln -s ${PREFIX}/${libdir}/opengl/global/include/${file} || echo "Failed to create ${DST_PREFIX}/include/GL/$(basename "${file}")" elif [[ -e ${PREFIX}/${libdir}/opengl/${gl_implem}/include/${file} ]] ; then if [[ -f ${file} || ( -L ${file} && ! -e ${file} ) ]] ; then rm -f "${file}" || echo "Failed to delete ${DST_PREFIX}/include/GL/$(basename "${file}")" fi ln -s ${PREFIX}/${libdir}/opengl/${gl_implem}/include/${file} || echo "Failed to create ${DST_PREFIX}/include/GL/$(basename "${file}")" elif [[ -e ${PREFIX}/${libdir}/opengl/xorg-x11/include/${file} ]] ; then if [[ -f ${file} || ( -L ${file} && ! -e ${file} ) ]] ; then rm -f "${file}" || echo "Failed to delete ${DST_PREFIX}/include/GL/$(basename "${file}")" fi ln -s ${PREFIX}/${libdir}/opengl/xorg-x11/include/${file} || echo "Failed to create ${DST_PREFIX}/include/GL/$(basename "${file}")" fi done popd &> /dev/null # Setup the $LDPATH ldpath="${ldpath:+${ldpath}:}${PREFIX}/${libdir}/opengl/${gl_local}/lib" done sed -i '/LDPATH=.*/d' ${ENV_FILE} echo "LDPATH=\"${ldpath}\"" >> ${ENV_FILE} oldldpath=$(cat /etc/profile.env|grep LDPATH | cut -d"'" -f2) sed -i '/export LDPATH=.*/d' /etc/profile.env sed -i '/setenv LDPATH=.*/d' /etc/csh.env sed -i '/export LD_LIBRARY_PATH=.*/d' /etc/profile.env sed -i '/setenv LD_LIBRARY_PATH=.*/d' /etc/csh.env sed -i "s/OPENGL_PROFILE=.*/OPENGL_PROFILE='${gl_implem}'/" /etc/profile.env sed -i "s/OPENGL_PROFILE=.*/OPENGL_PROFILE='${gl_implem}'/" /etc/csh.env sed -i '/LD_LIBRARY_PATH=.*/d' ${ENV_FILE} sed -i "s/OPENGL_PROFILE=.*/OPENGL_PROFILE=\"${gl_implem}\"/" ${ENV_FILE} echo "export LDPATH='"${ldpath}":"${oldldpath}"'" >> /etc/profile.env echo "setenv LDPATH='"${ldpath}":"${oldldpath}"'" >> /etc/csh.env echo "export LD_LIBRARY_PATH='"${ldpath}"'" >> /etc/profile.env echo "setenv LD_LIBRARY_PATH='"${ldpath}"'" >> /etc/csh.env echo 'LD_LIBRARY_PATH="'${ldpath}'"' >> ${ENV_FILE} source /etc/profile &> /dev/null echo " done" } do_set() { local action="error" local current=$(get_current_implementation) local available=$(get_implementations) local new while [[ ${#@} -gt 0 ]] ; do local opt=${1} shift case ${opt} in *) action="set-implementation" if has ${opt} ${available}; then new="${opt}" else echo "Unrecognized option: ${opt}" fi ;; esac done case ${action} in set-implementation) if [[ -n ${new} ]] ; then set_new_implementation ${new} rc=$? sed -i "s/opengl\/xorg-x11\//opengl\/${new}\//" /etc/ld.so.conf sed -i "s/opengl\/ati\//opengl\/${new}\//" /etc/ld.so.conf sed -i "s/opengl\/nvidia\//opengl\/${new}\//" /etc/ld.so.conf ldconfig -X &> /dev/null return ${rc} else echo "Please specify an implementation to set" fi ;; *) echo "Invalid usage of set action." ;; esac } do_show() { local current=$(get_current_implementation) echo ${current} } is_live=$(cat /proc/cmdline | grep cdroot) if [ -n "$is_live" ]; then if [ "$1" == "show" ]; then do_show else do_set $@ fi else if [ "$1" == "show" ]; then eselect opengl show else eselect opengl set $@ fi fi