It is quite common to have several toolchains and to switch back and forth between them while doing development. At least, this is something I do a lot when doing Buildroot development and debugging. As I hate typing full paths all the time, I usually put the toolchain bin/
directory into my $PATH
variable, so that I can easily access the toolchain binaries. However, it means that everytime you run a new shell or everytime you want to switch from one toolchain to another, you need to modify the PATH
variable manually by re-exporting it. Of course, one could easily put all the bin/
directories of all toolchains in the PATH, but that would clutter what is shown when I do arm-TAB-TAB
, and that’s not nice.
So, I ended up hacking a few lines of Bash that provide me with two new commands: xtoolsadd, to add a toolchain to my PATH and xtoolsdel, to remove a toolchain from my PATH. These commands work by making the assumption that all toolchains are stored in a common directory. In my case /usr/local/xtools/
contains all the toolchains, one per subdirectory. So I have /usr/local/xtools/arm-unknown-linux-gnu
for an ARM glibc-based non-EABI toolchain, or /usr/local/xtools/arm-unknown-linux-uclibcgnueabi
for an ARM uClibc-based EABI toolchain).
So, now I can do things such as
xtoolsadd arm-unknown-linux-gnu
or
xtoolsdel arm-unknown-linux-uclibcgnueabi
Because these commands must modify the PATH variable of the current shell, they cannot be implemented as separate shell scripts, so they are in fact implemented as functions in my ~/.bashrc
script. And in addition to these functions, I also implemented completion, so when you do xtoolsadd TAB-TAB
, it gives you a choice of toolchains, and if you start typing one and press TAB
, it will just automatically complete for you. The same thing works with xtoolsdel
, of course.
To make this work, here is what you need to put in your ~/.bashrc
file:
export XTOOLSDIR=/usr/local/xtools xtoolsadd() { TOOLCHAINDIR=$XTOOLSDIR/$1/bin if [ ! -d $TOOLCHAINDIR ] ; then echo "Directory $XTOOLSDIR doesn't exist" else case "$PATH" in *"$XTOOLSDIR"*) ;; *) export PATH=$TOOLCHAINDIR:$PATH esac fi } xtoolsdel() { TOOLCHAINDIR=$XTOOLSDIR/$1/bin NEWPATH= found=0 for i in $(echo $PATH | tr ":" "\n") ; do if [ $i == $TOOLCHAINDIR ] ; then found=1 else NEWPATH=$NEWPATH:$i fi done if [ $found == 0 ] ; then echo "$1 is not in your PATH" else export PATH=$NEWPATH fi } _xtoolsadd() { cur=${COMP_WORDS[COMP_CWORD]} LIST=$(ls -1 $XTOOLSDIR | tr "\n" " ") COMPREPLY=( $( compgen -W "$LIST" -- $cur)) } _xtoolsdel() { cur=${COMP_WORDS[COMP_CWORD]} LIST=$(echo $PATH | tr ":" "\n" | grep "^$XTOOLSDIR" | sed "s%$XTOOLSDIR/\([^/]*\)/bin%\1%") COMPREPLY=( $( compgen -W "$LIST" -- $cur)) } complete -F _xtoolsadd xtoolsadd complete -F _xtoolsdel xtoolsdel
The shell code may not be perfect or fully optimized, but it works. Of course, if you have suggestions or questions, don’t hesitate to post comments!