Added multilib functions to handle installing include files for separate ABIs.
authorJeremy Huddleston <eradicator@gentoo.org>
Wed, 12 Jan 2005 11:13:28 +0000 (11:13 +0000)
committerJeremy Huddleston <eradicator@gentoo.org>
Wed, 12 Jan 2005 11:13:28 +0000 (11:13 +0000)
eclass/kernel-2.eclass
eclass/multilib.eclass

index 6123c91a1240f8a8592a3b25116bdd6aaeb70515..11f3e80313e0dacdc347a5014e0fb350a4d7e1c9 100644 (file)
@@ -1,6 +1,6 @@
 # Copyright 1999-2005 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/kernel-2.eclass,v 1.76 2005/01/12 05:07:24 eradicator Exp $
+# $Header: /var/cvsroot/gentoo-x86/eclass/kernel-2.eclass,v 1.77 2005/01/12 11:13:28 eradicator Exp $
 
 # Description: kernel.eclass rewrite for a clean base regarding the 2.6
 #              series of kernel with back-compatibility for 2.4
@@ -42,7 +42,7 @@
 # UNIPATCH_STRICTORDER - if this is set places patches into directories of
 #                                                order, so they are applied in the order passed
 
-inherit toolchain-funcs
+inherit toolchain-funcs multilib
 
 ECLASS="kernel-2"
 INHERITED="$INHERITED $ECLASS"
