summaryrefslogblamecommitdiff
path: root/eclass/gcc-java.eclass
blob: 47b96be5023ec5121108300fee5eabde6e167772 (plain) (tree)
1
2
3
4
5
6
7
8
9





                                                                  


               
 
                                                                  
 
                                                                      
 


                      












                        

                              












                                                   


               


































                                                                                            


                     















































































                                                                                                                                   


       
 



                                                   

          
                       

 


        































                                                                                                         








                                                                                                                                                                   




























                                                                                                       
            

                                                 

 


      
 












































































                                                                                      

                                                         
                                     

                                            







































                                                                                     

                                          


                                                            

                                                   
                                   





                                           



                                      

            
                                                                               

            




                                                       
 

                           
 

























                                                                                            



                       














                                                                               










                                                                         


                             



                                                                                            

                       
# Copyright 1999-2006 Gentoo Foundation
# Distributed under the terms of the GNU General Public License v2
# Header: $

ECLASS=gcc-java

#
# ECLASS CONFIG
#

inherit flag-o-matic gnuconfig libtool toolchain-funcs versionator

EXPORT_FUNCTIONS pkg_setup src_unpack src_compile src_test src_install

gcc-java_pkg_setup() {
	gcj_pkg_setup
}
gcc-java_src_unpack() {
	gcj_src_unpack
}
gcc-java_src_compile() {
	gcj_src_compile
}
gcc-java_src_test() {
	gcj_src_test
}
gcc-java_src_install() {
	gcj_src_install
}

IUSE="n32 n64 nls nogtk cairo"
RESTRICT="nostrip"

RDEPEND="virtual/libc
	>=sys-libs/zlib-1.1.4
	!nogtk? ( >=x11-libs/gtk+-2.8
		cairo? ( >=x11-libs/cairo-1.0.2 ) )
	>=media-libs/libart_lgpl-2.1
	>=sys-libs/ncurses-5.2-r2
	nls? ( sys-devel/gettext )"

DEPEND="${RDEPEND}
	>=sys-apps/texinfo-4.2-r4
	>=sys-devel/bison-1.875
	>=sys-devel/binutils-2.16.1"
#
# GCJ VARIABLES
#

export CTARGET=${CTARGET:-${CHOST}}
if [[ ${CTARGET} = ${CHOST} ]] ; then
	if [[ ${CATEGORY/cross-} != ${CATEGORY} ]] ; then
		export CTARGET=${CATEGORY/cross-}
	fi
fi

GCC_RELEASE_VER=$(get_version_component_range 1-3)
GCC_BRANCH_VER=$(get_version_component_range 1-2)
GCCMAJOR=$(get_version_component_range 1)
GCCMINOR=$(get_version_component_range 2)
GCCMICRO=$(get_version_component_range 3)
[[ ${BRANCH_UPDATE:-notset} == "notset" ]] && BRANCH_UPDATE=$(get_version_component_range 4)

# According to gcc/c-cppbuiltin.c, GCC_CONFIG_VER MUST match this regex.
# ([^0-9]*-)?[0-9]+[.][0-9]+([.][0-9]+)?([- ].*)?
GCC_CONFIG_VER=${GCC_CONFIG_VER:-"$(replace_version_separator 3 '-')"}

# Pre-release support
if [[ ${PV} != ${PV/_pre/-} ]] ; then
	PRERELEASE=${PV/_pre/-}
