Overview
A number of things have to happen for your Arduino code to get onto the Arduino board. First, the Arduino environment performs some minor pre-processing to turn your sketch into a C++ program. Next, dependencies of the sketch are located. It then gets passed to a compiler (avr-gcc), which turns the human readable code into machine readable instructions (or object files). Then your code gets combined with (linked against),) the standard Arduino libraries that provide basic functions like digitalWrite()
or Serial.print()
. The result is a single Intel hex file, which contains the specific bytes that need to be written to the program memory of the chip on the Arduino board. This file is then uploaded to the board: transmitted over the USB or serial connection via the bootloader already on the chip or with external programming hardware.
Pre-Processing
The Arduino environment performs a few transformations to your sketch before passing it to the avr-gcc compiler:
No pre-processing is done to files in a sketch with any extension other than .ino. Additionally, .h files in the sketch are not automatically #included from the main sketch file. Further, if you want to call functions defined in a .c file from a .cpp file (like one generated from your sketch), you'll need to wrap its declarations in an 'extern "C" {}' block that is defined only inside of C++ files.
Dependency Resolution
The sketch is scanned recursively for dependencies. There are predefined include search paths:
- Core library folder (as defined by
{build.core}
) - Variant folder (as defined by
{build.variant}
) - Standard system directories (e.g.,
{runtime.tools.avr-gcc.path}/avr/include
)
If the dependency is not present in any of those locations, the installed libraries are then searched (see the Location Priority table below for library locations). For information on the allowed library sub-folder structures see https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#source-code. -I
options are generated for the path to each library dependency and appended to the includes
property, to be used in compilation recipes in platform.txt.
If multiple libraries contain a file that matches the #include
directive, the priority is determined by applying the following rules, one by one in this order, until a rule determines a winner:
- A library that is architecture optimized or compatible wins against a library that is not architecture compatible (see Architecture Matching)
- A library that has better "folder name priority" wins (see Folder Name Priority)
- A library that is architecture optimized wins against a library that is architecture compatible (see Architecture Matching)
- A library that has a better "location priority" wins (see Location Priority)
- A library that has a folder name with a better score using the "closest-match" algorithm wins
- A library that has a folder name that comes first in alphanumeric order wins
Architecture Matching
A library is considered compatible with architecture X
if the architectures
field in library.properties:
- explicitly contains the architecture
X
- contains the catch-all
*
- is not specified at all.
A library is considered optimized for architecture X
only if the architectures
field in library.properties explicitly contains the architecture X
.
Examples:
architectures field in library.properties
| Compatible with avr
| Optimized for avr
|
---|---|---|
not specified | YES | NO |
architectures=* | YES | NO |
architectures=avr | YES | YES |
architectures=*,avr | YES | YES |
architectures=*,esp8266 | YES | NO |
architectures=avr,esp8266 | YES | YES |
architectures=samd | NO | NO |
Folder Name Priority
The "folder name priority" is determined as follows (in order of highest to lowest priority):
Rule | Example for Servo.h
|
---|---|
The folder name matches the include 100% | Servo |
The folder name matches the include 100%, except with a -master suffix | Servo-master |
The folder name has a matching prefix | ServoWhatever |
The folder name has a matching suffix | AwesomeServo |
The folder name contains the include | AnAwesomeServoForWhatever |
Location Priority
The "location priority" is determined as follows (in order of highest to lowest priority):
- The library is in the sketchbook (
{sketchbook path}/libraries
) - The library is bundled with the board platform/core (
{runtime.platform.path}/libraries
) - The library is bundled with the referenced board platform/core
- The library is bundled with the IDE (
{runtime.ide.path}/libraries
)
Compilation
Sketches are compiled by avr-gcc and avr-g++ according to the variables in the boards.txt file of the selected board's platform.
The include path includes:
- The board's variant folder (as specified by the
build.variant
property in boards.txt for the selected board) - The core folder (as specified by the
build.core
property in boards.txt for the selected board) - The avr include directory (
hardware/tools/avr/avr/include/
) -
libraries/{librarydir}
sub-folder of the Arduino IDE installation folder where library lives -
libraries/{librarydir}
sub-folder of the hardware package of the currently selected board where library lives -
libraries/{librarydir}
sub-folder of the sketchbook where library lives
For information on the allowed library sub-folder structure see https://github.com/arduino/Arduino/wiki/Arduino-IDE-1.5:-Library-specification#source-code.
The sketch is built in a temporary directory in the system-wide temporary directory (e.g. /tmp on Linux).