@@ -300,18 +300,17 @@ install_headers() {
                dodir ${ddir}/asm-sparc64
                cp -ax ${S}/include/asm-sparc/* ${D}/usr/include/asm-sparc
                cp -ax ${S}/include/asm-sparc64/* ${D}/usr/include/asm-sparc64
-               generate_sparc_asm ${D}/usr/include
-       else
-               cp -ax ${S}/include/asm/* ${D}/${ddir}/asm
-       fi
 
-       if [ "${ARCH}" = "amd64" ]; then
+               #generate_sparc_asm ${D}/usr/include
+               create_ml_includes /usr/include/asm __sparc__:/usr/include/asm-sparc __sparc64__:/usr/include/asm-sparc64
+       elif [ "${ARCH}" = "amd64" ]; then
                rm -Rf ${D}/${ddir}/asm
                dodir ${ddir}/asm-i386
                dodir ${ddir}/asm-x86_64
                cp -ax ${S}/include/asm-i386/* ${D}/usr/include/asm-i386
                cp -ax ${S}/include/asm-x86_64/* ${D}/usr/include/asm-x86_64
-               /bin/sh ${FILESDIR}/generate-asm-amd64 ${D}/usr/include
+               #/bin/sh ${FILESDIR}/generate-asm-amd64 ${D}/usr/include
+               create_ml_includes /usr/include/asm __i386__:/usr/include/asm-i386 __x86_64__:/usr/include/asm-x86_64
        else
                cp -ax ${S}/include/asm/* ${D}/${ddir}/asm
        fi
index aa065b22feff9fe635b1537d1d56d486e508a229..10d33a67d1be1f854fa0cbd91562a85780906a46 100644 (file)
@@ -1,6 +1,6 @@
 # Copyright 1999-2004 Gentoo Foundation
 # Distributed under the terms of the GNU General Public License v2
-# $Header: /var/cvsroot/gentoo-x86/eclass/multilib.eclass,v 1.1 2005/01/12 00:21:53 eradicator Exp $
+# $Header: /var/cvsroot/gentoo-x86/eclass/multilib.eclass,v 1.2 2005/01/12 11:13:28 eradicator Exp $
 #
 # Author: Jeremy Huddleston <eradicator@gentoo.org>
 #
@@ -12,6 +12,8 @@ INHERITED="$INHERITED $ECLASS"
 
 DESCRIPTION="Based on the ${ECLASS} eclass"
 
+DEPEND="!build? ( sys-apps/sed sys-apps/findutils sys-apps/coreutils )"
+
 # This function simply returns the desired lib directory. With portage
 # 2.0.51, we now have support for installing libraries to lib32/lib64
 # to accomidate the needs of multilib systems. It's no longer a good idea
@@ -30,16 +32,7 @@ get_libdir() {
        if [ ! -z "${CONF_LIBDIR_OVERRIDE}" ] ; then
                # if there is an override, we want to use that... always.
                CONF_LIBDIR="${CONF_LIBDIR_OVERRIDE}"
-       # We don't need to know the verison of portage. We only need to know
-       # if there is support for CONF_LIBDIR in econf and co.
-       # Danny van Dyk <kugelfang@gentoo.org> 2004/17/09 
-       #elif portageq has_version / '<sys-apps/portage-2.0.51_pre20' ; then
-       #       # and if there isnt an override, and we're using a version of
-       #       # portage without CONF_LIBDIR support, force the use of lib. dolib
-       #       # and friends from portage 2.0.50 wont be too happy otherwise.
-       #       CONF_LIBDIR="lib"
-       #fi
-       elif [ -n "$(get_abi_LIBDIR)" ]; then # Using eradicator's LIBDIR_<abi> approach...
+       elif [ -n "$(get_abi_LIBDIR)" ]; then
                CONF_LIBDIR="$(get_abi_LIBDIR)"
        elif [ "${LIBDIR_TEST/CONF_LIBDIR}" == "${LIBDIR_TEST}" ]; then # we don't have CONF_LIBDIR support
                # will be <portage-2.0.51_pre20
@@ -110,24 +103,230 @@ get_abi_var() {
 }
 
 get_abi_CFLAGS() { get_abi_var CFLAGS ${@}; }
-get_abi_CXXFLAGS() { get_abi_var CXXFLAGS ${@}; }
-get_abi_ASFLAGS() { get_abi_var ASFLAGS ${@}; }
+get_abi_CDEFINE() { get_abi_var CDEFINE ${@}; }
 get_abi_LIBDIR() { get_abi_var LIBDIR ${@}; }
 
+# Return a list of the ABIs we want to install for with 
+# the last one in the list being the default.
+get_abi_order() {
+       local order=""
+
+       if [ -z "${MULTILIB_ABIS}" ]; then
+               echo "NOMULTILIB"
+               return 1
+       fi
+
+       if hasq multilib-pkg-force ${RESTRICT} || 
+          { hasq multilib-pkg ${FEATURES} && hasq multilib-pkg ${RESTRICT}; }; then
+               for x in ${MULTILIB_ABIS}; do
+                       if [ "${x}" != "${DEFAULT_ABI}" ]; then
+                               hasq ${x} ${ABI_DENY} || ordera="${ordera} ${x}"
+                       fi
+               done
+               hasq ${DEFAULT_ABI} ${ABI_DENY} || order="${ordera} ${DEFAULT_ABI}"
+
+               if [ -n "${ABI_ALLOW}" ]; then
+                       local ordera=""
+                       for x in ${order}; do
+                               if hasq ${x} ${ABI_ALLOW}; then
+                                       ordera="${ordera} ${x}"
+                               fi
+                       done
+                       order="${ordera}"
+               fi
+       else
+               order="${DEFAULT_ABI}"
+       fi
+
+       if [ -z "${order}" ]; then
+               die "The ABI list is empty.  Are you using a proper multilib profile?  Perhaps your USE flags or MULTILIB_ABIS are too restrictive for this package."
+       fi
+
+       echo ${order}
+       return 0
+}
+
 # get_all_libdir()
-# Returns a list of all the libdirs used by this profile
+# Returns a list of all the libdirs used by this profile.  This includes
+# those that might not be touched by the current ebuild.
 get_all_libdirs() {
-       local libdirs
+       local libdirs="lib"
+       local abi
+       local dir
+
        if [ -n "${MULTILIB_ABIS}" ]; then
                for abi in ${MULTILIB_ABIS}; do
-                       libdirs="${libdirs} $(get_abi_LIBDIR ${abi})"
+                       [ "$(get_abi_LIBDIR ${abi})" != "lib" ] && libdirs="${libdirs} $(get_abi_LIBDIR ${abi})"
                done
-               libdirs="${libdirs:1}"
        elif [ -n "${CONF_LIBDIR}" ]; then
-               libdirs="${CONF_LIBDIR} ${CONF_MULTILIBDIR:=lib32}"
-       else
-               libdirs="lib"
+               for dir in ${CONF_LIBDIR} ${CONF_MULTILIBDIR:=lib32}; do
+                       [ "${dir}" != "lib" ] && libdirs="${libdirs} ${dir}"
+               done
        fi
 
        echo "${libdirs}"
 }
+
+# Return true if ${ABI} is the last ABI on our list (or if we're not
+# using the new multilib configuration.  This can be used to determine
+# if we're in the last (or only) run through src_{unpack,compile,install}
+is_final_abi() {
+       [ -z "${ABI}" ] && return 0
+       local ALL_ABIS=$(get_abi_order)
+       local LAST_ABI=${ALL_ABIS/* /}
+       [ "${LAST_ABI}" = "${ABI}" ]
+}
+
+# echo the number of ABIs we will be installing for
+number_abis() {
+       get_abi_order | wc -w
+}
+
+# prep_ml_includes:
+#
+# Some includes (include/asm, glibc, etc) are ABI dependent.  In this case,
+# We can install them in different locations for each ABI and create a common
+# header which includes the right one based on CDEFINE_${ABI}.  If your
+# package installs ABI-specific headers, just add 'prep_ml_includes' to the
+# end of your src_install().  It takes a list of directories that include
+# files are installed in (default is /usr/include if none are passed).
+#
+# Example:
+# src_install() {
+#    ...
+#    prep_ml_includes /usr/qt/3/include
+# }
+
+prep_ml_includes() {
+       local dirs
+       if [ ${#} -eq 0 ]; then
+               dirs="/usr/include"
+       else
+               dirs="${@}"
+       fi
+
+       if [ $(number_abis) -gt 1 ]; then
+               local dir
+               for dir in ${dirs}; do
+                       mv ${D}/${dir} ${D}/${dir}.${ABI}
+               done
+
+               if is_final_abi; then
+                       for dir in ${dirs}; do
+                               local args="${dir}"
+                               local abi
+                               for abi in $(get_abi_order); do
+                                       args="${args} $(get_abi_CDEFINE ${abi})${dir}.${abi}"
+                               done
+                               create_ml_includes ${args}
+                       done
+               fi
+       fi
+}
+
+# If you need more control than prep_ml_includes can offer (like linux-headers
+# for the asm-* dirs, then use create_ml_includes.  The firs argument is the
+# common dir.  The remaining args are of the form <symbol>:<dir> where
+# <symbol> is what is put in the #ifdef for choosing that dir.
+#
+# Ideas for this code came from debian's sparc-linux headers package.
+#
+# Example:
+# create_ml_includes /usr/include/asm __sparc__:/usr/include/asm-sparc __sparc64__:/usr/include/asm-sparc64
+# create_ml_includes /usr/include/asm __i386__:/usr/include/asm-i386 __x86_64__:/usr/include/asm-x86_64
+create_ml_includes() {
+       local dest="${1}"
+       shift
+       local mlinfo="${@}"
+       local basedirs=$(create_ml_includes-listdirs ${mlinfo})
+
+       create_ml_includes-makedestdirs ${dest} ${basedirs}
+
+       local file
+       for file in $(create_ml_includes-allfiles ${basedirs}); do
+               local name="$(echo $file | tr a-z A-Z | sed 's:[^A-Z]:_:g')"
+               {
+                       echo "/* Common header file autogenerated by create_ml_includes in multilib.eclass */"
+                       echo "#ifndef __CREATE_ML_INCLUDES_STUB_${name}__"
+                       echo "#define __CREATE_ML_INCLUDES_STUB_${name}__"
+                       echo ""
+
+                       local dir
+                       for dir in ${basedirs}; do
+                               if [ -f "${D}/${dir}/${file}" ]; then
+                                       echo "#ifdef $(create_ml_includes-sym_for_dir ${dir} ${mlinfo})"
+                                       echo "#include \"$(create_ml_includes-relative_between ${dest} ${dir})/${file}\""
+                                       echo "#endif /* $(create_ml_includes-sym_for_dir ${dir} ${mlinfo}) */"
+                                       echo ""
+                               fi
+                       done
+
+                       echo "#endif /* __CREATE_ML_INCLUDES_STUB_${name}__ */"
+               } > ${D}/${dest}/${file}
+       done
+}
+
+# Helper function for create_ml_includes
+# TODO: This needs to be updated to spit out relative paths...
+create_ml_includes-relative_between() {
+       local from=${1}
+       local to=${2}
+       
+       echo "${ROOT}${to}"
+}
+
+# Helper function for create_ml_includes
+create_ml_includes-listdirs() {
+       local dirs
+       local data
+       for data in ${@}; do
+               dirs="${dirs} ${data/*:/}"
+       done
+       echo ${dirs:1}
+}
+
+# Helper function for create_ml_includes
+create_ml_includes-makedestdirs() {
+       local dest=${1}
+       shift
+       local basedirs=${@}
+
+       dodir ${dest}
+
+       local basedir
+       for basedir in ${basedirs}; do
+               local dir
+               for dir in $(find ${D}/${basedir} -type d); do
+                       dodir ${dest}/${dir/${D}\/${basedir}/}
+               done
+       done
+}
+
+# Helper function for create_ml_includes
+create_ml_includes-allfiles() {
+       local basedirs=${@}
+
+       local files
+       for basedir in ${basedirs}; do
+               local file
+               for file in $(find ${D}/${basedir} -type f); do
+                       echo ${file/${D}\/${basedir}\//}
+               done
+       done | sort | uniq
+}
+
+# Helper function for create_ml_includes
+create_ml_includes-sym_for_dir() {
+       local dir="${1}"
+       shift
+       local data
+       for data in ${@}; do
+               if [ "${dir}" = "${data/*:/}" ]; then
+                       echo ${data/:*/}
+                       return 0
+               fi
+       done
+       echo "Should be here -- create_ml_includes-sym_for_dir ${1} ${@}"
+       # exit because we'll likely be called from a subshell
+       exit 1
+}