h1

My magic AVR build script

2011/08/11

Don’t get me wrong, I like make…  Hah! Yeah, right!

make has its place, no doubt, but small microcontroller projects not so much.  In my projects I like to just start coding, pulling in existing code where it makes sense.  Maintaining a makefile for that gets old really fast, and is massively overwrought compared to the requirements.

So, over the last couple years I’ve developed my own scripts to build AVR projects.  The latest variation has just received a major speedup, so I thought I’d share it along with some selected Bash tips.

#!/bin/sh -e

# Paths to various libraries
xmega=/home/omega/work/xmega
libpaths="/home/omega/work/iostack $xmega"

# Figure out what chip we're targetting
prog=`echo $1 | sed 's/\.c$//g'`;shift
core=$1;shift

# Set up the common commands
cc="avr-gcc -O6 -g -mmcu=${core} -I. -Wl,-u,vfprintf -lprintf_flt -lm -Wall -Werror -Wno-unused-variable $*"
for libpath in $libpaths;do
  cc="$cc -I$libpath"
done
#avrdude="avrdude -cavrisp2 -p${chip} -Pnet:localhost:$pipe"

# Remove and recreate the hidden bin directory
rm -rf .run-${prog}
mkdir .run-${prog}

# Remove the final binary and its srec
rm -f ${prog} ${prog}.srec

# Compile the main source (in background)
/bin/echo -en "${prog}."
$cc -o .run-${prog}/${prog}.o -c ${prog}.c -Wa,-almshd=.run-${prog}/${prog}.lst > .run-${prog}/${prog}.err 2>&1 &
objs=".run-${prog}/${prog}.o"

# Track down all the lib files that are in use
sources="${prog}"
srctocheck="${prog}"
while :;do
  # for all sources still to check, find all the headers they're dependent on
  headers=""
  for srcbase in $srctocheck;do
    hdrs=$(echo `$cc -MM ${srcbase}.c | sed -e 's@\\\\@@g' -e 's@^.*:@@g'`)
    headers="$headers $hdrs"
  done
  # break the list into lines, sort/uniq it, and collapse it again
  headers=$(echo `echo $headers | fmt -w1 | sort -u`)

  # for each header found, check to see if it exists as a C file
  newsrctocheck=""
  for srcbase in `echo $headers | sed 's/\.h//g'`;do
    if [ -e ${srcbase}.c ];then
      # if it isn't already in the sources list, add it
      if `echo $sources | grep -vq ${srcbase}`;then
        # start the compile
        src=`basename $srcbase`
        /bin/echo -en "."
        $cc -c ${srcbase}.c -o .run-${prog}/${src}.o -Wa,-almshd=.run-${prog}/${src}.lst > .run-${prog}/${src}.err &
        objs="$objs .run-${prog}/${src}.o"

        sources="$sources ${srcbase}"
        newsrctocheck="$newsrctocheck ${srcbase}"
      fi
    fi
  done

  if [ "x$newsrctocheck" = "x" ];then
    break
  fi
  srctocheck=$newsrctocheck
done

wait

echo

# check for any errors
haserrors=0
for srcbase in $sources;do
  if [ -s .run-${prog}/${srcbase}.err ];then
    haserrors=$((haserrors + 1))
    echo "ERRORS for $srcbase:"
    cat .run-${prog}/${srcbase}.err
  fi
done
if [ $haserrors -ne 0 ];then
  exit
fi

# Link it all together, strip, and generate SREC
$cc -o ${prog} $objs
avr-strip ${prog}
avr-objcopy --output-target=srec ${prog} ${prog}.srec

The script is run with the base name of the project (without the .c suffix) and the microcontroller to build for. Additional CFLAGS can be added to the commandline, like -D’s.  It will start compiling the main source file, and simultaneously recurse through all the referenced non-system headers looking for other source files in the same place (#includewill add xyz.c in that same directory to the source list).  The libraries listed at the top of the file ($libpaths) contain my various library files (many of which I should publish eventually).

Oh, I promised to share a tip or two about bash:

  • If you have a bunch of strings intermixed with both spaces/tabs and newlines, do this: list=$(echo `generate list`)
  • If that list has potential duplicates you want to get rid of, do this: list=$(echo `echo $list | fmt -w1 | sort -u`)

Anyway, I’m hoping this script is useful for someone ;-)

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: