# Copyright 1999-2006 Gentoo Foundation # Distributed under the terms of the GNU General Public License v2 # $Header: $ # ATTN! # set HOMEPAGE and LICENSE in appropriate ebuild, as we have # gnat developed at two locations now. inherit versionator toolchain-funcs flag-o-matic multilib EXPORT_FUNCTIONS pkg_setup src_unpack src_compile src_install DESCRIPTION="Based on the ${ECLASS} eclass" IUSE="nls multilib" RDEPEND="app-admin/eselect-gnat" #---->> globals and SLOT <<---- # versioning # because of gnatpro/gnatgpl we need to track both gcc and gnat versions # these simply default to $PV GNATMAJOR=$(get_version_component_range 1) GNATMINOR=$(get_version_component_range 2) GNATBRANCH=$(get_version_component_range 1-2) GNATRELEASE=$(get_version_component_range 1-3) # GCCVER and SLOT logic # # ATTN! GCCVER stands for the provided backend gcc, not the one on the system # so tc-* functions are of no use here # # GCCVER can be set in the ebuild, but then care will have to be taken # to set it before inheriting, which is easy to forget # so set it here for what we can.. if [[ ${PN} == "gnatgcc" ]]; then SLOT="${GNATBRANCH}" GCCVER="${PV}" else # Ada Core provided stuff is really conservative and changes backends rarely SLOT=${GNATMAJOR} case "${SLOT}" in "3") GCCVER="2.8.1" ;; "5") [ -z "${GCCVER}" ] && die "please set GCCVER in ebuild! (before inherit)" ;; esac fi # finally extract GCC version strings GCCMAJOR=$(get_version_component_range 1 "${GCCVER}") GCCMINOR=$(get_version_component_range 2 "${GCCVER}") GCCBRANCH=$(get_version_component_range 1-2 "${GCCVER}") GCCRELEASE=$(get_version_component_range 1-3 "${GCCVER}") # possible future crosscompilation support export CTARGET=${CTARGET:-${CHOST}} is_crosscompile() { [[ ${CHOST} != ${CTARGET} ]] } # set our install locations PREFIX=${GNATBUILD_PREFIX:-/usr} # not sure we need this hook, but may be.. LIBPATH=${PREFIX}/lib/${PN}/${CTARGET}/${SLOT} LIBEXECPATH=${PREFIX}/libexec/${PN}/${CTARGET}/${SLOT} INCLUDEPATH=${LIBPATH}/include BINPATH=${PREFIX}/${CTARGET}/${PN}-bin/${SLOT} DATAPATH=${PREFIX}/share/${PN}-data/${CTARGET}/${SLOT} # ebuild globals if [[ ${PN} == "gnatgcc" ]]; then DEPEND="=sys-devel/gcc-${GNATBRANCH}*" S="${WORKDIR}/gcc-${GNATRELEASE}" # use GNATRELEASE rather than PV in case we want some _pre or cvs code else if [[ ${GNATMAJOR} == "3" ]] ; then DEPEND="x86? ( >=app-shells/tcsh-6.0 )" S="${WORKDIR}/gcc-2.8.1" else DEPEND="" # FIXME!!! set appropriate S here, when get gnatgpl/pro source fi fi # some buildtime globals GNATBUILD="${WORKDIR}/build" # necessary for detecting lib locations and creating env.d entry #XGCC="${GNATBUILD}/gcc/xgcc -B${GNATBUILD}/gcc" #----<< globals and SLOT >>---- # set SRC_URI's in ebuilds for now #----<< support checks >>---- # skipping this section - do not care about hardened/multilib for now #---->> specs + env.d logic <<---- # TODO!!! # set MANPATH, etc.. #----<< specs + env.d logic >>---- #---->> some helper functions <<---- # returns true if called from one of the gnats # ada packages need different handling # is_compiler() { # if [[ ${PN} == "gnat" || ${PN} == "gnatpro" || \ # ${PN} == "gnatgpl" || ${PN} == "gnatgcc" ]] # then # return 0 # else # return 1 # fi # } is_multilib() { [[ ${GCCMAJOR} < 3 ]] && return 1 case ${CTARGET} in mips64*|powerpc64*|s390x*|sparc64*|x86_64*) has_multilib_profile || use multilib ;; *) false ;; esac } # adapted from toolchain, # left only basic multilib functionality and cut off mips stuff create_gnat_env_entry() { dodir /etc/env.d/gnat local gnat_envd_base="/etc/env.d/gnat/${CTARGET}-${PN}-${SLOT}" if [[ -z $1 ]] ; then gnat_envd_file="${D}${gnat_envd_base}" gnat_specs_file="" else gnat_envd_file="${D}${gnat_envd_base}-$1" gnat_specs_file="${LIBPATH}/$1.specs" fi echo "PATH=\"${BINPATH}\"" > ${gnat_envd_file} echo "ROOTPATH=\"${BINPATH}\"" >> ${gnat_envd_file} LDPATH="${LIBPATH}" for path in 32 64 o32 ; do [[ -d ${LIBPATH}/${path} ]] && LDPATH="${LDPATH}:${LIBPATH}/${path}" done echo "LDPATH=\"${LDPATH}\"" >> ${gnat_envd_file} echo "MANPATH=\"${DATAPATH}/man\"" >> ${gnat_envd_file} echo "INFOPATH=\"${DATAPATH}/info\"" >> ${gnat_envd_file} is_crosscompile && echo "CTARGET=${CTARGET}" >> ${gnat_envd_file} # Set which specs file to use [[ -n ${gnat_specs_file} ]] && echo "GCC_SPECS=\"${gnat_specs_file}\"" >> ${gnat_envd_file} } # eselect stuff taked traight from toolchain.eclass with minor modifications add_profile_eselect_conf() { local compiler_config_file=$1 local abi=$2 local specs=$3 local gcc_specs_file local var if [[ -z ${specs} ]] ; then gcc_specs_file="" specs="vanilla" else gcc_specs_file="${LIBPATH}/${specs}.specs" fi echo >> ${compiler_config_file} if ! is_multilib ; then echo "[${specs}]" >> ${compiler_config_file} echo " ctarget=${CTARGET}" >> ${compiler_config_file} else echo "[${abi}-${specs}]" >> ${compiler_config_file} var="CTARGET_${abi}" if [[ -n ${!var} ]] ; then echo " ctarget=${!var}" >> ${compiler_config_file} else var="CHOST_${abi}" if [[ -n ${!var} ]] ; then echo " ctarget=${!var}" >> ${compiler_config_file} else echo " ctarget=${CTARGET}" >> ${compiler_config_file} fi fi fi echo " ldpath=${LIBPATH}" >> ${compiler_config_file} if [[ -n ${gcc_specs_file} ]] ; then echo " specs=${gcc_specs_file}" >> ${compiler_config_file} fi var="CFLAGS_${abi}" if [[ -n ${!var} ]] ; then echo " cflags=${!var}" >> ${compiler_config_file} fi } create_eselect_conf() { local config_dir="/etc/eselect/gnat" local gnat_config_file="${D}/${config_dir}/${CTARGET}-${PN}-${SLOT}.conf" # local abi dodir ${config_dir} echo "[global]" > ${gnat_config_file} echo " version=${CTARGET}-${SLOT}" >> ${gnat_config_file} echo " binpath=${BINPATH}" >> ${gnat_config_file} echo " manpath=${DATAPATH}/man" >> ${gnat_config_file} echo " infopath=${DATAPATH}/info" >> ${gnat_config_file} # echo " alias_cc=gcc" >> ${compiler_config_file} # echo " stdcxx_incdir=${STDCXX_INCDIR##*/}" >> ${compiler_config_file} echo " bin_prefix=${CTARGET}" >> ${gnat_config_file} for abi in $(get_all_abis) ; do add_profile_eselect_conf "${gnat_config_file}" "${abi}" done } # active compiler selection, called from pkg_postinst should_we_gcc_config() { # we only want to switch compilers if installing to / [[ ${ROOT} == "/" ]] || return 1 # if the current config is invalid, we definitely want a new one local curr_config=$(env -i eselect gnat show ${CTARGET} 2>&1) || return 0 # if the previously selected config has the same SLOT, then it will probably # be uninstalled, make sure we run eselect. # FIXME the awk below will definitely need changing local curr_config_ver=$(env -i eselect compiler show ${CTARGET} | cut -f1 -d/ | awk -F - '{ print $5 }') local curr_branch_ver=$(get_version_component_range 1-2 ${curr_config_ver}) # If we're using multislot, just run gcc-config if we're installing # to the same profile as the current one. use multislot && return $([[ ${curr_config_ver} == ${GCC_CONFIG_VER} ]]) if [[ ${curr_branch_ver} == ${GCC_BRANCH_VER} ]] ; then return 0 else # if we're installing a genuinely different compiler version, # we should probably tell the user -how- to switch to the new # gcc version, since we're not going to do it for him/her. # We don't want to switch from say gcc-3.3 to gcc-3.4 right in # the middle of an emerge operation (like an 'emerge -e world' # which could install multiple gcc versions). einfo "The current gcc config appears valid, so it will not be" einfo "automatically switched for you. If you would like to" einfo "switch to the newly installed gcc version, do the" einfo "following:" echo if has_version 'app-admin/eselect-compiler' ; then einfo "eselect compiler set " else einfo "gcc-config ${CTARGET}-${GCC_CONFIG_VER}" fi einfo "source /etc/profile" echo ebeep return 1 fi } do_gnat_config() { if ! should_we_config ; then # Just make sure all our LDPATH's are updated eselect gnat update return 0 fi local current_gnatc_config=$(env -i eselect gnat show ${CTARGET}) local current_specs=$(echo ${current_gnat_config} | cut -f2 -d/) if eselect gnat set ${CTARGET}-${PN}-${SLOT}/${current_specs} &> /dev/null; then einfo "The following gnat profile has been activated based on your previous profile:" einfo "${CTARGET}-${PN}-${SLOT}/${current_specs}" else local prefix=${current_specs%-*} [[ -n ${prefix} ]] && prefix="${prefix}-" local spec="vanilla" if eselect gnat set ${CTARGET}-${PN}-${SLOT}/${prefix}${spec} &> /dev/null ; then ewarn "We were not able to select the currently in use profile with" ewarn "your newly emerged gnat. Instead, we have enabled the following:" ewarn "${CTARGET}-${PN}-${SLOT}/${prefix}${spec}" ewarn "If this is incorrect, please use 'eselect gnat set' to" ewarn "select another profile." else if [[ -n ${DEFAULT_ABI} ]] ; then prefix="${DEFAULT_ABI}-" fi if eselect compiler set ${CTARGET}-${PN}-${SLOT}/${prefix}${spec} &> /dev/null ; then ewarn "We were not able to select the currently in use profile with" ewarn "your newly emerged gcc. Instead, we have enabled the following:" ewarn "${CTARGET}-${PN}-${SLOT}/${prefix}${spec}" ewarn "If this is incorrect, please use 'eselect compiler set' to" ewarn "select another profile." else eerror "We were not able to automatically set the current compiler" eerror "to your newly emerged gcc. Please use 'eselect compiler set'" eerror "to select your compiler." fi fi fi } #---->> pkg_* <<---- gnatbuild_pkg_setup() { debug-print-function ${FUNCNAME} $@ # common environment stuff that does not need to scan sources case $(tc-arch) in ppc) GNATBOOT="${WORKDIR}/gnat-3.15p-powerpc-unknown-linux-gnu" GNATBOOTINST="${GNATBOOT}" GCC_EXEC_BASE="${GNATBOOT}/lib/gcc-lib" ;; amd64 | x86) GNATBOOT="${WORKDIR}/usr" GCC_EXEC_BASE="${GNATBOOT}/lib/gcc" ;; esac # Setup variables which would normally be in the profile if is_crosscompile ; then multilib_env ${CTARGET} if ! use multilib ; then MULTILIB_ABIS=${DEFAULT_ABI} fi fi # we dont want to use the installed compiler's specs to build gnat! unset GCC_SPECS } gcc-compiler_pkg_postinst() { export LD_LIBRARY_PATH="${LIBPATH}:${LD_LIBRARY_PATH}" do_gnat_config } #---->> pkg_* <<---- #---->> src_* <<---- # common unpack stuff gnatbuild_src_unpack() { debug-print-function ${FUNCNAME} $@ unpack ${A} # Prepare the gcc source directory cd "${S}" touch gcc/cstamp-h.in touch gcc/ada/[es]info.h touch gcc/ada/nmake.ad[bs] mkdir -p "${GNATBUILD}" # set the compiler name to gnatgcc for i in `find ${S}/gcc/ada -name '*.ad[sb]'`; do \ sed -i -e "s/\"gcc\"/\"gnatgcc\"/g" ${i}; \ done } # it would be nice to split configure and make steps # but both need to operate inside specially tuned evironment # so just do sections for now (as in eclass section of handbook) # sections are: configure, make-tools, bootstrap, # gnatlib_and_tools, gnatlib-shared gnatbuild_src_compile() { debug-print-function ${FUNCNAME} $@ [ -z "$1" ] && ( gnatbuild_src_compile all; exit ) if [ "all" == "$1" ] then # specialcasing "all" to avoid scanning sources unnecessarily gnatbuild_src_compile configure make-tools \ bootstrap gnatlib_and_tools gnatlib-shared else # Set some paths to our bootstrap compiler. GCC_EXEC_PREFIX=$(echo ${GCC_EXEC_BASE}/*/*) PATH="${GNATBOOT}/bin:${PATH}" case $(tc-arch) in ppc) export LDFLAGS="-L${GCC_EXEC_PREFIX} -L${GNATBOOTINST}" ;; amd64 | x86) export LDFLAGS="-L${GCC_EXEC_PREFIX}" ;; esac export CC="${GNATBOOT}/bin/gcc" export LD_LIBRARY_PATH="${GNATBOOT}/lib" # this should catch the one that works local ADA_OBJECTS_PATH local ADA_INCLUDE_PATH for x in $(find "${GCC_EXEC_PREFIX}" -name adalib); do ADA_OBJECTS_PATH="${x}:${ADA_OBJECTS_PATH}" done for x in $(find "${GCC_EXEC_PREFIX}" -name adainclude); do ADA_INCLUDE_PATH="${x}:${ADA_INCLUDE_PATH}" done #einfo "CC=${CC}, GCC_EXEC_PREFIX=${GCC_EXEC_PREFIX}" while [ "$1" ]; do case $1 in configure) debug-print-section configure # Configure gcc local confgcc # some cross-compile logic from toolchain confgcc="${confgcc} --host=${CHOST}" if is_crosscompile || tc-is-cross-compiler ; then confgcc="${confgcc} --target=${CTARGET}" fi [[ -n ${CBUILD} ]] && confgcc="${confgcc} --build=${CBUILD}" # Native Language Support if use nls ; then confgcc="${confgcc} --enable-nls --without-included-gettext" else confgcc="${confgcc} --disable-nls" fi # reasonably sane globals (from toolchain) confgcc="${confgcc} \ --with-system-zlib \ --disable-checking \ --disable-werror \ --disable-libunwind-exceptions" cd "${GNATBUILD}" CFLAGS="${CFLAGS}" CXXFLAGS="${CXXFLAGS}" "${S}"/configure \ --prefix=${PREFIX} \ --bindir=${BINPATH} \ --includedir=${INCLUDEPATH} \ --libdir="${LIBPATH}" \ --libexecdir="${LIBEXECPATH}" \ --datadir=${DATAPATH} \ --mandir=${DATAPATH}/man \ --infodir=${DATAPATH}/info \ --program-prefix=gnat \ --enable-languages="c,ada" \ --enable-libada \ --with-gcc \ --enable-threads=posix \ --enable-shared \ --with-system-zlib \ --disable-nls \ ${confgcc} || die "configure failed" ;; make-tools) debug-print-section make-tools # Compile helper tools cd "${GNATBOOT}" cp ${S}/gcc/ada/xtreeprs.adb . cp ${S}/gcc/ada/xsinfo.adb . cp ${S}/gcc/ada/xeinfo.adb . cp ${S}/gcc/ada/xnmake.adb . gnatmake xtreeprs && \ gnatmake xsinfo && \ gnatmake xeinfo && \ gnatmake xnmake || die "building helper tools" ;; bootstrap) debug-print-section bootstrap # and, finally, the build itself cd "${GNATBUILD}" emake bootstrap || die "bootstrap failed" ;; gnatlib_and_tools) debug-print-section gnatlib_and_tools einfo "building gnatlib_and_tools" cd "${GNATBUILD}" emake -j1 -C gcc gnatlib_and_tools || die "gnatlib_and_tools failed" ;; gnatlib-shared) debug-print-section gnatlib-shared einfo "building shared lib" cd "${GNATBUILD}" rm -f gcc/ada/rts/*.{o,ali} || die #otherwise make tries to reuse already compiled (without -fPIC) objs.. emake -j1 -C gcc gnatlib-shared LIBRARY_VERSION=3.4 || die "gnatlib-shared failed" ;; esac shift done # while fi # "all" == "$1" } gnatbuild_src_install() { debug-print-function ${FUNCNAME} $@ [ -z "$1" ] && ( gnatbuild_src_install all; exit ) while [ "$1" ]; do case $1 in install) # runs provided make install debug-print-section install # Do not allow symlinks in /usr/lib/gcc/${CHOST}/${MY_PV}/include as # this can break the build. for x in "${GNATBUILD}"/gcc/include/* ; do if [ -L ${x} ] ; then rm -f ${x} fi done # Remove generated headers, as they can cause things to break # (ncurses, openssl, etc). (from toolchain.eclass) for x in $(find "${WORKDIR}"/build/gcc/include/ -name '*.h') ; do grep -q 'It has been auto-edited by fixincludes from' "${x}" \ && rm -f "${x}" done # Install gnatgcc, tools and native threads library cd "${GNATBUILD}" make DESTDIR=${D} install || die # remove duplicate identical binary cd "${D}${BINPATH}" if [[ -f ${CTARGET}-gcc-${GCCRELEASE} ]] ; then rm -f ${CTARGET}-gcc-${GCCRELEASE} ln -sf ${CTARGET}-gnatgcc ${CTARGET}-gcc-${GCCRELEASE} fi # TODO should we provide versioned symlinks for all the gnat* binaries into /usr/bin? ;; cleanup) debug-print-section cleanup cd "${D}${LIBPATH}/.." rm -rf lib/ lib64/ cd "${D}${LIBPATH}" rm -r libiberty.a # this one comes with binutils rmdir include/ # should be empty rm -rf "${D}${LIBEXECPATH}/gcc/${CTARGET}/${GCCRELEASE}"/install-tools/ # remove duplicate docs cd "${D}${DATAPATH}" has noinfo ${FEATURES} \ && rm -rf info \ || rm -f info/{gcc,cpp}* has noman ${FEATURES} \ && rm -rf man \ || rm -rf man/man7/ ;; move_libs) debug-print-section relocate # gcc insists on installing libs in its own place mv "${D}${LIBPATH}/gcc/${CTARGET}/${GCCRELEASE}"/* "${D}${LIBPATH}" rm -rf "${D}${LIBPATH}/gcc" mv "${D}${LIBEXECPATH}/gcc/${CTARGET}/${GCCRELEASE}"/* "${D}${LIBEXECPATH}" rm -rf "${D}${LIBEXECPATH}/gcc" # set the rts libs cd "${D}${LIBPATH}" mkdir rts-native mv adalib adainclude rts-native ln -s rts-native/adalib adalib ln -s rts-native/adainclude adainclude # use gid of 0 because some stupid ports don't have # the group 'root' set to gid 0 (toolchain.eclass) chown -R root:0 "${D}${LIBPATH}" # some provided ada specific Makefiles, may be usefull mv "${D}${PREFIX}/share/gnat" "${D}${DATAPATH}" ;; prep_env) dodir /etc/env.d/gnat create_gnat_env_entry create_eselect_conf ;; all) gnatbuild_src_install install cleanup move_libs prep_env ;; esac shift done # while }