Build Process

bperrybap edited this page May 1, 2018 · 11 revisions

The process the Arduino environment uses to build a sketch. More useful information can be found in the Arduino IDE 1.5 3rd party Hardware specification. Note that the following refers specifically to the build process for AVR targets. Other architectures will have a similar build process.

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. 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:

  • All .ino files in the sketch folder (shown in the IDE as tabs with no extension) are concatenated together, starting with the file that matches the folder name followed by the others in alphabetical order, and the .cpp extension is added to the filename.
  • If not already present, #include <Arduino.h> is added to the sketch. This header file (found in the core folder for the currently selected board) includes all the definitions needed for the standard Arduino core.
  • Prototypes are generated for all function definitions in .ino files that don't already have prototypes. In some rare cases prototype generation may fail for some functions. To work around this, you can provide your own prototypes for these functions.
  • #line directives are added to make warning or error messages reflect the original sketch layout.

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.

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).

The .c and .cpp files of the target are compiled and output with .o extensions to this directory, as is the main sketch file and any other .c or .cpp files in the sketch and any .c or .cpp files in any libraries which are #included in the sketch.

Before compiling each .c or .cpp file, an attempt is made to reuse the previously compiled .o file, which speeds up the build process. A special .d (dependency) file provides a list of all other files included by the source. The compile step is skipped if the .o and .d files exist and have timestamps newer than the source and all the dependent files. If the source or any dependent file has been modified, or any error occurs verifying the files, the compiler is run normally, writing a new .o & .d file. After a new board is selected from the Tools menu, all .c and .cpp files are rebuilt on the next compile.

These .o files are then linked together into a static library and the main sketch file is linked against this library. Only the parts of the library needed for your sketch are included in the final .hex file, reducing the size of most sketches.

The .hex file is the final output of the compilation which is then uploaded to the board.

If verbose output during compilation is checked in the Preferences dialog, the complete command line of each external command executed as part of the build process will be printed in the editor console.

Uploading

Sketches are uploaded by avrdude. The upload process is also controlled by variables in the boards and main preferences files. See the Arduino IDE 1.5 3rd party Hardware specification page for details.

If verbose output during upload is checked in the Preferences dialog, debugging information will be output to the editor console, including avrdude command lines and verbose output.