14aee7db8313ebfb1eac1d5af7bd68d835f1fb47
[gentoo.git] / sys-devel / gcc-config / files / gcc-config-1.5
1 #!/bin/bash
2 # Copyright 1999-2011 Gentoo Foundation
3 # Distributed under the terms of the GNU General Public License v2
4 # $Id$
5
6 # Format of /etc/env.d/gcc/:
7 #  config-TARGET:       CURRENT=version for TARGET
8 #  TARGET-VER:          has a TARGET and VER variable
9
10 : ${ROOT:=/}
11 [[ ${ROOT} != */ ]] && ROOT="${ROOT}/"
12 [[ ${ROOT} != /* ]] && ROOT="${PWD}${ROOT}"
13
14 cd /
15
16 trap ":" INT QUIT TSTP
17
18 argv0=${0##*/}
19 source /etc/init.d/functions.sh || {
20         echo "${argv0}: Could not source /etc/init.d/functions.sh!" 1>&2
21         exit 1
22 }
23 esyslog() { :; }
24 umask 022
25
26 die_eerror() {
27         eerror "${argv0}: $*"
28         exit 1
29 }
30
31 # *BSD are plain stupid ... copy a GNU extension but don't just copy it,
32 # change it so it works differently.  Wish Darwin did selective evolution
33 # on software developers.
34 SED=$(type -P gsed)
35 : ${SED:=$(type -P sed)}
36
37 # Further pain: `tac` is not available everywhere #390179
38 if ! type -P tac >/dev/null ; then
39         tac() { ${SED} -e '1!G;h;$!d' "$@" ; }
40 fi
41
42 GENTOO_LIBDIR="@GENTOO_LIBDIR@"
43 [[ ${GENTOO_LIBDIR} == @*@ ]] && GENTOO_LIBDIR="lib"
44
45 usage() {
46 cat << "USAGE_END"
47 Usage: gcc-config [options] [CC Profile]
48 Change the current cc/gcc profile, or give info about profiles.
49
50 Options:
51   -C, --nocolor              Disable color output
52   -O, --use-old              Use the old profile if one was selected.
53   -f, --force                Make sure all config files are regenerated.
54   -P, --use-portage-chost    Only set to given profile if its CHOST is the
55                              same as that set in /etc/portage/make.conf
56                              (or one of other portage config files...).
57   -c, --get-current-profile  Print current used gcc profile.
58   -l, --list-profiles        Print a list of available profiles.
59   -S, --split-profile        Split profiles into their components
60   -E, --print-environ        Print environment that can be used to setup the
61                              current gcc profile, or a specified one.
62   -B, --get-bin-path         Print path where binaries of the given/current
63                              profile are located.
64   -L, --get-lib-path         Print path where libraries of the given/current
65                              profile are located.
66
67 Profile names are of the form:  <CHOST>-<gcc version>
68 For example:                    i686-pc-linux-gnu-3.2.1
69 USAGE_END
70         exit ${1:-1}
71 }
72 [[ $# -lt 1 ]] && usage 1
73
74 # Usage: source_var <var> <file> [default value]
75 source_var() {
76         unset $1
77         local val=$(source "$2"; echo ${!1})
78         : ${val:=$3}
79         eval $1=\"${val}\"
80 }
81 show_var() {
82         source_var "$@"
83         echo "${!1}"
84 }
85
86 try_real_hard_to_find_CHOST() {
87         #
88         # First we read make.conf
89         #
90
91         local varname=${1:-CHOST}
92         local conf=${ROOT}/etc/portage/make.conf
93         if [[ ! -e ${conf} && -e ${ROOT}/etc/make.conf ]] ; then
94                 conf=${ROOT}/etc/make.conf
95         fi
96         local ret=$(source "${conf}" 2>/dev/null ; echo ${!varname})
97         if [[ -z ${ret} ]] ; then
98                 # newer portage supports spaces between the var and =
99                 # CHOST     =  "this-is-retarded"
100                 ret=$(eval $(
101                         sed -n \
102                                 -e 's:[[:space:]]::g' \
103                                 -e "/^${varname}=/p" \
104                                 "${conf}"
105                         ) ; echo ${!varname}
106                 )
107         fi
108
109         if [[ -n ${ret} ]] ; then
110                 echo ${ret}
111                 return 0
112         fi
113
114         #
115         # Then we try /etc/env.d/gcc/config-${CTARGET}
116         #
117         if [[ -s ${ROOT}/etc/env.d/gcc/config-${CTARGET} ]] ; then
118                 ret=$(split_gcc_ver $(show_var CURRENT "${ROOT}"/etc/env.d/gcc/config-${CTARGET}))
119                 echo ${ret% *}
120         fi
121 }
122
123 get_real_chost() {
124         [[ -n ${REAL_CHOST} ]] && return 0
125
126         # shortcut for switching compilers in a cross chroot
127         if [[ -n ${CHOST} && ${ROOT} != "/" ]] ; then
128                 REAL_CHOST=${CHOST}
129                 return 0
130         fi
131
132         # make sure portage isnt broken
133         if python -V &>/dev/null ; then
134                 export REAL_CHOST=$(env -i portageq envvar CHOST 2>/dev/null)
135         else
136                 ewarn "Python seems to be broken, attempting to locate CHOST ourselves ..."
137                 export REAL_CHOST=$(try_real_hard_to_find_CHOST)
138         fi
139
140         if [[ -z ${REAL_CHOST} ]] ; then
141                 eerror "${argv0}: Could not get portage CHOST!"
142                 eerror "${argv0}: You should verify that CHOST is set in one of these places:"
143                 eerror "${argv0}:  - ${ROOT}/etc/portage/make.conf"
144                 eerror "${argv0}:  - active environment"
145                 exit 1
146         fi
147 }
148
149 is_cross_compiler() {
150         get_real_chost
151         [[ ${CC_COMP/${REAL_CHOST}} == ${CC_COMP} ]]
152 }
153
154 convert_profile_paths() {
155         # Older gcc's used PATH= and ROOTPATH= in the env.d files.
156         # Newer one's only use GCC_PATH=.  Convert old to new here.
157         cp -p "${GCC_ENV_D}/${CC_COMP}" "${GCC_ENV_D}/${CC_COMP}.gcc-config-ref" || return 1
158         GCC_PATH=$(
159                 unset GCC_PATH PATH ROOTPATH
160                 source "${GCC_ENV_D}/${CC_COMP}"
161                 echo ${GCC_PATH:-${PATH:-${ROOTPATH}}}
162         )
163         ${SED} -i \
164                 -e '/^PATH=/d' \
165                 -e '/^ROOTPATH=/d' \
166                 -e '/^GCC_PATH=/d' \
167                 "${GCC_ENV_D}/${CC_COMP}" || return 1
168         echo "GCC_PATH=\"${GCC_PATH}\"" >> "${GCC_ENV_D}/${CC_COMP}" || return 1
169         touch -r "${GCC_ENV_D}/${CC_COMP}.gcc-config-ref" "${GCC_ENV_D}/${CC_COMP}" || return 1
170         rm -f "${GCC_ENV_D}/${CC_COMP}.gcc-config-ref" || return 1
171         return 0
172 }
173
174 update_wrappers() {
175         local CTARGET=$1
176
177         # Find the bin wrapper
178         local wrapper
179         for wrapper in ${GENTOO_LIBDIR} lib lib64 lib32 lib ; do
180                 wrapper="${ROOT}usr/${wrapper}/misc/gcc-config"
181                 [[ -e ${wrapper} ]] && break
182         done
183
184         # Update the wrappers for this profile.  We maintain this list
185         # by hand as the tools that are available can come & go if the
186         # user re-emerges gcc with dif USE flags.  We need to clean out
187         # the old wrappers if the functionality no longer exists.
188         # XXX: Future work: save the list of wrappers we generated in
189         # the generated env.d file so we can scrub things better.
190         # After that, we can use a dynamic list based on what tools are
191         # actually available in ${GCC_PATH}/.
192         for x in {,${CTARGET}-}{cpp,cc,gcc,c++,g++,f77,g77,gcj,gcjh,gcov,gdc,gdmd,gfortran,gccgo} ; do
193                 # Obviously don't want to touch native stuff for cross-compilers
194                 [[ ${x} != ${CTARGET}-* ]] && is_cross_compiler && continue
195
196                 # Make sure we have no stale wrappers
197                 rm -f "${ROOT}/usr/bin/${x}"
198                 [[ ${x:${#x}-3} == "gcc" || ${x:${#x}-3} == "g++" ]] \
199                         && rm -f "${ROOT}/usr/bin/${x}"{32,64}
200
201                 # Only install a wrapper if the binary exists ...
202                 # We want to figure out the 'reference file' for each
203                 # wrapper (the binary we're 'wrapping') so that we can
204                 # sync mtimes together.  This makes things like ccache
205                 # happy.  See Bug #70548 for more info.
206                 local ref
207                 case ${x} in
208                         cc)  ref=gcc;;
209                         f77) ref=g77;;
210                         *)   ref=${x};;
211                 esac
212                 ref="${ROOT}/${GCC_PATH}/${ref}"
213                 if [[ -x ${ref} ]] ; then
214                         cp -f "${wrapper}" "${ROOT}/usr/bin/${x}"
215                         touch -r "${ref}" "${ROOT}/usr/bin/${x}"
216                 fi
217         done
218         # legacy cruft, make sure we dont leave it laying around #143205
219         rm -f "${ROOT}/usr/bin/${CTARGET}-cc"
220
221         # install the canonical cpp wrapper
222         [[ ${CTARGET} == *-solaris* ]] && return 0
223         if ! is_cross_compiler ; then
224                 cp -f "${wrapper}" "${ROOT}/lib/cpp"
225                 touch -r "${ROOT}/usr/bin/${CTARGET}-cpp" "${ROOT}/lib/cpp"
226         fi
227 }
228
229 mv_if_diff() {
230         if cmp -s "$1" "$2" ; then
231                 rm -f "$1"
232                 return 0
233         else
234                 mv -f "$1" "$2"
235                 return 1
236         fi
237 }
238
239 switch_profile() {
240         local MY_LDPATH=
241         local GCC_PROFILES=
242         local OLD_CC_COMP=
243         local GCC_PATH=
244
245         [[ $(id -u) != "0" ]] && die_eerror "Must be root"
246
247         if is_cross_compiler ; then
248                 ebegin "Switching cross-compiler to ${CC_COMP}"
249         else
250                 ebegin "Switching native-compiler to ${CC_COMP}"
251         fi
252
253         if egrep -q '^(PATH|ROOTPATH)=' "${GCC_ENV_D}/${CC_COMP}" ; then
254                 convert_profile_paths "${GCC_ENV_D}/${CC_COMP}" || return 1
255         fi
256         source_var GCC_PATH "${GCC_ENV_D}/${CC_COMP}"
257
258         # Setup things properly again for this profile
259         unset GCC_SPECS LDPATH
260         source "${GCC_ENV_D}/${CC_COMP}"
261         # Ignore active profile errors here since we're switching away
262         OLD_CC_COMP=$(get_current_profile 2>/dev/null)
263
264         # GCC_SPECS have long been stable, and people messing with
265         # them know better than to install bad paths, so don't bother
266         # with sanity checks.
267         local envd="${ENV_D}/05gcc-${CTARGET}"
268         cat <<-EOF > "${envd}.tmp"
269         PATH="${GCC_PATH}"
270         ROOTPATH="${GCC_PATH}"
271         GCC_SPECS="${GCC_SPECS}"
272         EOF
273         echo "CURRENT=${CC_COMP}" > "${GCC_ENV_D}/config-${CTARGET}"
274         if ! is_cross_compiler ; then
275                 # Order our profiles to have the default first ...
276                 # We do this so that we can have them ordered with default
277                 # first in /etc/ld.so.conf, as the logical is that all
278                 # compilers for default CHOST will be used to compile stuff,
279                 # and thus we want all their lib paths in /etc/ld.so.conf ...
280                 get_real_chost
281                 MY_LDPATH=$(${SED} -n \
282                         -e '/^LDPATH=/{s|LDPATH=||;s|"||g;s|:|\n|g;p}' \
283                         "${GCC_ENV_D}"/${REAL_CHOST}-* \
284                         "${GCC_ENV_D}"/${CC_COMP} | tac
285                 )
286
287                 # Pass all by default
288                 awk '!/^(STDCXX_INCDIR|LDPATH|CC|CXX|CTARGET|GCCBITS|GCC_SPECS|GCC_PATH)=/ {print $0}' \
289                         "${GCC_ENV_D}/${CC_COMP}" >> "${envd}.tmp"
290                 if [[ -d ${ROOT}/etc/ld.so.conf.d ]] ; then
291                         echo "${MY_LDPATH}" > "${ROOT}"/etc/ld.so.conf.d/05gcc-${CTARGET}.conf
292                 else
293                         echo "LDPATH=\"${MY_LDPATH}\"" >> "${envd}.tmp"
294                 fi
295
296                 # Punt old files; maybe globs too much, but oh well
297                 rm -f \
298                         "${GCC_ENV_D}/NATIVE" "${GCC_ENV_D}/.NATIVE" \
299                         "${ENV_D}/05gcc" "${GCC_ENV_D}/config" \
300                         "${ENV_D}/05gcc-${CTARGET}"-* "${GCC_ENV_D}/config-${CTARGET}"-*
301
302                 # Help out the gcc wrapper
303                 ln -sf ${CC_COMP} "${GCC_ENV_D}/.NATIVE"
304
305
306                 # Relocate random crap
307                 if [[ -e ${ROOT}/usr/${GENTOO_LIBDIR}/pkgconfig/libgcj-${CC_COMP_VERSION}.pc ]] ; then
308                         local mver=${CC_COMP_VERSION:0:3}
309                         for x in "" "-${mver}" ; do
310                                 x="${ROOT}/usr/lib/pkgconfig/libgcj${x}.pc"
311                                 rm -f "${x}"
312                                 ln -s libgcj-${CC_COMP_VERSION}.pc "${x}"
313                         done
314                 fi
315
316                 # We need to make sure that libgcc_s.so / libunwind.so make it into /lib.
317                 # On many systems (x86/amd64/etc...), this will probably never matter,
318                 # but on other systems (arm/mips/etc...), this is quite critical.
319                 # http://bugs.gentoo.org/60190
320                 #
321                 # The funky move magic is required for proper updating of in-use files.
322                 #
323                 # Need to cut out extra paths in multilib case and pray the first path
324                 # is the "root" multilib path ... maybe some day change this to use
325                 # `gcc -print-file-name` ...
326                 LDPATH=${LDPATH%%:*}
327                 for multilib in $("${ROOT}/${GCC_PATH}"/gcc -print-multi-lib); do
328                         multiarg=${multilib#*;}
329                         multiarg=${multiarg/@/-}
330                         multilibdir=${multilib%;*}
331                         libdir="lib/"$("${ROOT}/${GCC_PATH}"/gcc ${multiarg} -print-multi-os-directory)
332                         if mkdir -p "${ROOT}/${libdir}"/.gcc.config.new ; then
333                                 for gcclib in gcc_s unwind ; do
334                                         if [[ -n $(ls "${ROOT}/${LDPATH}/${multilibdir}"/lib${gcclib}.so.* 2>/dev/null) ]]; then
335                                                 cp -pP "${ROOT}/${LDPATH}/${multilibdir}"/lib${gcclib}.so.* "${ROOT}/${libdir}"/.gcc.config.new/
336                                                 # no need to sanity remove this as the `mv` should take
337                                                 # care of it.  we also need this step to be completly atomic
338                                                 # for systems that have even `mv` linked against libgcc_s.so.
339                                                 # http://bugs.gentoo.org/150257
340                                                 #rm -f "${ROOT}/${libdir}"/lib${gcclib}.so*
341                                                 mv -f "${ROOT}/${libdir}"/.gcc.config.new/* "${ROOT}/${libdir}"/
342                                         fi
343                                 done
344                                 rmdir "${ROOT}/${libdir}"/.gcc.config.new
345                         fi
346                 done
347                 unset multilib
348                 unset multilibdir
349                 unset multiarg
350                 unset libdir
351         fi
352         mv_if_diff "${envd}.tmp" "${envd}"
353         local envd_changed=$?
354
355         update_wrappers ${CTARGET}
356
357         if [[ ${ROOT} == "/" ]] && \
358            [[ ${OLD_CC_COMP} != ${CC_COMP} || ${FORCE} == "yes" ]] && \
359            [[ ${envd_changed} -eq 1 ]]
360         then
361                 # in case python is broken ...
362                 if ! env-update ; then
363                         echo ""
364                         ewarn "env-update failed to work properly; making sure ld.so.conf paths"
365                         ewarn "are setup properly.  Please rerun gcc-config with the -f option."
366                         echo ""
367                         if [[ ! -d /etc/ld.so.conf.d ]] ; then
368                                 show_var LDPATH "${ROOT}"/etc/env.d/05gcc-${CTARGET} \
369                                         | sed -e 's|:|\n|g' >> /etc/ld.so.conf
370                         fi
371                         ldconfig
372                 fi
373         else
374                 envd_changed=0
375         fi
376
377         eend 0
378
379         if [[ ${envd_changed} -ne 0 ]] ; then
380                 echo
381                 ewarn "If you intend to use the gcc from the new profile in an already"
382                 ewarn "running shell, please remember to do:"
383                 echo
384                 ewarn "  . /etc/profile"
385                 echo
386         fi
387
388         return 0
389 }
390
391 get_current_profile() {
392         local conf="${GCC_ENV_D}/config-${CTARGET}"
393         if [[ ! -f ${conf} ]] ; then
394                 conf="${GCC_ENV_D}/config" # old name
395         elif [[ -n ${CC_COMP} ]] && is_cross_compiler ; then
396                 conf="${conf}-${CC_COMP}"
397         fi
398
399         if [[ ! -f ${conf} ]] ; then
400                 eerror "${argv0}: No gcc profile is active!"
401                 return 1
402         fi
403
404         source_var CURRENT "${conf}"
405
406         if [[ -z ${CURRENT} ]] ; then
407                 eerror "${argv0}: No gcc profile is active!"
408                 return 1
409         elif [[ ! -f ${GCC_ENV_D}/${CURRENT} ]] ; then
410                 eerror "${argv0}: Active gcc profile is invalid!"
411                 return 1
412         fi
413
414         echo "${CURRENT}"
415
416         return 0
417 }
418
419 list_profiles() {
420         local i=0
421         local filter=
422
423         if [[ ${ROOT} != "/" ]] ; then
424                 echo "Using gcc-config info in ${ROOT}"
425         fi
426
427         if [[ ! -f ${GCC_ENV_D}/config-${CTARGET} ]] ; then
428                 if ! is_cross_compiler && [[ -e ${GCC_ENV_D}/config ]] ; then
429                         [[ -w ${GCC_ENV_D}/config ]] && mv ${GCC_ENV_D}/config ${GCC_ENV_D}/config-${CTARGET}
430                 else
431                         # get_current_profile already warns
432                         #eerror "${argv0}: No gcc profile is active; please select one!"
433                         filter=${CTARGET}
434                 fi
435         fi
436
437         source_var CURRENT "${GCC_ENV_D}"/config-${CTARGET}
438         CURRENT_NATIVE=${CURRENT}
439         local target=
440         for x in "${GCC_ENV_D}"/* ; do
441                 [[ -f ${x} ]] || continue
442                 [[ ${x} == */config* ]] && continue
443
444                 source_var CTARGET "${x}"
445
446                 ((++i))
447
448                 [[ -n ${filter} ]] && [[ ${filter} != ${CTARGET} ]] && continue
449
450                 if [[ ${target} != ${CTARGET} ]] ; then
451                         [[ ${i} -gt 1 ]] && echo
452                         target=${CTARGET}
453                         CTARGET=""
454                 fi
455
456                 x=${x##*/}
457                 if [[ ${x} == ${CURRENT_NATIVE} ]] ; then
458                         x="${x} ${GOOD}*${NORMAL}"
459                 elif [[ -e ${GCC_ENV_D}/config-${target} ]] ; then
460                         source "${GCC_ENV_D}/config-${target}"
461                         [[ ${x} == ${CURRENT} ]] && x="${x} ${HILITE}*${NORMAL}"
462                 fi
463                 echo " [${i}] ${x}"
464         done
465 }
466
467 print_environ() {
468         local GCC_PATH=
469         local ENV_CMD=
470         local SET_ELEMENT=
471
472         source_var GCC_PATH "${GCC_ENV_D}/${CC_COMP}" "${PATH}"
473
474         case ${SHELL} in
475                 */csh|*/tcsh)
476                         ENV_CMD="setenv"
477                         SET_ELEMENT=" "
478                         ;;
479                 *)
480                         ENV_CMD="export"
481                         SET_ELEMENT="="
482                         ;;
483         esac
484
485         (
486         PATH=${GCC_PATH}:${PATH}
487         for var in PATH GCC_SPECS ; do
488                 echo "${ENV_CMD} ${var}${SET_ELEMENT}\"${!var}\""
489         done
490         )
491 }
492
493 get_bin_path() { show_var GCC_PATH "${GCC_ENV_D}/${CC_COMP}" ; }
494 get_lib_path() { show_var LDPATH "${GCC_ENV_D}/${CC_COMP}" ; }
495
496 split_gcc_ver() {
497         # Split up the gcc profile into components:
498         # TARGET-VER[-specs] -> TARGET VER [specs]
499         # arm-linux-3.3.6 -> arm-linux 3.3.6
500         # x86_64-linux-4.0.1-pre1234 -> x86_64-linux 4.0.1-pre1234
501         # sh-linux-3.4.4-hardened -> sh-linux 3.4.4 hardened
502         #
503         # So below we will start at the end and run a small state machine ...
504         # specs [3]
505         #    accept everything
506         # specs -> version transition [3->2]
507         #    when we find a version component
508         # version [2]
509         #    accept only version components (see the regex)
510         # version -> target transition [2->1]
511         #    when we hit a non version component
512         # target [1]
513         #    accept everything we have left
514         #
515         echo "$@" | awk -F- '
516         function pushit(onme, pushee) {
517                 return (onme == "" ? pushee : pushee"-"onme);
518         }
519         {
520                 state=3
521                 targ=""
522                 ver=""
523                 spec=""
524                 for (i=NF; i > 0; --i) {
525                         if (state >= 2) {
526                                 if ($i ~ /^(alpha|beta|pre|rc|p)?[[:digit:].]+$/) {
527                                         ver=pushit(ver, $i)
528                                         state=2
529                                 } else if (state == 3)
530                                         spec=pushit(spec, $i)
531                                 else
532                                         state=1
533                         }
534                         if (state == 1)
535                                 targ = pushit(targ, $i)
536                 }
537
538                 if (targ == "") {
539                         if (ver == "") {
540                                 ver=spec
541                                 spec=""
542                         }
543                         targ=ver
544                         ver=""
545                 }
546                 print targ " " ver (spec != "" ? " " spec : "")
547         }'
548 }
549 chop_gcc_ver_spec() {
550         local splitTED=$(split_gcc_ver $@) # target ver spec
551         splitTED=${splitTED#* }            # ver spec
552         echo ${splitTED/ /-}               # ver-spec
553 }
554
555 SET_X=false
556 NEED_ACTION="yes"
557 DOIT="switch_profile"
558 CHECK_CHOST="no"
559 FORCE="no"
560
561 CC_COMP=
562 ENV_D="${ROOT}etc/env.d"
563 GCC_ENV_D="${ENV_D}/gcc"
564
565 for x in "$@" ; do
566         case "${x}" in
567                 # Only use specified compiler if one is not already selected.
568                 -O|--use-old)
569                         : ${CTARGET:=$(try_real_hard_to_find_CHOST)}
570                         if get_current_profile &>/dev/null ; then
571                                 CC_COMP=$(get_current_profile)
572                         else
573                                 die_eerror "No profile selected, unable to utilize --use-old"
574                         fi
575                         ;;
576                 -f|--force)
577                         FORCE="yes"
578                         ;;
579                 -P|--use-portage-chost)
580                         CHECK_CHOST="yes"
581                         ;;
582                 -c|--get-current-profile)
583                         if [[ ${NEED_ACTION} == "yes" ]] ; then
584                                 NEED_ACTION="no"
585                                 DOIT="get_current_profile"
586                         fi
587                         ;;
588                 -l|--list-profiles)
589                         if [[ ${NEED_ACTION} == "yes" ]] ; then
590                                 NEED_ACTION="no"
591                                 DOIT="list_profiles"
592                         fi
593                         ;;
594                 -S|--split-profile)
595                         if [[ ( $1 != "-S" && $1 != "--split-profile" ) || $# -eq 1 ]] ; then
596                                 usage 1
597                         fi
598                         shift # push -S out
599                         for x in "$@" ; do
600                                 split_gcc_ver ${x}
601                         done
602                         exit 0
603                         ;;
604                 -E|--print-environ)
605                         if [[ ${NEED_ACTION} == "yes" ]] ; then
606                                 NEED_ACTION="no"
607                                 DOIT="print_environ"
608                         fi
609                         ;;
610                 -B|--get-bin-path)
611                         if [[ ${NEED_ACTION} == "yes" ]] ; then
612                                 NEED_ACTION="no"
613                                 DOIT="get_bin_path"
614                         fi
615                         ;;
616                 -L|--get-lib-path)
617                         if [[ ${NEED_ACTION} == "yes" ]] ; then
618                                 NEED_ACTION="no"
619                                 DOIT="get_lib_path"
620                         fi
621                         ;;
622                 -x|--debug)
623                         SET_X=true
624                         ;;
625                 -C|--nocolor)
626                         # nothing to do; functions.sh parsed this for us
627                         ;;
628                 -h|--help)
629                         usage 0
630                         ;;
631                 -V|--version)
632                         unset RCSfile Revision Date
633                         rcsfile="$RCSfile: gcc-config-1.5,v $"
634                         rcsfile=${rcsfile#: }
635                         rcsfile=${rcsfile%,v*}
636                         cvsrev="$Revision: 1.7 $"
637                         cvsrev=${cvsrev#: }
638                         cvsdate="$Date: 2011/12/07 05:42:19 $"
639                         cvsdate=${cvsdate#: }
640                         echo "${rcsfile} (r${cvsrev% *} @ ${cvsdate% *})"
641                         exit 0
642                         ;;
643                 -*)
644                         die_eerror "Invalid switch!  Run ${argv0} without parameters for help."
645                         ;;
646                 *)
647                         ${SET_X} && set -x
648                         if [[ -z ${CC_COMP} ]] ; then
649                                 if [[ -z $(echo ${x} | tr -d '[:digit:]') ]] ; then
650                                         # User gave us a # representing the profile
651                                         i=1
652                                         for y in "${GCC_ENV_D}"/* ; do
653                                                 [[ -f ${y} ]] || continue
654                                                 [[ ${y} == */config* ]] && continue
655
656                                                 if [[ -f ${y} ]] && [[ ${x} == ${i} ]] ; then
657                                                         CC_COMP=${y##*/}
658                                                         break
659                                                 fi
660                                                 ((++i))
661                                         done
662                                         if [[ -z ${CC_COMP} ]] ; then
663                                                 die_eerror "Could not locate profile #$x !"
664                                         fi
665                                 else
666                                         # User gave us a full HOST-gccver
667                                         x=${x##*/}
668                                         if [[ ${DOIT} == "get_current_profile" && -z $(ls "${GCC_ENV_D}"/${x}-* 2>/dev/null) ]] || \
669                                            [[ ${DOIT} != "get_current_profile" && ! -f ${GCC_ENV_D}/${x} ]]
670                                         then
671                                                 # Maybe they just gave us a gccver ...
672                                                 get_real_chost
673                                                 if [[ -f ${GCC_ENV_D}/${REAL_CHOST}-${x} ]] ; then
674                                                         x=${REAL_CHOST}-${x}
675                                                 else
676                                                         die_eerror "Could not locate '$x' in '${GCC_ENV_D}/' !"
677                                                 fi
678                                         fi
679                                         CC_COMP=${x}
680                                 fi
681                         else
682                                 die_eerror "Too many arguments!  Run ${argv0} without parameters for help."
683                         fi
684                         ;;
685         esac
686 done
687
688 ${SET_X} && set -x
689
690 if [[ ${DOIT} == "switch_profile" ]] && [[ -z ${CC_COMP} ]] ; then
691         usage 1
692 fi
693
694 get_real_chost
695 [[ ${DOIT} == "get_current_profile" ]] \
696         && : ${CTARGET:=${CC_COMP:-${REAL_CHOST}}} \
697         || : ${CTARGET:=${REAL_CHOST}}
698
699 if [[ -z ${CC_COMP} ]] ; then
700         CC_COMP=$(get_current_profile)
701         if [[ $? -ne 0 ]] ; then
702                 echo "${CC_COMP}"
703                 list_profiles
704                 exit 1
705         fi
706 fi
707
708 if [[ ${DOIT} != "get_current_profile" ]] ; then
709         GCC_LIB=$(
710                 show_var LDPATH "${GCC_ENV_D}/${CC_COMP}" | \
711                         awk -F/ '{ print  "/"$2"/"$3"/"$4"/" }'
712         )
713
714         CC_COMP_VERSION=$(chop_gcc_ver_spec ${CC_COMP})
715         CC_COMP_TARGET=${CC_COMP%-${CC_COMP_VERSION}*}
716
717         if [[ ! -d ${ROOT}/${GCC_LIB}/${CC_COMP_TARGET}/${CC_COMP_VERSION} ]]; then
718                 CC_COMP_VERSION=${CC_COMP_VERSION%-*}
719         fi
720
721         if [[ ! -d ${ROOT}/${GCC_LIB}/${CC_COMP_TARGET}/${CC_COMP_VERSION} ]] || \
722            [[ ! -f ${GCC_ENV_D}/${CC_COMP} ]]
723         then
724                 eerror "${argv0}: Profile does not exist or invalid setting for ${GCC_ENV_D}/${CC_COMP}" 1>&2
725                 #exit 1
726         fi
727 fi
728
729 if [[ ${CHECK_CHOST} == "yes" ]] ; then
730         # Chosen CHOST are not the same as the real CHOST according to
731         # make.conf, and --use-portage-chost option was given, so do nothing
732         get_real_chost
733         CC_COMP_VERSION=$(chop_gcc_ver_spec ${CC_COMP})
734         CC_COMP_TARGET=${CC_COMP:0:${#CC_COMP}-${#CC_COMP_VERSION}-1}
735         [[ ${CC_COMP_TARGET} != ${REAL_CHOST} ]] && exit 0
736 fi
737
738 ${DOIT}
739
740 # vim:ts=4