Ответ 1
Как получить определения для undefined reference
Сообщение undefined reference to 'xxxxxxxxx'
означает, что компоновщик не может найти фактическое определение (а не просто объявление) для рассматриваемой функции.
Когда компоновщик не может найти определение для функции, это определение обычно находится в файле lib (например, *.so или *.dll) или в исходном файле (например, *.cpp или *. с). Для вашего Arduino вам нужно сообщить avr-gcc, чтобы скомпилировать и связать файлы Arduino *.cpp. Вам нужны все исходные файлы из ядра Arduino.
ARDCOREDIR = <my arduino folder>/hardware/arduino/cores/arduino
Судар дал хороший совет, выступая за использование Makefile для AVR, который настроен на включение определений функций Arduino. (Я свяжусь с моим и объясню это ниже.)
В моем make файле я обработал эту операцию следующим образом:
# CPP_SOURCE_FILES is a previously-defined variable, holding my project source files
CPP_SOURCE_FILES += $(filter-out $(ARDCOREDIR)/main.cpp, $(wildcard $(ARDCOREDIR)/*.cpp))
Обратите внимание, что я пропустил файл main.cpp, потому что файл Arduino main.cpp определяет main()
, и я хочу сам определить его в своих файлах проекта.
Необходимые файлы заголовков
Конечно, вы также должны передать avr-gcc флаг include для заголовков arduino:
-I$(ARDCOREDIR)
И вы должны включить файл Ardhuino.h в свой код проекта:
#include <Arduino.h>
Заголовочный файл Arduino.h будет содержать все другие файлы заголовков Arduino, включая файл распиновки, в котором содержатся определения для контактов Arduino. У разных Arduinos должны быть разные файлы распиновки, поэтому укажите тип, который вы используете, и сообщите avr-gcc о включении каталога, содержащего соответствующий файл распиновки. Если вы используете стандартный Arduino (UNO), используйте следующее:
-I$(ARDCOREDIR)/../../variants/standard
Мой файл Makefile
Не только ваш процесс сборки должен реализовать несколько инструкций, описанных выше, он должен знать, как сделать файл .hex, который должен быть запрограммирован на ваш Arduino (или AVR). Поэтому рекомендуется использовать make файл.
Мне не нравится перестраивать мой make файл для каждого проекта, поэтому у меня есть только один базовый make файл на моей машине, и каждый проект имеет свой собственный очень короткий make файл, который вызывает include
, чтобы включить базовый make файл. Здесь вы можете найти мой базовый файл.
Пример короткого (не базового) файла Makefile для одного проекта на моей машине:
# This is the name of the file that shall be created. (It is also the name of my primary source file, without the file extension.)
TARGET = temp
# create a variable that only pertains to this project
MY_OWN_LIBRARY_DIR = /usr/home/MJ/Arduino/libraries/mj_midi
# "EXTRAINCDIRS" is a variable used by the base makefile. The base makefile creates a -I compiler flag for every item in the "EXTRAINCDIRS" list.
EXTRAINCDIRS = $(MY_OWN_LIBRARY_DIR)
# specify *.c source files pertaining to my project
SRC =
# specify *.cpp source files pertaining to my project
PSRC = temp.cpp $(MY_OWN_LIBRARY_DIR)/midi-listener.cpp $(MY_OWN_LIBRARY_DIR)/midi-song.cpp
# specify additional (non-core) Arduino libraries to include
ARDLIBS = SoftwareSerial
# include my base makefile
include /d/dev/avr/Makefile.base
Примечание. Если вы собираетесь использовать мой базовый make файл, убедитесь, что вы установили переменную ARDDIR
(которая появляется в верхней части файла), чтобы указать на каталог Arduino на вашем компьютере.