Tue, 29 Mar 2011 20:04:34 +0200
Rework package yet again, correcting and introducing new buildconf logic:
Conditionally disable bootstrap stage comparison correctly, correct
english grammar, better find system as(1) and ld(1), indotruce detailed
optimization option messages, more completely guess cpu types, allow
profiled bootstrapping without a preinstalled GCC because many other
compilers have long since implemented 64-bit arithmetic, instruct make
to build sequentially (not in sparallel) when building a profiled
bootstrap as GCC online documents recommend, and generally improve
comment blocks.
The single most important correction in this changeset relates to the
GCC changed optimization policy since at least GCC 4.5, in which -march
is always passed and not always correctly guessed. In the case of this
package, allowing GCC to guess the architecture leads to wild build
errors at various subcomponents (zlib, libgcc, libiberty...) and
bootstrap stages. It seems quite platform specific, and the safest
approach to correcting this seems to be explicitly always specifying the
-march argument when bootstrapping GCC. Because the best choice 'native'
is not available when bootstrapping using a foreign (non GCC) compiler,
a guess is made according to rpmmacros l_platform in that case.
It is questionable as to whether these recent optimization changes
on the part of GCC or this package are compatible with each other,
or if either are complete or correct at all. At least applying these
corrections allows this package to build again in most cases test.
1 ##
2 ## gcc.spec -- OpenPKG RPM Package Specification
3 ## Copyright (c) 2000-2010 OpenPKG Foundation e.V. <http://openpkg.net/>
4 ##
5 ## Permission to use, copy, modify, and distribute this software for
6 ## any purpose with or without fee is hereby granted, provided that
7 ## the above copyright notice and this permission notice appear in all
8 ## copies.
9 ##
10 ## THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
11 ## WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
12 ## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
13 ## IN NO EVENT SHALL THE AUTHORS AND COPYRIGHT HOLDERS AND THEIR
14 ## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
15 ## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
16 ## LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
17 ## USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
18 ## ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
19 ## OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
20 ## OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
21 ## SUCH DAMAGE.
22 ##
24 # package version
25 %define V_full 4.6.0
26 %define V_comp %nil
28 # package information
29 Name: gcc
30 Summary: GNU Compiler Collection
31 URL: http://gcc.gnu.org/
32 Vendor: Free Software Foundation
33 Packager: OpenPKG Foundation e.V.
34 Distribution: OpenPKG Community
35 Class: CORE
36 Group: Compiler
37 License: GPL
38 Version: %{V_full}
39 Release: 20110320
41 # package options
42 %option with_binutils yes
43 %option with_cxx yes
44 %option with_objc no
45 %option with_java no
46 %option with_fortran no
47 %option with_optimize yes
48 %option with_profile no
49 %option with_threads yes
50 %option with_multilib no
52 # list of sources
53 Source0: ftp://gcc.gnu.org/pub/gcc/releases/gcc-%{V_full}/gcc-core-%{V_full}.tar.bz2
54 Source1: ftp://gcc.gnu.org/pub/gcc/releases/gcc-%{V_full}/gcc-g++-%{V_full}.tar.bz2
55 Source2: ftp://gcc.gnu.org/pub/gcc/releases/gcc-%{V_full}/gcc-objc-%{V_full}.tar.bz2
56 Source3: ftp://gcc.gnu.org/pub/gcc/releases/gcc-%{V_full}/gcc-java-%{V_full}.tar.bz2
57 Source4: ftp://gcc.gnu.org/pub/gcc/releases/gcc-%{V_full}/gcc-fortran-%{V_full}.tar.bz2
58 Patch0: gcc.patch
60 # build information
61 Prefix: %{l_prefix}
62 BuildRoot: %{l_buildroot}
63 BuildPreReq: OpenPKG, openpkg >= 20060823, make
64 PreReq: OpenPKG, openpkg >= 20060823
65 BuildPreReq: mpc, mpfr, gmp
66 PreReq: mpc, mpfr, gmp
67 %if "%{with_binutils}" == "yes"
68 BuildPreReq: binutils >= 2.14
69 PreReq: binutils >= 2.14
70 %endif
71 %if "%{with_cxx}" == "yes"
72 BuildPreReq: libiconv
73 PreReq: libiconv
74 %endif
75 %if "%{with_java}" == "yes"
76 BuildPreReq: zlib
77 PreReq: zlib
78 %endif
79 AutoReq: no
80 AutoReqProv: no
82 %description
83 The GNU Compiler Collection (GCC) provides standard conforming and
84 highly portable compilers for the ISO C, ISO C++, Objective-C,
85 Fortran and Java languages.
87 %track
88 prog gcc = {
89 version = %{V_full}
90 url = ftp://gcc.gnu.org/pub/gcc/releases/
91 regex = gcc-(4\.\d+\.\d+)
92 url = ftp://gcc.gnu.org/pub/gcc/releases/gcc-__NEWVER__/
93 regex = gcc-core-(\d+\.\d+\.\d+)\.tar\.bz2
94 }
96 %prep
97 %setup -q
98 %if "%{with_cxx}" == "yes"
99 %setup -q -T -D -b 1
100 %endif
101 %if "%{with_objc}" == "yes"
102 %setup -q -T -D -b 2
103 %endif
104 %if "%{with_java}" == "yes"
105 %setup -q -T -D -b 3
106 %endif
107 %if "%{with_fortran}" == "yes"
108 %setup -q -T -D -b 4
109 %endif
110 %patch -p0
111 %{l_shtool} subst \
112 -e 's;\(instname="\$dir/\$name"\)i;\1;' \
113 ltmain.sh
114 %{l_shtool} subst -v -s \
115 -e 's;\(gmplibs="-lmpc\) \(-lmpfr -lgmp\);\1 -lm \2;' \
116 configure
117 %{l_shtool} subst -v -s \
118 -e 's;PREFIX_INCLUDE_DIR;PREFIX_INCLUDE_DIR_DISABLED;g' \
119 gcc/configure
120 %{l_shtool} subst \
121 -e 's;[ \t]*-W[a-zA-Z0-9_\-][a-zA-Z0-9_\-]*,*;;g' \
122 lto-plugin/Makefile.in
123 %{l_shtool} subst \
124 -e 's;-rpath *[^ \t][^ \t]*;;g' \
125 -e 's;--tag=disable-static;--tag=disable-shared;g' \
126 -e 's;\.\./libiberty/libiberty\.a;-L../libiberty -liberty;g' \
127 -e 's;\.\./libiberty/pic/libiberty\.a;-L../libiberty/pic -liberty;g' \
128 lto-plugin/Makefile.in
129 if [ ".%{V_comp}" != . ]; then
130 %{l_shtool} subst -v -s \
131 -e 's;(libdir)/gcc/;(libdir)/gcc%{V_comp}/;' \
132 `find . -name Makefile.in -type f -print`
133 fi
134 %{l_shtool} subst \
135 -e 's;^\(do-compare\) *\(=.*\);#\1-shouldnt-be-defined-here \2;' \
136 config/*.mk
137 case "%{l_platform -t}" in
138 amd64-linux* )
139 %{l_shtool} subst \
140 -e 's/GLIBCXX_IS_NATIVE=false/GLIBCXX_IS_NATIVE=true/g' \
141 -e 's/test x.gcc_no_link = xyes/false/g' \
142 libstdc++-v3/configure
143 ;;
144 esac
145 %{l_shtool} subst \
146 -e 's;<iconv\.h>;"%{l_prefix}/include/iconv.h";' \
147 libstdc++-v3/include/ext/codecvt_specializations.h
149 %build
150 # create build subdirectory
151 %{l_shtool} mkdir -p obj
152 cd obj
154 # locate ld(1) and as(1) accordingly
155 %if "%{with_binutils}" == "yes"
156 # allow OpenPKG binutils
157 LD=%{l_tool_locate ld ld}
158 AS=%{l_tool_locate as as}
159 %else
160 # ignore OpenPKG binutils
161 LD=`PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/ccs/bin:/opt/bin:/opt/sbin:/usr/local/bin:/usr/local/sbin which ld`
162 AS=`PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/ccs/bin:/opt/bin:/opt/sbin:/usr/local/bin:/usr/local/sbin which as`
163 %endif
164 l_with_gnu_ld_as=""
165 echo $LD | grep '^/' >/dev/null && l_with_gnu_ld_as="--with-ld=$LD"
166 echo $AS | grep '^/' >/dev/null && l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-as=$AS"
167 $LD --version </dev/null 2>/dev/null | grep "^GNU ld " >/dev/null && l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-gnu-ld" || l_with_gnu_ld_as="${l_with_gnu_ld_as} --without-gnu-ld"
168 $AS --version </dev/null 2>/dev/null | grep "^GNU assembler " >/dev/null && l_with_gnu_ld_as="${l_with_gnu_ld_as} --with-gnu-as" || l_with_gnu_ld_as="${l_with_gnu_ld_as} --without-gnu-as"
170 # determine threads use
171 %if "%{with_threads}" == "yes"
172 l_enable_threads="posix"
173 %else
174 l_enable_threads="single"
175 %endif
177 # determine language use
178 l_enable_languages="c"
179 %if "%{with_cxx}" == "yes"
180 l_enable_languages="${l_enable_languages},c++"
181 %endif
182 %if "%{with_objc}" == "yes"
183 l_enable_languages="${l_enable_languages},objc"
184 %endif
185 %if "%{with_java}" == "yes"
186 l_enable_languages="${l_enable_languages},java"
187 %endif
188 %if "%{with_fortran}" == "yes"
189 l_enable_languages="${l_enable_languages},f95"
190 %endif
192 # disable GNU iconv use
193 ( echo "am_cv_func_iconv=no"
194 echo "am_cv_lib_iconv=no"
195 ) >config.cache
196 # platforms failing 'compare' make target (see prep as well)
197 case "%{l_platform -t}" in
198 *i?86-sunos* ) echo "gcc_cv_prog_cmp_skip=true" >>config.cache ;;
199 *amd64-linux* ) echo "gcc_cv_prog_cmp_skip=true" >>config.cache ;;
200 esac
202 # configure the package
203 LD="$LD" \
204 AS="$AS" \
205 CC="%{l_cc}" \
206 CFLAGS="%{l_cflags}" \
207 %if "%{with_java}" == "yes" || "%{with_fortran}" == "yes" || "%{with_cxx}" == "yes"
208 CPPFLAGS="%{l_cppflags}" \
209 LDFLAGS="%{l_ldflags}" \
210 %endif
211 CONFIG_SHELL="%{l_bash}" \
212 GREP="%{l_bash}" \
213 ../configure \
214 --with-bugurl="http://openpkg.org/" \
215 --with-pkgversion="%{l_openpkg_release -F "OpenPKG-%%t"}" \
216 --cache-file=./config.cache \
217 --srcdir=`pwd`/.. \
218 --prefix=%{l_prefix} \
219 --exec-prefix=%{l_prefix} \
220 --mandir=%{l_prefix}/man \
221 --infodir=%{l_prefix}/info \
222 --includedir=%{l_prefix}/include/gcc%{V_comp} \
223 --libexecdir=%{l_prefix}/libexec/gcc%{V_comp} \
224 --with-gxx-include-dir=%{l_prefix}/include/g++%{V_comp} \
225 --with-local-prefix=%{l_prefix}/lib/gcc%{V_comp} \
226 --enable-languages="${l_enable_languages}" \
227 --enable-threads="${l_enable_threads}" \
228 --disable-maintainer-mode \
229 --disable-shared \
230 --disable-nls \
231 %if "%{with_java}" == "yes"
232 --with-system-zlib \
233 %endif
234 %if "%{with_multilib}" == "yes"
235 --enable-multilib \
236 %else
237 --disable-multilib \
238 %endif
239 %if "%{with_cxx}" == "yes"
240 --with-libiconv-prefix=%{l_prefix} \
241 %endif
242 --with-gmp=%{l_prefix} \
243 --with-mpfr=%{l_prefix} \
244 --with-mpc=%{l_prefix} \
245 ${l_with_gnu_ld_as}
247 # determine build flags
248 l_ccisgcc=no
249 if [ ".`(%{l_cc} -v; %{l_cc} --version) </dev/null 2>&1 | grep -i 'gcc'`" != . ]; then
250 l_ccisgcc=yes
251 fi
252 l_cflags=""
253 l_cxxflags=""
254 l_boot_cflags=""
255 l_libcflags="-g"
256 l_libcxxflags="-g"
257 # at least GNU as from GNU binutils supports -pipe always
258 "$AS" --version </dev/null 2>/dev/null | grep "^GNU assembler" >/dev/null && {
259 l_boot_cflags="$l_boot_cflags -pipe"
260 l_libcxxflags="$l_libcxxflags -pipe"
261 }
262 %if "%{with_optimize}" == "yes"
263 # GCC authors are not keeping up with optimized portability expectations
264 ( echo "As GCC advances its optimization logic becomes increasingly complex (and"
265 echo "buggy?) Since at least GCC 4.5, problems have been reported using arguments"
266 echo "-O, -mtune, or -march implicitly or explicitly during different bootstrap"
267 echo "stages as well as stage comparison and even the final installation."
268 echo ""
269 echo "Pay attention when building on one computer and installing on another as"
270 echo "problems may be platform specific. If in doubt, disable optimization."
271 ) | %{l_rpmtool} msg -b -t warn
272 if [ ".$l_ccisgcc" = .yes ]; then
273 l_archia32=native; l_archia64=native; l_archamd64=native
274 else
275 # CPU native detection only works with GCC (see driver-i386.c)
276 ( echo "Platform specific optimization is enabled, but detection of appropriate"
277 echo "native architecture is only possible when bootstrapping GCC using a pre-"
278 echo "installed GCC. The current build is using a different compiler, so to"
279 echo "provide any optimization at all a wild guess is made and a CPU type"
280 echo "hardcoded instead of using accurate native detection."
281 echo ""
282 echo "To achieve accurate optimization of GCC please install GCC first. Then"
283 echo "build this package a second time which will use GCC to bootstrap itself."
284 ) | %{l_rpmtool} msg -b -t notice
286 # guess lowest common denominator CPU types
287 # http://en.wikipedia.org/wiki/(X86|X64-64)
288 # http://gcc.gnu.org/onlinedocs/gcc/i386-and-x86_002d64-Options.html
289 l_archia32=pentium3; l_archia64=nocona; l_archamd64=k8
290 fi
291 # this optimization logic is unportable and could cause problems
292 # if installing the resulting binary package on a different host!
293 case "%{l_platform -t}" in
294 *sun4[uv]-* ) l_boot_cflags="$l_boot_cflags -mtune=v9" ;;
295 *sun-* ) l_boot_cflags="$l_boot_cflags -mtune=v8" ;;
296 *i?86-* ) l_boot_cflags="$l_boot_cflags -march=$l_archia32" ;;
297 *ia64-* ) l_boot_cflags="$l_boot_cflags -march=$l_archia64" ;;
298 *amd64-* ) l_boot_cflags="$l_boot_cflags -march=$l_archamd64" ;;
299 * ) l_boot_cflags="$l_boot_cflags -mtune=generic" ;;
300 esac
301 l_cflags="$l_cflags -O"
302 l_boot_cflags="$l_boot_cflags -O3 -fomit-frame-pointer"
303 l_libcxxflags="$l_libcxxflags -O3 -fno-implicit-templates"
304 %else
305 # don't optimize at all to avoid problems
306 l_boot_cflags="$l_boot_cflags -O0"
307 l_libcxxflags="$l_libcxxflags -O0"
308 %endif
309 %if "%{with_profile}" == "yes"
310 maketarget="profiledbootstrap"
311 loc_makeflags="%{l_mflags}"
312 if [ ".$l_ccisgcc" != .yes ]; then
313 ( echo "A preinstalled GCC is recommended when bootstrapping a profiled GCC. If the"
314 echo "compiler used to bootstrap GCC doesn't support 64-bit arithmetic, then"
315 echo "either runtime or buildtime errors could occur. Regardless of this,"
316 echo "parallel make logic is disabled according to profiling requirements."
317 echo ""
318 echo "If in doubt, stop now and start the build again with profiling disabled."
319 ) | %{l_rpmtool} msg -b -t warn
320 fi
321 %else
322 maketarget="bootstrap"
323 loc_makeflags="%{l_mflags -O}"
324 %endif
325 case "%{l_platform -t}" in
326 *64-* ) l_cflags="$l_cflags -fPIC"; l_cxxflags="$l_cxxflags -fPIC" ;;
327 esac
328 %if "%{with_java}" == "yes" || "%{with_fortran}" == "yes" || "%{with_cxx}" == "yes"
329 l_cflags="$l_cflags %{l_cppflags}"
330 l_cxxflags="$l_cxxflags %{l_cppflags}"
331 l_libcflags="$l_libcflags %{l_cppflags}"
332 l_libcxxflags="$l_libcxxflags %{l_cppflags}"
333 %endif
335 # build the package
336 MAKE="%{l_make} ${loc_makeflags}" \
337 %{l_make} ${loc_makeflags} \
338 GREP="grep" \
339 MAKE="%{l_make} ${loc_makeflags}" \
340 BOOT_CFLAGS="${l_boot_cflags}" \
341 CFLAGS="${l_cflags}" \
342 CXXFLAGS="${l_cxxflags}" \
343 LIBCFLAGS="${l_libcflags}" \
344 LIBCXXFLAGS="${l_libcxxflags}" \
345 $maketarget
347 %install
348 rm -rf $RPM_BUILD_ROOT
350 # fetch GNU platform triple
351 triple=`./config.guess`
353 # perform the standard installation procedure
354 ( cd obj
355 %{l_make} %{l_mflags} install DESTDIR=$RPM_BUILD_ROOT
356 ) || exit $?
358 # cleanup installation tree
359 mv $RPM_BUILD_ROOT%{l_prefix}/lib/{lib*.a,*.spec} \
360 $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/ \
361 >/dev/null 2>&1 || true
362 mv $RPM_BUILD_ROOT%{l_prefix}/lib64/{lib*.a,*.spec} \
363 $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/ \
364 >/dev/null 2>&1 || true
365 dirs=""
366 for multilib in `$RPM_BUILD_ROOT%{l_prefix}/bin/gcc --print-multi-lib`; do
367 subdir=`echo "$multilib" | sed -e 's/;.*$//'`
368 [ ".$subdir" = .. ] && continue
369 mv $RPM_BUILD_ROOT%{l_prefix}/lib/$subdir/lib*.a \
370 $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/$subdir/ \
371 >/dev/null 2>&1 || true
372 mv $RPM_BUILD_ROOT%{l_prefix}/lib64/$subdir/lib*.a \
373 $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/$subdir/ \
374 >/dev/null 2>&1 || true
375 dirs="$dirs $subdir"
376 done
377 for subdir in $dirs; do
378 rm -rf $RPM_BUILD_ROOT%{l_prefix}/lib/$subdir >/dev/null 2>&1 || true
379 done
380 mv $RPM_BUILD_ROOT%{l_prefix}/${triple}/include/* \
381 $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/include/ \
382 >/dev/null 2>&1 || true
384 # correct hardcoded paths
385 %{l_shtool} subst \
386 -e "s;\(dependency_libs='[ \t]*-L\).*;\1%{l_prefix}/lib -L%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]* -liberty';" \
387 $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/liblto_plugin.la
389 # strip installation tree
390 rm -rf $RPM_BUILD_ROOT%{l_prefix}/${triple}
391 rm -f $RPM_BUILD_ROOT%{l_prefix}/info/dir
392 rm -rf $RPM_BUILD_ROOT%{l_prefix}/man/man7 >/dev/null 2>&1 || true
393 rm -f $RPM_BUILD_ROOT%{l_prefix}/lib/*.la >/dev/null 2>&1 || true
394 rm -rf $RPM_BUILD_ROOT%{l_prefix}/lib64 >/dev/null 2>&1 || true
395 rm -f $RPM_BUILD_ROOT%{l_prefix}/bin/*-gcc* >/dev/null 2>&1 || true
396 %if "%{with_cxx}" == "yes"
397 rm -f $RPM_BUILD_ROOT%{l_prefix}/bin/*-c++ >/dev/null 2>&1 || true
398 rm -f $RPM_BUILD_ROOT%{l_prefix}/bin/*-g++ >/dev/null 2>&1 || true
399 %endif
400 strip $RPM_BUILD_ROOT%{l_prefix}/bin/* >/dev/null 2>&1 || true
401 for prog in cc1 cc1plus collect2 cpp; do
402 strip $RPM_BUILD_ROOT%{l_prefix}/lib/gcc%{V_comp}/${triple}/[0-9]*/${prog} \
403 >/dev/null 2>&1 || true
404 done
406 # bump up installation tree
407 ln $RPM_BUILD_ROOT%{l_prefix}/bin/gcc \
408 $RPM_BUILD_ROOT%{l_prefix}/bin/cc
409 ln $RPM_BUILD_ROOT%{l_prefix}/man/man1/gcc.1 \
410 $RPM_BUILD_ROOT%{l_prefix}/man/man1/cc.1
411 %if "%{with_cxx}" == "yes"
412 ln $RPM_BUILD_ROOT%{l_prefix}/man/man1/g++.1 \
413 $RPM_BUILD_ROOT%{l_prefix}/man/man1/c++.1
414 %endif
416 # determine installation file list
417 %{l_rpmtool} files -v -ofiles -r$RPM_BUILD_ROOT %{l_files_std}
419 %files -f files
421 %clean
422 rm -rf $RPM_BUILD_ROOT