title: Solving "undefined reference to" errors in a makefile
body: <p>I have a few custom source files in my <code>src</code> directory and a few source files from the Arduino project in my <code>src/base</code> directory.</p>
  
  <p>I compile all source files into objects which are stored in my <code>obj</code> directory using the following make rules:</p>
  
  <pre><code>PATHOBJ := obj/
  PATHSRC := src/
  PATHBIN := bin/
  PATHLIB := lib/
  PATHTMP := tmp/
  PATHARDUINO = $(PATHSRC)base/
  enter code here
  $(PATHOBJ)core_%.o : $(PATHARDUINO)%.c
      @mkdir -p $(dir $@)
      $(GCC) $(ALL_CORE_CFLAGS) -c $&lt; -o $@
  
  $(PATHOBJ)bot_%.o : $(PATHSRC)%.c
      @mkdir -p $(dir $@)
      $(GCC) $(CFLAGS)-c $&lt; -o $@
  </code></pre>
  
  <p>As you can see it would compile <code>src/tacho.c</code> to <code>obj/bot_tacho.o</code> and <code>src/base/wiring_analog.c</code> to <code>obj/core_wiring_analog.o</code>.</p>
  
  <p>In my makefile I compile all of my source files without any problems. In one of these files (namely <code>src/tacho.c</code>) I have added the following include:
  <code>#include "base/wiring.h"</code> which contains the prototype to <code>analogRead</code>.</p>
  
  <p>The funny thing is that <code>wiring.h</code> only contains the prototype to the 'analogRead' function. It doesn't even bother to include the files that actually define the function, but some nosing around led me to discover that the definition of the function was to be found in <code>src/base/wiring_analog.c</code>.</p>
  
  <p>I reckoned it would suffice to compile the file that does declare the function and link it along with all other necessary Arduino object files into a single library. I arbitrarily chose to name it <code>lib/core.a</code>. I made <code>lib/core.a</code> by executing the following:</p>
  
  <pre><code>avr-ar rcs lib/core.a obj/core_wiring.o \
      obj/core_wiring_analog.o \
      obj/core_wiring_digital.o \
      obj/core_wiring_pulse.o \
      obj/core_wiring_shift.o
  </code></pre>
  
  <p>Needless to say I first made sure that the prerequisites for this make rule were in order.</p>
  
  <p>That worked without a problem; however, the problem is that attempting to generate my binary leaves me with a "undefined reference" error.</p>
  
  <pre><code>avr-g++ lib/core.a \
      obj/bot_life.o \
      obj/bot_port.o \
      obj/bot_serial.o \
      obj/bot_time.o \
      obj/bot_tacho.o \
      obj/bot_main.o \
      -o bin/bot.elf
  /home/david/src/botPMA/src/tacho.c:13: undefined reference to `analogRead'
  /home/david/src/botPMA/src/tacho.c:14: undefined reference to `analogRead'
  make[1]: *** [bin/bot.elf] Error 1
  make[1]: Leaving directory `/home/david/src/botPMA'
  make: *** [all] Error 2
  </code></pre>
  
  <p>I did a objdump of the <code>core_%.o</code> objects, and I did notice that <code>core_wiring_analog.o</code> made mention of <code>analogRead</code>. If the way I thought it worked was correct <code>core.a</code> which contains <code>core_wiring_analog.o</code> should therefore contain the definition for <code>analogRead</code>.
  I went back to compile <code>src/tacho.c</code> which uses the function <code>analogRead</code> and that compiled fine every time I tried (the preprocessor didn't see the need to complain about my include). It's the linking that causing problems, I suppose.</p>
  
  <p>I've read a lot of stuff online, but I still can't seem to figure this one out by myself. Probably a stupid mistake, but I just can't see it. How can I solve this problem?</p>
  
  <p>For the sake of completeness, I've dropped my entire project here: <a href="https://code.google.com/p/botpma/source/browse/" rel="nofollow">googlecode repository for my project</a></p>