Решение "неопределенной ссылки на" ошибки в make-файле - PullRequest
2 голосов
/ 02 июня 2011

У меня есть несколько пользовательских исходных файлов в моем каталоге src и несколько исходных файлов из проекта Arduino в моем каталоге src/base.

Я собираю все исходные файлы в объекты, которые хранятся в моемobj директория, использующая следующие правила make:

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 $@

Как вы можете видеть, она будет компилироваться src/tacho.c в obj/bot_tacho.o и src/base/wiring_analog.c в obj/core_wiring_analog.o.

В моемmakefile Я скомпилирую все мои исходные файлы без проблем.В одном из этих файлов (а именно src/tacho.c) я добавил следующее: #include "base/wiring.h", который содержит прототип для analogRead.

Самое смешное, что wiring.h содержит только прототип дляфункция analogRead.Даже не стоит включать файлы, которые на самом деле определяют функцию, но некоторые шумихи привели меня к обнаружению, что определение функции должно быть найдено в src/base/wiring_analog.c.

Я считал, что этого будет достаточноскомпилировать файл, который объявляет функцию, и связать ее вместе со всеми другими необходимыми объектными файлами Arduino в одну библиотеку.Я произвольно решил назвать его lib/core.a.Я сделал lib/core.a, выполнив следующее:

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

Само собой разумеется, я сначала убедился, что предпосылки для этого правила make были в порядке.

Это сработало без проблем;однако проблема в том, что попытка сгенерировать мой бинарный файл оставляет меня с ошибкой «неопределенная ссылка».

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

Я сделал objdump из core_%.o объектов и заметил, что core_wiring_analog.o сделалупоминание о analogRead.Если я думал, что это правильно, то core.a, который содержит core_wiring_analog.o, должен содержать определение для analogRead.Я вернулся к компиляции src/tacho.c, которая использует функцию analogRead, и она прекрасно компилировалась при каждой попытке (препроцессор не видел необходимости жаловаться на мое включение).Полагаю, это связывание порождает проблемы.

Я много чего читал в Интернете, но я все еще не могу понять это сам.Возможно, глупая ошибка, но я просто не вижу ее.Как я могу решить эту проблему?

Ради полноты я отбросил весь свой проект здесь: репозиторий googlecode для моего проекта

Ответы [ 2 ]

5 голосов
/ 03 июня 2011

Я потратил почти весь свой день, чтобы понять, что пропустил параметр компоновщика -L. TARGET. В моем случае моя последняя процедура связывания в итоге выглядела примерно так:

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

Много времени тратится, по-видимому, много часов впустую, но ценный урок усвоен, так что, думаю, оно того стоило.

Деталь, деталь, деталь ...

0 голосов
/ 03 июня 2011

Я написал этот Makefile, вы можете найти его полезным:

http://code.google.com/p/asadchev/source/browse/trunk/work/arduino/Makefile

в основном создайте структуру dir, например:

sketch/sketch.pde
sketch/Makefile

и попробуйте make / makeзагрузить / и т.д.

...