Solving "undefined reference to" errors in a makefile
I've spend nearly my entire day to figure out that i missed the linker parameter -L. TARGET
. In my case my final linking routine ended up looking something like:
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 \
-L. lib/core.a
A lot of time spend, seemingly a lot of hours wasted but a valuable lesson learned so I guess it became worth my while.
Detail, detail, detail...
vidbina
Maker 👷🏿♂️/hacker 👨🏿💻/goofball 🥳 tinkering w/ cloud ☁️, electronics 🤖 & ML 🧠🖥️ , discovering how much I don't know. 📚🤷🏿
Updated on June 04, 2022Comments
-
vidbina almost 2 years
I have a few custom source files in my
src
directory and a few source files from the Arduino project in mysrc/base
directory.I compile all source files into objects which are stored in my
obj
directory using the following make rules: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 $< -o $@ $(PATHOBJ)bot_%.o : $(PATHSRC)%.c @mkdir -p $(dir $@) $(GCC) $(CFLAGS)-c $< -o $@
As you can see it would compile
src/tacho.c
toobj/bot_tacho.o
andsrc/base/wiring_analog.c
toobj/core_wiring_analog.o
.In my makefile I compile all of my source files without any problems. In one of these files (namely
src/tacho.c
) I have added the following include:#include "base/wiring.h"
which contains the prototype toanalogRead
.The funny thing is that
wiring.h
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 insrc/base/wiring_analog.c
.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
lib/core.a
. I madelib/core.a
by executing the following: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
Needless to say I first made sure that the prerequisites for this make rule were in order.
That worked without a problem; however, the problem is that attempting to generate my binary leaves me with a "undefined reference" error.
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
I did a objdump of the
core_%.o
objects, and I did notice thatcore_wiring_analog.o
made mention ofanalogRead
. If the way I thought it worked was correctcore.a
which containscore_wiring_analog.o
should therefore contain the definition foranalogRead
. I went back to compilesrc/tacho.c
which uses the functionanalogRead
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.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?
For the sake of completeness, I've dropped my entire project here: googlecode repository for my project