command line development in linux

Here's my Makefile. Well, not quite. I took a Makefile here (http://playground.arduino.cc/uploads/Learning/Makefile) but I didn't work for me. So I made the necessary adjustments. Your code will have to have the following "extras":

include "Arduino.h"
include "Servo.c" // or any other library

  1. function prototypes for all functions in your program.

Example:

#include "Arduino.h"
void setup();
void loop();

void setup() {
  pinMode(ledPin, OUTPUT);
}

void loop() {
}
PREFIX = PATH_TO_YOUR_ARDUINO_IDE_DIR
PORT = /dev/ttyACM0
# your program name minus the .cpp extension.
TARGET = YOUR_PROGRAM_NAME 
ARDUINO = $(PREFIX)/hardware/arduino/cores/arduino
ARDUINO_LIBS = $(PREFIX)/libraries
ARDUINO_INCL = $(PREFIX)/hardware/arduino/variants/standard $(wildcard $(ARDUINO_LIBS)/*)
ARDUINO_BIN = $PREFIX/hardware/tools/avr/bin
ARDUINO_TOOLS = $PREFIX/hardware/tools

VPATH=$(ARDUINO)

SRC = $(wildcard $(ARDUINO)/*.c)

# I had to include the Servo.cpp explicitly. If you use another library in addition, mention it here as well.
CXXSRC = $(TARGET).cpp $(wildcard $(ARDUINO)/*.cpp) $(ARDUINO_LIBS)/Servo/Servo.cpp

MCU = atmega328p
F_CPU = 16000000
FORMAT = ihex
UPLOAD_RATE = 19200

# Place -D or -U options here
CDEFS = -DF_CPU=$(F_CPU)
CXXDEFS = -DF_CPU=$(F_CPU)

# Place -I options here
CINCS = -I$(ARDUINO) $(foreach d, $(ARDUINO_INCL), -I$d)
CXXINCS = -I$(ARDUINO) $(foreach d, $(ARDUINO_INCL), -I$d)

CSTANDARD = 
CDEBUG = -g$(DEBUG)
CWARN = -Wall
CTUNING = -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums
CEXTRA = -Os -ffunction-sections -fdata-sections 
CXXEXTRA = -Os -fno-exceptions -ffunction-sections -fdata-sections 

CFLAGS = $(CDEFS) $(CINCS) -Os $(CWARN) $(CSTANDARD) $(CEXTRA)
CXXFLAGS = $(CDEFS) $(CINCS) $(CXXEXTRA)

# Programming support using avrdude. Settings and variables.
AVRDUDE_PROGRAMMER = arduino
AVRDUDE_PORT = $(PORT)
AVRDUDE_WRITE_FLASH = -U flash:w:$(TARGET).hex:i
AVRDUDE_FLAGS = -p$(MCU) -P$(AVRDUDE_PORT) -c$(AVRDUDE_PROGRAMMER) -b $(UPLOAD_RATE) -D $(AVRDUDE_WRITE_FLASH)

# Program settings
CC = $(ARDUINO_BIN)/avr-gcc
CXX = $(ARDUINO_BIN)/avr-g++
OBJCOPY = $(ARDUINO_BIN)/avr-objcopy
OBJDUMP = $(ARDUINO_BIN)/avr-objdump
SIZE = $(ARDUINO_BIN)/avr-size
NM = $(ARDUINO_BIN)/avr-nm
AVRDUDE = $(ARDUINO_TOOLS)/avrdude
REMOVE = rm -f
MV = mv -f

# Define all object files.
OBJ = $(SRC:.c=.c.o) $(CXXSRC:.cpp=.cpp.o) $(ASRC:.S=.o)

# Combine all necessary flags and optional flags.
# Add target processor to flags.
ALL_CFLAGS = -mmcu=$(MCU) -I. $(CFLAGS)
ALL_CXXFLAGS = -mmcu=$(MCU) -I. $(CXXFLAGS)

# Default target. Remove core.a before doing anything.
all: remove_core build

build: elf hex eep

elf: $(TARGET).elf
hex: $(TARGET).hex
eep: $(TARGET).eep

#$(AVRDUDE) -C$(ARDUINO_TOOLS)/avrdude.conf $(AVRDUDE_FLAGS)
# Program the device.  
upload: $(TARGET).hex $(TARGET).eep
	$(AVRDUDE) -C$(ARDUINO_TOOLS)/avrdude.conf -patmega328p -carduino -P/dev/ttyACM0 -b115200 -D -Uflash:w:$(TARGET).hex:i

.SUFFIXES: .elf .hex .eep .lss .sym

.elf.hex:
	$(OBJCOPY) -O $(FORMAT) -R .eeprom $(TARGET).elf $(TARGET).hex 

.elf.eep:
	-$(OBJCOPY) -j .eeprom --set-section-flags=.eeprom=alloc,load --change-section-lma .eeprom=0 -O $(FORMAT) $< $@

core: $(OBJ)
	$(ARDUINO_BIN)/avr-ar rcs core.a $?

# Link: create ELF output file from object files.
$(TARGET).elf: core
	$(CC) -Os -Wl,--gc-sections -mmcu=$(MCU) -o $(TARGET).elf core.a -lm 

# Compile: create object files from C++ source files.
%.cpp.o: %.cpp
	$(CXX) -c $(ALL_CFLAGS) $< -o $@

# Compile: create object files from C source files.
%.c.o: %.c
	$(CC) -c $(ALL_CXXFLAGS) $< -o $@

# Target: clean project.
clean:
	$(REMOVE) $(TARGET).hex $(TARGET).eep $(TARGET).cof $(TARGET).elf \
	$(OBJ) $(LST) $(SRC:.c=.s) $(SRC:.c=.d) $(CXXSRC:.cpp=.s) $(CXXSRC:.cpp=.d) \
	core.a

remove_core:
	$(REMOVE) core.a

.PHONY:	all build elf hex eep lss sym program clean remove_core