I have an Arduino Uno and a Linux environment. Though the Arduino IDE is great and all, however it doesn\'t give me much inputs if something goes wrong. And it also becomes excr
You might want to set the Arduino IDE compile options to verbose. Then compile something and watch the IDE's output. It will tell you where it locates the .cpp file and which compiler options it uses. Once you look into the .cpp file you see immediately what you need to include.
After that the makefiles become much easier to understand. If you have no prior experience with make my advice would be to avoid it and go for scons instead. Scons is written Python. Thus you immediately benefit from much simpler debugging.
I use a makefile for Arduino, which allows me to both user as well as system libraries. You don't have to use the Arduino IDE, but at the same time, can use the libraries that are provided by it.
undefined reference
The message undefined reference to 'xxxxxxxxx'
means that the linker can't find the actual definition (not just declaration) for the function in question.
When the linker can't find a definition for a function, that definition is typically to be found in a lib file (e.g *.so or *.dll) or in a source file (e.g. *.cpp or *.c). For your Arduino, you need to tell avr-gcc to compile and link the Arduino *.cpp files. You need all the source files from the Arduino core.
ARDCOREDIR = <my arduino folder>/hardware/arduino/cores/arduino
Sudar gave good advice, advocating the use of a Makefile for AVRs which is configured to include the Arduino function definitions. (I will link to mine and explain it below.)
In my makefile, I handled this operation as follows:
# CPP_SOURCE_FILES is a previously-defined variable, holding my project's source files
CPP_SOURCE_FILES += $(filter-out $(ARDCOREDIR)/main.cpp, $(wildcard $(ARDCOREDIR)/*.cpp))
Observe that I omitted the file main.cpp because the Arduino main.cpp file defines main()
, and I wish to define it myself in my own project files.
Of course, you must also pass avr-gcc an include flag for the arduino headers:
-I$(ARDCOREDIR)
And you must include the Ardhuino.h file in your actual project code:
#include <Arduino.h>
The Arduino.h header file will include all of the other Arduino header files, including the pinout file, which holds definitions for the Arduino pins. Different Arduinos must have different pinout files, so identify which type you are using, and tell avr-gcc to include the directory containing the appropriate pinout file. If you are using a standard Arduino (UNO), use the following:
-I$(ARDCOREDIR)/../../variants/standard
Not only does your build process need to implement the several instructions described above, it needs to know how to make the .hex file that shall be programmed onto your Arduino (or AVR). Therefore, it is a good idea to use a makefile.
I don't like to rebuild my makefile for each project, so I just have one base makefile on my machine, and each project has its own, very short makefile which calls include
to include the base makefile. You can find my base makefile here.
Example of a short (non-base) Makefile for a single project on my machine:
# 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
NB: If you're going to use my base makefile, make sure that you set the variable ARDDIR
(which appears near the top of the file) to point to the Arduino directory on your machine.