summaryrefslogtreecommitdiff
path: root/eclass/gcc-java.eclass
blob: 47b96be5023ec5121108300fee5eabde6e167772 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
# 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
}