fi
# make _alpha and _beta ebuilds automatically use a snapshot
if [[ ${PV} != ${PV/_alpha/} ]] ; then
	SNAPSHOT=${GCC_BRANCH_VER}-${PV##*_alpha}
elif [[ ${PV} != ${PV/_beta/} ]] ; then
	SNAPSHOT=${GCC_BRANCH_VER}-${PV##*_beta}
fi
export GCC_FILESDIR=${GCC_FILESDIR:-${FILESDIR}}

GCC_VAR_TYPE=${GCC_VAR_TYPE:-versioned}
GCC_LIB_COMPAT_ONLY="false"
GCC_TARGET_NO_MULTILIB=${GCC_TARGET_NO_MULTILIB:-false}

#
# SOURCE PATH & FILES
#

# This function sets the source directory depending on whether we're using
# a prerelease, snapshot, or release tarball. To use it, just set S with:
#
#	S="$(gcc_get_s_dir)"

gcc_get_s_dir() {
	if [[ -n ${PRERELEASE} ]] ; then
		GCC_S=${WORKDIR}/gcc-${PRERELEASE}
	elif [[ -n ${SNAPSHOT} ]] ; then
		GCC_S=${WORKDIR}/gcc-${SNAPSHOT}
	else
		GCC_S=${WORKDIR}/gcc-${GCC_RELEASE_VER}
	fi

	echo "${GCC_S}"
}

# This function handles the basics of setting the SRC_URI for a gcc ebuild.
# To use, set SRC_URI with:
#
#	SRC_URI="$(get_gcc_src_uri)"
#
# Other than the variables normally set by portage, this function's behavior
# can be altered by setting the following:
#
#	SNAPSHOT
#			If set, this variable signals that we should be using a snapshot
#			of gcc from ftp://sources.redhat.com/pub/gcc/snapshots/. It is
#			expected to be in the format "YYYY-MM-DD". Note that if the ebuild
#			has a _pre suffix, this variable is ignored and the prerelease
#			tarball is used instead.
#
#	BRANCH_UPDATE
#			If set, this variable signals that we should be using the main
#			release tarball (determined by ebuild version) and applying a
#			CVS branch update patch against it. The location of this branch
#			update patch is assumed to be in ${GENTOO_TOOLCHAIN_BASE_URI}.
#			Just like with SNAPSHOT, this variable is ignored if the ebuild
#			has a _pre suffix.
#
#	PATCH_VER
#	PATCH_GCC_VER
#			This should be set to the version of the gentoo patch tarball.
#			The resulting filename of this tarball will be:
#			gcc-${PATCH_GCC_VER:-${GCC_RELEASE_VER}}-patches-${PATCH_VER}.tar.bz2

gentoo_urls() {
	local devspace="HTTP~lv/GCC/URI HTTP~eradicator/gcc/URI HTTP~vapier/dist/URI
	HTTP~halcy0n/patches/URI"
	devspace=${devspace//HTTP/http:\/\/dev.gentoo.org\/}
	echo mirror://gentoo/$1 ${devspace//URI/$1}
}

get_gcc_src_uri() {
	export PATCH_GCC_VER=${PATCH_GCC_VER:-${GCC_RELEASE_VER}}

	# Set where to download gcc itself depending on whether we're using a
	# prerelease, snapshot, or release tarball.
	if [[ -n ${PRERELEASE} ]] ; then
		GCC_SRC_URI="ftp://gcc.gnu.org/pub/gcc/prerelease-${PRERELEASE}/gcc-${PRERELEASE}.tar.bz2"
	elif [[ -n ${SNAPSHOT} ]] ; then
		GCC_SRC_URI="ftp://sources.redhat.com/pub/gcc/snapshots/${SNAPSHOT}/gcc-${SNAPSHOT}.tar.bz2"
	else
		GCC_SRC_URI="mirror://gnu/gcc/gcc-${PV}/gcc-${GCC_RELEASE_VER}.tar.bz2"
		# we want all branch updates to be against the main release
		[[ -n ${BRANCH_UPDATE} ]] && \
			GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${GCC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2)"
	fi

	# various gentoo patches
	[[ -n ${PATCH_VER} ]] && \
		GCC_SRC_URI="${GCC_SRC_URI} $(gentoo_urls gcc-${PATCH_GCC_VER}-patches-${PATCH_VER}.tar.bz2)"

	echo "${GCC_SRC_URI}"
}

S=$(gcc_get_s_dir)
SRC_URI=$(get_gcc_src_uri)

#
# SETUP
#

gcj_pkg_setup() {
	if [ "${CHOST}" != "${CTARGET}" ]; then
		eerror "cross-compile unsupported!"
		die
	fi

	unset GCC_SPECS
}

#
# UNPACK
#

# gcc_quick_unpack will unpack the gcc tarball and patches in a way that is
# consistant with the behavior of get_gcc_src_uri. The only patch it applies
# itself is the branch update if present.
#
gcc_quick_unpack() {
	pushd ${WORKDIR} > /dev/null
	export PATCH_GCC_VER=${PATCH_GCC_VER:-${GCC_RELEASE_VER}}

	if [[ -n ${GCC_A_FAKEIT} ]] ; then
		unpack ${GCC_A_FAKEIT}.tar.bz2
		mv ${GCC_A_FAKEIT} "${S}"
	elif [[ -n ${PRERELEASE} ]] ; then
		unpack gcc-${PRERELEASE}.tar.bz2
	elif [[ -n ${SNAPSHOT} ]] ; then
		unpack gcc-${SNAPSHOT}.tar.bz2
	else
		unpack gcc-${GCC_RELEASE_VER}.tar.bz2
		# We want branch updates to be against a release tarball
		if [[ -n ${BRANCH_UPDATE} ]] ; then
			pushd ${S:-"$(gcc_get_s_dir)"} > /dev/null
			epatch ${DISTDIR}/gcc-${GCC_RELEASE_VER}-branch-update-${BRANCH_UPDATE}.patch.bz2
			popd > /dev/null
		fi
	fi

	[[ -n ${PATCH_VER} ]] && \
		unpack gcc-${PATCH_GCC_VER}-patches-${PATCH_VER}.tar.bz2

	popd > /dev/null
}

# This function allows us to gentoo-ize gcc's version number and bugzilla
# URL without needing to use patches.
gcc_version_patch() {
	[[ -z $1 ]] && die "no arguments to gcc_version_patch"

	sed -i -e "s~\(const char version_string\[\] = \"\).*\(\".*\)~\1$1\2~" \
	       -e 's~http:\/\/gcc\.gnu\.org\/bugs\.html~http:\/\/bugs\.gentoo\.org\/~' ${S}/gcc/version.c || die "failed to update version.c with Gentoo branding."
}

gcj_src_unpack() {
	local release_version="Gentoo ${PVR}"

	gcc_quick_unpack

	cd ${S:=$(gcc_get_s_dir)}

	version_string="${version_string} (${release_version})"
	einfo "patching gcc version: ${version_string}"
	gcc_version_patch "${version_string}"

	# Misdesign in libstdc++ (Redhat)
	if [[ ${GCCMAJOR} -ge 3 ]] && [[ -e ${S}/libstdc++-v3/config/cpu/i486/atomicity.h ]] ; then
		cp -pPR "${S}"/libstdc++-v3/config/cpu/i{4,3}86/atomicity.h
	fi

	# Fixup libtool to correctly generate .la files with portage
	cd "${S}"
	elibtoolize --portage --shallow --no-uclibc

	gnuconfig_update

	# update configure files
	einfo "Fixing misc issues in configure files"
	for f in $(grep -l 'autoconf version 2.13' $(find "${S}" -name configure)) ; do
		ebegin "  Updating ${f/${S}\/}"
		patch "${f}" "${GCC_FILESDIR}"/gcc-configure-LANG.patch >& "${T}"/configure-patch.log \
			|| die "Please file a bug about this"
		eend $?
	done

	./contrib/gcc_update --touch &> /dev/null
}

#
# TEST
#

gcj_src_test() {
	cd "${WORKDIR}"/build
	make check || ewarn "check failed and that sucks :("
}

#
# COMPILE
#

# This is mostly a stub function to be overwritten in an ebuild
gcc_do_filter_flags() {
	strip-flags

	# In general gcc does not like optimization, and add -O2 where
	# it is safe.  This is especially true for gcc 3.3 + 3.4
	replace-flags -O? -O2

	# ... sure, why not?
	strip-unsupported-flags

	# dont want to funk ourselves
	filter-flags '-mabi*' -m31 -m32 -m64

	case ${GCC_BRANCH_VER} in
	3.4|4.*)
		case $(tc-arch) in
			x86|amd64) filter-flags '-mcpu=*';;
		esac
		;;
	esac

	# Compile problems with these (bug #6641 among others)...
	#filter-flags "-fno-exceptions -fomit-frame-pointer -fforce-addr"

	# CFLAGS logic (verified with 3.4.3):
	# CFLAGS:
	#   This conflicts when creating a crosscompiler, so set to a sane
	#     default in this case:
	#   used in ./configure and elsewhere for the native compiler
	#   used by gcc when creating libiberty.a
	#   used by xgcc when creating libstdc++ (and probably others)!
	#     this behavior should be removed...
	#
	# CXXFLAGS:
	#   used by xgcc when creating libstdc++
	#
	# STAGE1_CFLAGS (not used in creating a crosscompile gcc):
	#   used by ${CHOST}-gcc for building stage1 compiler
	#
	# BOOT_CFLAGS (not used in creating a crosscompile gcc):
	#   used by xgcc for building stage2/3 compiler

	export GCJFLAGS=${GCJFLAGS:-${CFLAGS}}
}

is_uclibc() {
	[[ ${GCCMAJOR} -lt 3 ]] && return 1
	[[ ${CTARGET} == *-uclibc ]]
}

# Other than the variables described for gcc_setup_variables, the following
# will alter tha behavior of gcc_do_configure:
#
#	CTARGET
#	CBUILD
#			Enable building for a target that differs from CHOST
#
#	GCC_TARGET_NO_MULTILIB
#			Disable multilib. Useful when building single library targets.
#
#	GCC_LANG
#			Enable support for ${GCC_LANG} languages. defaults to just "c"
#
# Travis Tilley <lv@gentoo.org> (04 Sep 2004)
#
gcc_do_configure() {
	local confgcc

	# global configure defaults from toolchain.eclass
	confgcc="--with-system-zlib \
			--disable-checking \
			--disable-werror \
			--disable-libunwind-exceptions"

	[[ ${CTARGET} == *-softfloat-* ]] && confgcc="${confgcc} --with-float=soft"

	# Native Language Support
	if use nls ; then
		confgcc="${confgcc} --enable-nls --without-included-gettext"
	else
		confgcc="${confgcc} --disable-nls"
	fi

	case $(tc-arch) in
		# Add --with-abi flags to set default MIPS ABI
		mips)
		local mips_abi=""
		use n64 && mips_abi="--with-abi=64"
		use n32 && mips_abi="--with-abi=n32"
		[[ -n ${mips_abi} ]] && confgcc="${confgcc} ${mips_abi}"
		;;
		# Enable sjlj exceptions for backward compatibility on hppa
		hppa)
			[[ ${GCC_PV:0:1} == "3" ]] && \
			confgcc="${confgcc} --enable-sjlj-exceptions"
		;;
	esac

	confgcc="${confgcc} --enable-shared --enable-threads=posix"

	# __cxa_atexit is "essential for fully standards-compliant handling of
	# destructors", but apparently requires glibc.
	# --enable-sjlj-exceptions : currently the unwind stuff seems to work
	# for statically linked apps but not dynamic
	# so use setjmp/longjmp exceptions by default
	if is_uclibc ; then
		confgcc="${confgcc} --disable-__cxa_atexit --enable-target-optspace"
	else
		confgcc="${confgcc} --enable-__cxa_atexit"
	fi
	[[ ${CTARGET} == *-gnu* ]] && confgcc="${confgcc} --enable-clocale=gnu"
	[[ ${CTARGET} == *-uclibc* ]] && confgcc="${confgcc} --enable-clocale=uclibc"

	# our build specific configuration
	confgcc="--prefix=${GCJ_HOME} \
		--with-gxx-include-dir=${GCJ_HOME}/include \
		--enable-languages=c,c++,java \
		$(use_enable !nogtk java-awt gtk) \
		$(use_enable cairo gtk-cairo) \
		--disable-altivec \
		--disable-gtktest \
		--disable-glibtest \
		--disable-libarttest \
		--disable-multilib \
		--disable-maintainer-mode \
		--disable-libada \
		--disable-libmudflap \
		--disable-libssp \
		--disable-static \
		${confgcc}"

	echo
	einfo "Configuring GCJ with: ${confgcc//--/\n\t--} ${@} ${EXTRA_ECONF}"
	echo

	# and now to do the actual configuration
	addwrite /dev/zero
	"${S}"/configure ${confgcc} $@ ${EXTRA_ECONF} \
		|| die "failed to run configure"
}

