A few months ago I started playing with an Arduino UNO R2 board (yes, the flawed one, I had to solder a diode to convince the board to load sketches…). One of the machines I use for development is ARM based, so I couldn’t use the newest Arduino versions which are downloadable from the website, because  they are available only for 32 and 64 bit architectures. But the main reason for not using Arduino IDE is that I prefer vim or other IDEs to the one provided with Arduino package. Finding a working Makefile was not an easy job: I tried first to adapt the old Makefile I was using with the older Arduino codebase but it was clearly not compatibile, after having tried to adapt some other makefiles, finally I discovered a mostly working and very well written Makefile from http://ed.am/dev/make/arduino-mk, I had to patch it to support more configuration overrides and to fix the missing compilation of “c” source utilities from the Wire library. Meanwhile, I contacted Tim and he was independently fixing the same issues, after a few emails and tests we now have a wonderfull arduino Makefile: thanks Tim!

Advantages of the Makefile approach

Arduino IDE sucks. Ok, I admit it’s nice for beginners and for the click-and-forget kind of programmers, but it needs the full Java stack and hides to the user the fundamental steps involved in compiling and uploading programs to the arduino board. I (like many other software developers) prefer to understand what I’m doing and running a Makefile from the command line is the way to see the individual steps and choose which to run and when. Finally, I’m not going to drop my favourite editor just to write arduino programs. If your editor is vim, you will find this syntax highlighter useful: http://www.vim.org/scripts/script.php?script_id=2654.

Prepare your environment

There is nothing particular to do here, what you need is basically:
  1. the arduino libraries (source code)
  2. the Makefile
  3. the avr gcc compiler toolchain (the compiler and linker)
  4. avrdude (the program to speak with the MCU and upload the binaries)

Install arduino libraries

You can install the libraries with:
sudo apt-get install arduino
or dowload the latest version from here: http://arduino.cc/en/Main/Software (follow the source Luke: download the source tarball for Linux)
wget http://arduino.googlecode.com/files/arduino-1.0-src.tar.gz
tar -xzvf arduino-1.0-src.tar.gz

Get the Makefile

then grab the latest Makefile, put it in your sketchbook folder (the folder where your arduino programs are kept, create one if it does not exists, the folder name can be changed if you like):
mkdir sketchbook
cd sketchbook
wget http://ed.am/dev/make/arduino-mk/arduino.mk
ln -s arduino.mk Makefile
  You may prefer to use Makefile.edam.0.3.patched, which includes sketchbook/libraries folder. The Makefile configuration is normally very limited, you just tell the Makefile which board type you are using (e.g. “uno”) and, in a few cases, where are installed your arduino libraries. Except for the board type which cannot be guessed in any way,  the Makefile is smart enough to guess all other configuration parameters, which can be overriden setting environment variables for the need. In the case of manual source installation above, additional configuration would be:
echo "export ARDUINODIR=~/arduino-1.0" >> ~/.bashrc
echo "export BOARD=uno" >> ~/.bashrc
source ~/.bashrc
An important convention is that the program you are going to compile resides in a folder with the same name, see the examples below.

Install the gcc AVR compiler and avrdude

If you have installed arduino with apt-get you have already installed the compiler and avrdude, if you have downloaded the sources, you need to install the compiler and avrdude with:
sudo apt-get install avrdude binutils-avr gcc-avr avr-libc gdb-avr

Test sketch

The steps are:
  • create a directory with the same name of the sketch, this must be a subdirectory of the the sketchbook directory you have created above
  • create the sketch with your favourite editor and save into the directory, the name must be the same, file extension  can be “.ino” or “.pde”
  • connect your board to the USB plug
  • compile and upload (in one step)
cd ~/sketchbook
mkdir blink
cd blink
echo "void setup(){pinMode(13,OUTPUT);}void loop(){digitalWrite(13,HIGH);delay(1000);digitalWrite(13,LOW);delay(1000);}" > blink.ino
make -f ../Makefile
That’s all!

