When installing a stage3 system which is not identical to the default CHOST and doing the following: emerge kdebase emerge gcc Many library files are not fixed to point to the new location for libstdc++. The bulk of the libraries found to date are under /usr/kde/<kdeversion>. A full list after having emerged just kdebase and no other KDE components is attached. Reproducible: Always Steps to Reproduce: 1. Install system from stage3 onto i686 system 2. Emerge kdebase 3. Update make.conf to reflect i686, remerge GCC Actual Results: KDE breaks down, now pointing to a non-existent libstdc++ in /usr/lib/gcc-lib/i586-pc-linux-gnu. Expected Results: All library files pointing to the host CHOST should be updated to reflect the new.
Created attachment 13839 [details] Brief listing of broken libraries
Minor addendum, it was Stewart Honsberger who noted this anomaly at first, I just got impatient an bug reported it while he was out. ;)
1) Please attach a broken .la 2) This is not really a 'bug' as such, as fix_libtool_files.sh was not designed to do this. It was designed to fix the gcc version when installing a new version of gcc. It should not be too difficult to add this, the only issue is that it will not be safe for a system with a cross compiler installed. Also, there is not real safe way to detect if the user changed the CHOST, so I think support should be added, but not run in the ebuild - lets call it an emergency repair option. I will however think on this more.
Created attachment 13859 [details] Attached .la
Created attachment 13860 [details] Attached .so Attached a .la and a .so file affected by the issue
Ok, sorda have not gotten to this yet. Will try this week.
I spent some time this weekend when still offline to get a fix going, will try to commit as soon as my cvs works again.
Following should address this, although I still have some thoughts about cross compilers having issues. Could it please be tested by somebody with some time ? BTW, it should be in portage by now .. Change set is rather large: -------------------------------------------------------- Index: fix_libtool_files.sh =================================================================== RCS file: /home/cvsroot/gentoo-x86/sys-devel/gcc/files/fix_libtool_files.sh,v retrieving revision 1.6 diff -u -r1.6 fix_libtool_files.sh --- fix_libtool_files.sh 24 Jul 2003 18:00:07 -0000 1.6 +++ fix_libtool_files.sh 24 Aug 2003 08:25:07 -0000 @@ -1,12 +1,12 @@ #!/bin/bash -# Copyright 1999-2002 Gentoo Technologies, Inc. +# Copyright 1999-2003 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 # Author: Martin Schlemmer <azarah@gentoo.org> # $Header: /home/cvsroot/gentoo-x86/sys-devel/gcc/files/fix_libtool_files.sh,v 1.6 2003/07/24 18:00:07 azarah Exp $ usage() { cat << "USAGE_END" -Usage: fix_libtool_files.sh <old-gcc-version> +Usage: fix_libtool_files.sh <old-gcc-version> [--oldarch <old-CHOST>] Where <old-gcc-version> is the version number of the previous gcc version. For example, if you updated to @@ -14,17 +14,32 @@ # fix_libtool_files.sh 3.2 + If you updated to gcc-3.2.3, and the old CHOST was i586-pc-linux-gnu + but you now have CHOST as i686-pc-linux-gnu, run: + + # fix_libtool_files.sh 3.2 --oldarch i586-pc-linux-gnu + + Note that if only the CHOST and not the version changed, you can run + it with the current version and the '--oldarch <old-CHOST>' arguments, + and it will do the expected: + + # fix_libtool_files.sh `gcc -dumpversion` --oldarch i586-pc-linux-gnu + + USAGE_END exit 1 } -if [ "$#" -ne 1 ] +if [ "$2" != "--oldarch" -a "$#" -ne 1 ] || \ + [ "$2" = "--oldarch" -a "$#" -ne 3 ] then usage fi ARGV1="$1" +ARGV2="$2" +ARGV3="$3" source /etc/profile source /sbin/functions.sh @@ -35,6 +50,13 @@ exit 1 fi +if [ "${ARGV2}" = "--oldarch" -a "x${ARGV3}" != "x" ] +then + OLDCHOST="${ARGV3}" +else + OLDCHOST= +fi + AWKDIR="/lib/rcscripts/awk" if [ ! -r "${AWKDIR}/fixlafiles.awk" ] @@ -43,8 +65,9 @@ exit 1 fi -einfo "Scannig libtool files for hardcoded gcc $1 library path..." -/bin/gawk -v OLDVER="${ARGV1}" -f "${AWKDIR}/fixlafiles.awk" +einfo "Scannig libtool files for hardcoded gcc library paths..." +/bin/gawk -v OLDVER="${ARGV1}" -v OLDCHOST="${OLDCHOST}" \ + -f "${AWKDIR}/fixlafiles.awk" # vim:ts=4 Index: awk/fixlafiles.awk =================================================================== RCS file: /home/cvsroot/gentoo-x86/sys-devel/gcc/files/awk/fixlafiles.awk,v retrieving revision 1.7 diff -u -r1.7 fixlafiles.awk --- awk/fixlafiles.awk 28 Apr 2003 02:40:34 -0000 1.7 +++ awk/fixlafiles.awk 24 Aug 2003 08:25:07 -0000 @@ -1,18 +1,33 @@ -# Copyright 1999-2002 Gentoo Technologies, Inc. +# Copyright 1999-2003 Gentoo Technologies, Inc. # Distributed under the terms of the GNU General Public License v2 # Author: Martin Schlemmer <azarah@gentoo.org> # $Header: /home/cvsroot/gentoo-x86/sys-devel/gcc/files/awk/fixlafiles.awk,v 1.7 2003/04/28 02:40:34 azarah Exp $ +function printn(string) +{ + system("echo -n \"" string "\"") +} + function einfo(string) { system("echo -e \" \\e[32;01m*\\e[0m " string "\"") } +function einfon(string) +{ + system("echo -ne \" \\e[32;01m*\\e[0m " string "\"") +} + function ewarn(string) { system("echo -e \" \\e[33;01m*\\e[0m " string "\"") } +function ewarnn(string) +{ + system("echo -ne \" \\e[33;01m*\\e[0m " string "\"") +} + function eerror(string) { system("echo -e \" \\e[31;01m*\\e[0m " string "\"") @@ -30,54 +45,126 @@ } } +# system() wrapper that normalize return codes ... +function dosystem(command, ret) +{ + ret = 0 + + ret = system(command) + if (ret == 0) + return 1 + else + return 0 +} + BEGIN { - while((getline ldsoconf_data < ("/etc/ld.so.conf")) > 0) { + LIBCOUNT = 0 + # Add the two default library paths + DIRLIST[1] = "/lib" + DIRLIST[2] = "/usr/lib" + + # Walk /etc/ld.so.conf line for line and get any library paths + pipe = "cat /etc/ld.so.conf | sort 2>/dev/null" + while(((pipe) | getline ldsoconf_data) > 0) { - if (ldsoconf_data !~ /[[:space:]]*#/) { + if (ldsoconf_data !~ /^[[:space:]]*#/) { if (ldsoconf_data == "") continue + + # Remove any trailing comments + sub(/#.*$/, "", ldsoconf_data) + # Remove any trailing spaces + sub(/[[:space:]]+$/, "", ldsoconf_data) split(ldsoconf_data, nodes, /[:,[:space:]]/) - DIRLIST[1] = "/lib" - DIRLIST[2] = "/usr/lib" - + # Now add the rest from ld.so.conf for (x in nodes) { sub(/=.*/, "", nodes[x]) sub(/\/$/, "", nodes[x]) if (nodes[x] == "") continue + + CHILD = 0 + + # Drop the directory if its a child directory of + # one that was already added ... + for (y in DIRLIST) { + + if (nodes[x] ~ "^" DIRLIST[y]) { + + CHILD = 1 + break + } + } + + if (CHILD) continue - DIRLIST[++i + 2] = nodes[x] + DIRLIST[++LIBCOUNT + 2] = nodes[x] } } } - - if (i == 0) { - eerror("Could not read from /etc/ld.so.conf!") - exit 1 - } - close("/etc/ld.so.conf") + close(pipe) + +# We have no guarantee that ld.so.conf have more library paths than +# the default, and its better to fix .la files only in /lib and +# /usr/lib than not at all ... +# if (LIBCOUNT == 0) { +# eerror("Could not read from /etc/ld.so.conf!") +# exit 1 +# } + + LIBCOUNT += 2 + + # Get current gcc's CHOST + pipe = "gcc -v 2>&1 | egrep '^Reading specs' \ + | sed -e 's:^.*/gcc-lib/\\([^/]*\\)/[0-9]\\+.*$:\\1:' 2>/dev/null" + + # If we fail to get the CHOST, see if we can get the CHOST + # portage thinks we are using ... + if ((!((pipe) | getline CHOST)) || (CHOST == "")) { + close(pipe) + pipe = "/usr/bin/portageq envvar 'CHOST'" + assert(((pipe) | getline CHOST), "(" pipe ") | getline CHOST") + } - pipe = "/usr/bin/python -c 'import portage; print portage.settings[\"CHOST\"];'" - assert(((pipe) | getline CHOST), "(" pipe ") | getline CHOST") close(pipe) + if (CHOST == "") { + eerror("Could not get gcc's CHOST!") + exit 1 + } + + if (OLDCHOST != "") + if (OLDCHOST == CHOST) + OLDCHOST = "" + GCCLIBPREFIX = "/usr/lib/gcc-lib/" GCCLIB = GCCLIBPREFIX CHOST + if (OLDCHOST != "") + OLDGCCLIB = GCCLIBPREFIX OLDCHOST - sub(/\/$/, "", GCCLIB) - + # Get current gcc's version pipe = "gcc -dumpversion" assert(((pipe) | getline NEWVER), "(" pipe ") | getline NEWVER)") close(pipe) + + if (NEWVER == "") { + eerror("Could not get gcc's version!") + exit 1 + } + + # Nothing to do ? + if ((OLDVER == NEWVER) && (OLDCHOST == "")) + exit 0 - for (x in DIRLIST) { + for (x = 1;x <= LIBCOUNT;x++) { + # Do nothing if the target dir is gcc's internal library path if (DIRLIST[x] ~ GCCLIBPREFIX) continue einfo(" Scanning " DIRLIST[x] "...") @@ -85,37 +172,103 @@ pipe = "find " DIRLIST[x] "/ -name '*.la' 2>/dev/null" while (((pipe) | getline la_files) > 0) { + # Do nothing if the .la file is located in gcc's internal lib path if (la_files ~ GCCLIBPREFIX) continue CHANGED = 0 + CHOST_CHANGED = 0 + # See if we need to fix the .la file while ((getline la_data < (la_files)) > 0) { - if ((gsub(GCCLIB "/" OLDVER "/", GCCLIB "/" NEWVER "/", la_data) > 0) || - (gsub(GCCLIB "/" OLDVER "[[:space:]]", GCCLIB "/" NEWVER " ", la_data) > 0)) { + if (OLDCHOST != "") { + + if (gsub(OLDGCCLIB "[/[:space:]]+", + GCCLIB, la_data) > 0) { - CHANGED = 1 - break + CHANGED = 1 + CHOST_CHANGED = 1 + } + } + + if (OLDVER != NEWVER) { + + if (gsub(GCCLIB "/" OLDVER "[/[:space:]]+", + GCCLIB "/" NEWVER, la_data) > 0) + CHANGED = 1 } } close(la_files) + # Do the actual changes in a second loop, as we can then + # verify that CHOST_CHANGED among things is correct ... if (CHANGED) { - ewarn(" FIXING: " la_files) + ewarnn(" FIXING: " la_files " ... ") + + if (CHANGED) + printn("[") + + # Clear the temp file (removing rather than '>foo' is better + # out of a security point of view?) + dosystem("rm -f " la_files ".new") while ((getline la_data < (la_files)) > 0) { - gsub(GCCLIB "/" OLDVER "/", GCCLIB "/" NEWVER "/", la_data) - gsub(GCCLIB "/" OLDVER "[[:space:]]", GCCLIB "/" NEWVER " ", la_data) + if (OLDCHOST != "") { + + tmpstr = gensub(OLDGCCLIB "([/[:space:]]+)", + GCCLIB "\\1", "g", la_data) + + if (la_data != tmpstr) { + printn("c") + la_data = tmpstr + } + + if (CHOST_CHANGED > 0) { + + # We try to be careful about CHOST changes outside + # the gcc library path (meaning we cannot match it + # via /GCCLIBPREFIX CHOST/) ... + + # Catch: + # + # dependency_libs=' -L/usr/CHOST/{bin,lib}' + # + gsub("-L/usr/" OLDCHOST "/", + "-L/usr/" CHOST "/", la_data) + # Catch: + # + # dependency_libs=' -L/usr/lib/gcc-lib/CHOST/VER/../../../../CHOST/lib' + # + la_data = gensub("(" GCCLIB "/[^[:space:]]+)/" OLDCHOST "/", + "\\1/" CHOST "/", "g", la_data) + } + } + + if (OLDVER != NEWVER) { + + tmpstr = gensub(GCCLIB "/" OLDVER "([/[:space:]]+)", + GCCLIB "/" NEWVER "\\1", "g", la_data) + + if (la_data != tmpstr) { + printn("v") + la_data = tmpstr + } + } print la_data >> (la_files ".new") } + if (CHANGED) + print "]" + + close(la_files) close(la_files ".new") - system("mv -f " la_files ".new " la_files) + assert(dosystem("mv -f " la_files ".new " la_files), + "dosystem(\"mv -f " la_files ".new " la_files "\")") } } --- 1/gcc-3.3.1.ebuild 2003-08-10 23:09:11.000000000 +0200 +++ 2/gcc-3.3.1.ebuild 2003-08-17 14:43:51.221198560 +0200 @@ -130,15 +130,25 @@ chk_gcc_version() { # This next bit is for updating libtool linker scripts ... - OLD_GCC_VERSION="`gcc -dumpversion`" + local OLD_GCC_VERSION="`gcc -dumpversion`" + local OLD_GCC_CHOST="$(gcc -v 2>&1 | egrep '^Reading specs' |\ + sed -e 's:^.*/gcc-lib/\([^/]*\)/[0-9]\+.*$:\1:')" if [ "${OLD_GCC_VERSION}" != "${MY_PV_FULL}" ] then - echo "${OLD_GCC_VERSION}" > ${WORKDIR}/.oldgccversion + echo "${OLD_GCC_VERSION}" > "${WORKDIR}/.oldgccversion" + fi + + if [ -n "${OLD_GCC_CHOST}" ] + then + if [ "${CHOST}" = "${CCHOST}" -a "${OLD_GCC_CHOST}" != "${CHOST}" ] + then + echo "${OLD_GCC_CHOST}" > "${WORKDIR}/.oldgccchost" + fi fi # Did we check the version ? - touch ${WORKDIR}/.chkgccversion + touch "${WORKDIR}/.chkgccversion" } version_patch() { @@ -527,11 +537,27 @@ fi # Update libtool linker scripts to reference new gcc version ... - if [ -f ${WORKDIR}/.oldgccversion -a "${ROOT}" = "/" ] + if [ "${ROOT}" = "/" ] && \ + [ -f "${WORKDIR}/.oldgccversion" -o -f "${WORKDIR}/.oldgccchost" ] then - OLD_GCC_VERSION="`cat ${WORKDIR}/.oldgccversion`" + local OLD_GCC_VERSION= + local OLD_GCC_CHOST= + + if [ -f "${WORKDIR}/.oldgccversion" ] && \ + [ -n "$(cat "${WORKDIR}/.oldgccversion")" ] + then + OLD_GCC_VERSION="$(cat "${WORKDIR}/.oldgccversion")" + else + OLD_GCC_VERSION="${MY_PV_FULL}" + fi + + if [ -f "${WORKDIR}/.oldgccchost" ] && \ + [ -n "$(cat "${WORKDIR}/.oldgccchost")" ] + then + OLD_GCC_CHOST="--oldarch $(cat "${WORKDIR}/.oldgccchost")" + fi - /sbin/fix_libtool_files.sh ${OLD_GCC_VERSION} + /sbin/fix_libtool_files.sh ${OLD_GCC_VERSION} ${OLD_GCC_CHOST} fi # Fix ncurses b0rking (if r5 isn't unmerged)
Should be fixed.