summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--opencl.eselect/opencl.eselect340
1 files changed, 340 insertions, 0 deletions
diff --git a/opencl.eselect/opencl.eselect b/opencl.eselect/opencl.eselect
new file mode 100644
index 0000000..a29d095
--- /dev/null
+++ b/opencl.eselect/opencl.eselect
@@ -0,0 +1,340 @@
+# -*-eselect-*- vim: ft=eselect
+# Copyright 1999-2010 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+# Author: Martin Schlemmer <azarah@gentoo.org>
+# Further modifications by Michał Górny <mgorny@gentoo.org>
+# Further modifications by Tomáš Chvátal <scarabeus@gentoo.org>
+# Further modifications by Donnie Berkholz <dberkholz@gentoo.org>
+# Further modifications based off submissions to bug #54984 <cyfred@gentoo.org>
+# Further modifications by Jeremy Huddleston <eradicator@gentoo.org>
+# Made into eselect module by Jeremy Huddleston <eradicator@gentoo.org>
+
+inherit multilib package-manager config
+
+# Eselect data
+DESCRIPTION="Manage the OpenCL implementation used by your system"
+MAINTAINER="xarthisius@gentoo.org"
+SVN_DATE='$Date$'
+VERSION=$(svn_date_to_version "${SVN_DATE}" )
+EBUILD_VERSION="1.1.0"
+
+# Our data
+ENV_FILE="${EROOT}/etc/env.d/03opencl"
+PREFIX="${EROOT}/usr"
+DST_PREFIX="${EROOT}/usr"
+unset IGNORE_MISSING
+
+get_current_implementation() {
+ local ret
+ local ldpath=$(load_config "${ENV_FILE}" LDPATH)
+ local opencl_profile=$(load_config "${ENV_FILE}" OPENCL_PROFILE)
+
+ if [[ -n ${opencl_profile} ]] ; then
+ ret="${opencl_profile}"
+ elif [[ -n ${ldpath} ]] ; then
+ ret="${ldpath%%:*}"
+ ret="${ret##*OpenCL/vendors/}"
+ ret="${ret%/lib*}"
+ fi
+
+ echo ${ret}
+}
+
+get_implementations() {
+ local ret
+ local libdir
+ local dir
+ local dir_name
+
+ for libdir in $(list_libdirs) ; do
+ [[ ${ROOT} != / ]] && libdir=${libdir#${EROOT}}
+ for dir in "${PREFIX}/${libdir}"/OpenCL/vendors/* ; do
+ dir_name=$(basename "${dir}")
+ [[ -d ${dir} && ${dir_name} != "global" ]] || continue
+ has ${dir_name} ${ret} && continue
+ ret=${ret:+${ret} }${dir_name}
+ done
+ done
+
+ echo ${ret}
+}
+
+# 1: file
+# 2: workdir
+upgrade_file() {
+ local file=$1
+ local filename
+ local workdir=$2
+ local linkfile=$(relative_name ${file} "${workdir}")
+
+ [[ -f ${file} ]] || return
+ filename=$(basename "${file}")
+
+ if [[ -f ${filename} || ( -L ${filename} && ! -e ${filename} ) ]] ; then
+ rm -f "${filename}"* || die -q "Failed to delete ${workdir}/${filename}"
+ fi
+
+ #echo "DEBUG: ln -s \"${linkfile}\" \"${filename}\""
+ if [[ "x${REMOVE_ONLY}" == "xfalse" ]]; then
+ ln -s "${linkfile}" "${filename}" || die -q "Failed to create symlink ${workdir}/${filename}"
+ fi
+}
+
+setup_soname_symlinks() {
+ local file=$1
+ local target=$2
+ local soname
+ local scanner
+
+ # if we have .so or dylib we need to make its soname symlinked
+ # in order to be easy to find and faster to grab
+ if [[ ${file} == *.so || ${file} == *.dylib ]] ; then
+ [[ ${file} == *.so ]] && scanner=scanelf || scanner="scanmacho"
+ soname=$(${scanner} -qBF '%S|%p' "${file}" | head -n1)
+ soname=${soname%|*} # stupid scanelf must print filename
+ [[ ${file} == *.so ]] && soname="${file%/*}"/${soname}
+ upgrade_file "${soname}" "${target}"
+ fi
+}
+
+setup_lib_symlinks() {
+ local profile_libdir=$1
+ local target=$2
+ local file
+
+ mkdir -p "${target}" || die "Failed to create ${target}"
+
+ pushd "${target}" &> /dev/null
+ for file in "${profile_libdir}"/lib*.so; do
+ upgrade_file "${file}" "${target}"
+ setup_soname_symlinks "${file}" "${target}"
+ done
+ popd &> /dev/null
+}
+
+setup_includes_symlinks() {
+ local target=$1
+ local file
+ local sdir
+
+ shift
+
+ mkdir -p "${target}" || die "Failed to create ${target}"
+ pushd "${target}" &> /dev/null
+ for file in cl_ext.h cl_gl_ext.h cl_gl.h cl.h cl_platform.h opencl.h; do
+ for sdir in "$@"; do
+ if [[ -e ${sdir}/${file} ]]; then
+ upgrade_file "${sdir}/${file}" "${target}"
+ break
+ fi
+ done
+ done
+ popd &> /dev/null
+}
+
+set_new_implementation() {
+ local cl_implem=$1
+ local avail_implems=$(get_implementations)
+ local libdir
+ local moduledir
+ local gl_dir
+ local cl_local
+
+ # Set a sane umask... bug #83115
+ umask 022
+
+ if ! has ${cl_implem} ${avail_implems}; then
+ die -q "Invalid opencl implementation selected."
+ fi
+
+ if [[ -z ${IGNORE_MISSING+1} ]]; then
+ local found_opencl
+ for libdir in $(list_libdirs); do
+ [[ ${ROOT} != / ]] && libdir=${libdir#${EROOT}}
+ [[ -d ${PREFIX}/${libdir}/OpenCL && ! -h ${PREFIX}/${libdir} ]] || continue
+ [[ -f "${PREFIX}/${libdir}/OpenCL/vendors/${cl_implem}/libOpenCL.so" ]] && found_opencl=yes
+ echo "${PREFIX}/${libdir}/OpenCL/vendors/${cl_implem}/libOpenCL.so"
+ done
+
+ if [[ -z ${found_opencl} ]]; then
+ write_error_msg "The ${cl_implem} OpenCL implementation doesn't seem to provide"
+ write_error_msg "libOpenCL.so file. This might be an effect of breakage introduced"
+ write_error_msg "by a prioprietary driver installer. Please re-merge the package"
+ write_error_msg "providing your OpenCL implementation."
+ die -q "Selected OpenCL implementation incomplete."
+ fi
+ fi
+
+ echo -n "Switching to ${cl_implem} OpenCL interface..."
+ if [[ -f ${ENV_FILE} ]] ; then
+ rm -f "${ENV_FILE}" || die -q "Failed to remove ${ENV_FILE}"
+ fi
+
+ for libdir in $(list_libdirs); do
+ # Set libdir correctly to EROOT
+ [[ ${ROOT} != / ]] && libdir=${libdir#${EROOT}}
+
+ # First make sure we have an opencl directory and this
+ # is a real lib dir, not a symlink
+ [[ -d ${PREFIX}/${libdir}/OpenCL && ! -h ${PREFIX}/${libdir} ]] || continue
+
+ # Check if opencl implementation directory exists
+ # and use xorg-x11 as fallback (mesa)
+ # If even mesa is not around then simply die
+ if [[ -d "${PREFIX}/${libdir}/OpenCL/vendors/${cl_implem}" ]] ; then
+ cl_local="${cl_implem}"
+ REMOVE_ONLY="false" # global variable
+ else
+ # we are moving to implementation that does not have any support
+ # for specified libdir (ie 32bit libs for mesa) so we should
+ # remove the current symlinks and continue like nothing happened.
+ REMOVE_ONLY="true" # global variable
+ cl_local=$(get_current_implementation)
+ if ! has ${cl_local} ${avail_implems}; then
+ # skipping the libdir cause there was no profile actually
+ # selected before
+ continue 2
+ fi
+ fi
+
+ setup_lib_symlinks \
+ "${PREFIX}/${libdir}/OpenCL/vendors/${cl_local}/" \
+ "${DST_PREFIX}/${libdir}"
+
+ setup_includes_symlinks \
+ "${DST_PREFIX}/include/CL" \
+ "${PREFIX}/${libdir}/OpenCL/vendors/${cl_implem}/include/CL/" \
+ "${PREFIX}/${libdir}/OpenCL/vendors/${cl_implem}/include/" \
+ "${PREFIX}/${libdir}/OpenCL/global/include/"
+
+ # Setup the $LDPATH
+ if [[ "x${REMOVE_ONLY}" == "xfalse" ]]; then
+ # we need this relative to ROOT
+ ldpath="${ldpath:+${ldpath}:}${PREFIX#${ROOT}}/${libdir}/OpenCL/vendors/${cl_local}"
+ fi
+ done
+
+ store_config ${ENV_FILE} LDPATH "${ldpath}"
+ store_config ${ENV_FILE} OPENCL_PROFILE "${cl_implem}"
+
+ do_action env update &> /dev/null
+
+ echo " done"
+}
+
+### show action ###
+describe_show() {
+ echo "Print the current OpenCL implementation."
+}
+
+do_show() {
+ local current=$(get_current_implementation)
+
+ if [[ -n ${current} ]] ; then
+ echo ${current}
+ return 0
+ else
+ echo "(none)"
+ return 2
+ fi
+}
+
+### list action ###
+describe_list() {
+ echo "List the available OpenCL implementations."
+}
+
+do_list() {
+ local targets=( $(get_implementations) )
+ local i
+
+ write_list_start "Available OpenCL implementations:"
+ for (( i = 0; i < ${#targets[@]}; i++ )); do
+ [[ ${targets[i]} = $(get_current_implementation) ]] \
+ && targets[i]=$(highlight_marker "${targets[i]}")
+ done
+ write_numbered_list -m "(none found)" "${targets[@]}"
+}
+
+### set action ###
+describe_set() {
+ echo "Select the OpenCL implementation."
+}
+
+describe_set_parameters() {
+ echo "<target>"
+}
+
+describe_set_options() {
+ echo "<target> : The profile to activate"
+ echo "--use-old : If an implementation is already set, use that one instead"
+ echo "--prefix=<val> : Set the source prefix (default: /usr)"
+ echo "--dst-prefix=<val> : Set the destination prefix (default: /usr)"
+ echo "--ignore-missing : Ignore missing files when setting a new implementation"
+}
+
+do_set() {
+ local action="error"
+ local current=$(get_current_implementation)
+ local available=$(get_implementations)
+ local new
+ local opt
+
+ while [[ ${#@} -gt 0 ]] ; do
+ opt=$1
+ shift
+ case ${opt} in
+ --use-old)
+ if [[ -n ${current} ]] && has ${current} ${available}; then
+ action="old-implementation"
+ fi
+ ;;
+ --prefix=*)
+ PREFIX=${ROOT}${opt#*=}
+ available=$(get_implementations)
+ ;;
+ --dst-prefix=*)
+ DST_PREFIX=${ROOT}${opt#*=}
+ ;;
+ --ignore-missing)
+ IGNORE_MISSING=1
+ ;;
+ *)
+ if [[ ${action} != "old-implementation" ]] ; then
+ action="set-implementation"
+ fi
+
+ if is_number ${opt} ; then
+ targets=( $(get_implementations) )
+ new=${targets[$(( ${opt} - 1 ))]}
+ if [[ -z ${new} ]] ; then
+ die -q "Unrecognized option: ${opt}"
+ fi
+ elif has ${opt} ${available}; then
+ new="${opt}"
+ else
+ die -q "Unrecognized option: ${opt}"
+ fi
+ ;;
+ esac
+ done
+
+ case ${action} in
+ old-implementation)
+ set_new_implementation ${current}
+ return $?
+ ;;
+ set-implementation)
+ if [[ -n ${new} ]] ; then
+ set_new_implementation ${new}
+ return $?
+ else
+ die -q "Please specify an implementation to set"
+ fi
+ ;;
+ *)
+ die -q "Invalid usage of set action."
+ ;;
+ esac
+}