21 Responses to “Arduino 1.0 development with a makefile on Linux”

  • Andreas

    Super tutorial – just what I needed. I tried the procedure above and everything works perfectly!

    Thanks a lot!


  • Bill

    I wonder, how can I change it to include libraries in a specified folder (under sketchbook/libraries) apart from the default ones?

  • Alessandro Pasotti


    I’ve patched the makefile to include sketchbook/libraries and sent it to Tim (the original author), but I didn’t get a relpy yet.

    I’m attaching the new version to the post above.

    You may need to adjust the paths (tested under Ubuntu LTS).

  • Bill

    Alessandro it works right out of the box (just changed the symlink in my system).

    Thank you very much.

    ps: I suggest this gets stored in the arduino playground so that people find it more easily 🙂

  • Andreas Kring


    The procedures in the article above used work out for me fine, but now I run into trouble (i.e. nothing happens (on the Arduino) when I run “make -f ../Makefile” from the blink folder) when follow the steps described (I have just switched from Ubuntu 10.04 LTS to Ubuntu 12.04 LTS).

    Everything works fine when I use the standard Arduino IDE.

    I did not add “export ARDUINODIR=~/arduino-1.0” to ~/.bashrc (do I have to do this when I installed the arduino package using $ apt-get install arduino?)

    When I run “make -f ../Makefile”, I get the following output in the terminal:

    mkdir -p .dep/./
    /usr/bin/avr-g++ -Os -Wall -fno-exceptions -ffunction-sections -fdata-sections -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -mmcu=atmega328p -DF_CPU=16000000L -DARDUINO=100 -DUSB_VID= -DUSB_PID= -I. -Iutil -Iutility -I /usr/share/arduino/hardware/arduino/cores/arduino -I /usr/share/arduino/hardware/arduino/variants/standard/ -c -MMD -MP -MF .dep/Blink.ino.dep -o Blink.o -x c++ -include /usr/share/arduino/hardware/arduino/cores/arduino/Arduino.h Blink.ino
    /usr/bin/avr-gcc -Os -Wl,–gc-sections -mmcu=atmega328p Blink.o .lib/arduino.a -lm -o Blink.elf
    /usr/bin/avr-objcopy -O ihex -R .eeprom Blink.elf Blink.hex
    rm Blink.elf

    Any ideas on what can be the problem?

    Best regards

  • Alessandro Pasotti

    Hi, Andreas,

    there is nothing wrong in your output, just type:

    make -f ../Makefile upload

    and the binary .hex will be uploaded to your Arduino.

    It’s a two step procedure, but you can easily modify the make file to do everything in a single step if you want.

  • Andreas Kring

    Hi, Alessandro.

    Ok, thanks a lot – that explains it.
    Thanks for the fast reply.

    Best regards

  • Ilya

    Thanks so much!
    I doing some wrong,I get also this mesage when I trying make -f

    ../Makefile:169: *** ARDUINODIR is not set correctly; arduino software not found. Stop.

    what I did wrong?
    Thank you!

  • Jeane

    Thanks so much for the Makefile.

    I am getting a: “Makefile:328: *** missing separator. Stop.”
    Don’t know why?
    Any guess?


  • Fotis

    Looks like the community loves your solution! Is there a way to know whether the makefile does exactly the same things with the Arduino IDE “verify” button (including the preprocesing, generating function prototypes, etc)?

    Thanks a lot!!

  • Alessandro Pasotti


    there are no function prototypes in the Makefile, the only thing the Makefile does under the hood is to include Arduino.h (I wouldn’t call this pre-processing though).

    BTW this is seldom a problem, on the contrary, I believe that this forces the user to write correct C/C++ code, I personally hated the way Arduino team advertised the “Arduino Programming Language” as a self-standing entity, as a software developer, at first I thought it was a real new programming language not just plain old C without prototypes.

    Also, as explained in the post, I’m not the author of the Makefile and there are many more Makefiles in the net. It seems like I’m not the only IDE-hater out there 🙂


  1.  Programming an Arduino from the command line with Linux | OpenForce.dk