gcj_src_compile() {
	gcc_do_filter_flags

	# Build in a separate build tree
	mkdir -p ${WORKDIR}/build
	pushd ${WORKDIR}/build >/dev/null

	gcc_do_configure

	if [[ $(tc-arch) == "x86" || $(tc-arch) == "amd64" || $(tc-arch) == "ppc64" ]]
	then
		GCC_MAKE_TARGET=profiledbootstrap
	else
		GCC_MAKE_TARGET=bootstrap-lean
	fi

	# the gcc docs state that parallel make isnt supported for the
	# profiledbootstrap target, as collisions in profile collecting may occur.
	[[ ${GCC_MAKE_TARGET} == "profiledbootstrap" ]] && export MAKEOPTS="${MAKEOPTS} -j1"

	touch ${S}/gcc/c-gperf.h

	emake \
		BOOT_CFLAGS="$(get_abi_CFLAGS) ${CFLAGS}" \
		LDFLAGS="-Wl,-O1" \
		LIBPATH="${GCJ_HOME}/lib" \
		STAGE1_CFLAGS="-O" \
		${GCC_MAKE_TARGET} \
		|| die "emake failed with ${GCC_MAKE_TARGET}"

	popd >/dev/null
}

#
# INSTALL
#

do_cleanup() {
	# delete binaries
	rm ${D}${GCJ_HOME}/bin/{addr2name.awk,c++,cpp,g++,gcc*,gcov,${CHOST}-*}

	# copy headers - have them in one place for apps
	cp -a ${D}${GCJ_HOME}/lib/gcc/${CHOST}/${PV/_/-}/include/* \
		${D}${GCJ_HOME}/include/
	cp -a ${D}${GCJ_HOME}/include/${CHOST}/bits/* \
		${D}${GCJ_HOME}/include/bits/
}

gcj_src_install() {
	einfo "Installing GCJ ..."
	pushd ${WORKDIR}/build >/dev/null

	make DESTDIR="${D}" install || die "install failed!"

	# Punt some tools which are really only useful while building gcc
	#rm -r "${D}${LIBEXECPATH}"/install-tools
	# This one comes with binutils
	find "${D}" -name libiberty.a -exec rm -f {} \;

	# conflicts with gcc?
	do_cleanup

	# Now do the fun stripping stuff
	env RESTRICT="" STRIP=${CHOST}-strip prepstrip "${D}${BINPATH}" "${D}${LIBEXECPATH}"
	env RESTRICT="" STRIP=${CTARGET}-strip prepstrip "${D}${LIBPATH}"

	popd >/dev/null
}