Arduino bundle for TextMate

This is pretty much was David was proposing.

When working on pure avr-gcc projects (off arduino goodness), I simply hit Comand-R (r like in run) and textmate starts executing the makefile which is living in the same folder.
David once also released a makfile for arduino! See http://www.arduino.cc/en/Hacking/CommandLine
EDIT: @xSmurf: oops! I just see you allready found the makfile... I missed your edit in the second post. I leave the link here as a reference.

But somewhere on the forum I think I've read, the arduino makefile is now somehow out of date ....
I haven't tested it since the 0007 release. I only know that within the current arduino IDE there's no makefile beeing used besides java to compile everything.

@david
a comandline preprocessing java for arduino code would be gorgeous. Could you still keep the actuall compiling step in a makefile? I think it's a nice standard.
As everything is still avr-gcc/libc compatible so far, it would be just convenient to stay compatible with a standardised compiling scheme. Have you heard of www.cmake.org? It looks like they try to avoid plattform specific issues like you reported with make in first arduino releases.

A textmate bundle could just issue the java preprocessing comand with a dedicated preferences.txt and then start (c)make...

Oli

last edited: [timestamp=1188259247]

I tried using the makefile from 0009 and I modified the path and it built without any issue as far as I could see. As for upload, I modified the avrdude command a little and I get this

/Users/mlalonde/Applications/Development/Arduino/arduino-0009/tools/avr/bin/avrdude -C /Users/mlalonde/Applications/Development/Arduino/arduino-0009/tools/avr/etc/avrdude.conf -F -p atmega168 -P /dev/tty.usbserial* -c stk500 -b 19200 -U flash:w:ntsc.hex
avrdude: stk500_getsync(): not in sync: resp=0x30
avrdude: stk500_2_ReceiveMessage(): timeout

If the Makefiles become a reliable way of building outside the IDE, I'm not sure there is a real need for a command line tool.

Ok, forgett what I said about cmake. It's just another beast as automake/autoconfig...

xSmurf, your' right. We actualy don't need a java comand line when a proper makefile exists.

Last night I decided not to sleep and came up with this:

  • An improved makefile, which features the same auto reset feature which the arduino IDE does on Diecimila boards. I found out, that avrdude supports to toggle the DTR line... :slight_smile:
  • The Makefile also allows to compile and work with standard .pde files directly. I does automatic preprocessing by simple shell commands. No additions to standard .pde files are needed... at least with led_blink works like a charm! :wink:
  • I made a small addition to textmate's standard Makefile Bundle. You have now command-R for compiling and command-U for upload. Just as in the Arduino IDE.
  • I upgraded an old Arduino Extreme V2 (atmega8 board) to auto-reset itself from the serial port, just like Diecimila boards can. It's very easy but usefull and described in the makefile.

But there are also some things that need additional work and thoughts:

  • As I compile and "preprocess" (this word is really to much for what happens in the makefile :slight_smile: the .pde into a .cpp file, errors that arouse from compiling do refer to that new file. So if you click on an error in the nice Textmate info window, you will be redirected to this file, instead of your .pde file, where you actually wan't to code.
  • The Textmate info windows show output of compiling and uploading only at the end of each process. It would be nice to see everything right when it happens...
  • I couldn't test to include additional .c files. Should it be enough to have .h header files included at the top in the .pde (just like in the Arduino IDE)? Or does the makefile need extra knowledge. Probably putting the extra .c files in $SRC?
  • things I missed so far...

Here's the makefile and the extended TextMate Bundle:
http://rapidshare.com/files/51829818/Arduino_Makfile_Textmate_Bundle.zip.html

I hope some find this usefull. I enjoy using it! :slight_smile: Esp. with auto-reset, the programming is so amazing fast.

Regarding TextMate shortcut keys: Besides CMD-U and CMD-R remember CMD-W to close the compile and upload info windows. Also CMD-< and CMD-> is handy to cycle between all open TextMate windows.

cheers,
Oli

Wow, very nice.

I had no idea that avrdude supported the reset automatically either (right now I'm doing it manually before calling avrdude). That's awesome, I'll have to try to incorporate it into the next version.

Do you mind if I include this, or a variant of it, in the next Arduino release?

Also, there is one more preprocessing step that the Arduino environment does, which is to automatically generate prototypes for your functions. It's a small thing, but it might sketches slightly incompatible between the Makefile and environment.

hi mellis,

of corse you can do with it what you want. It's anyway just a patchwork between different makfiles I found.
You mean, there could be a problem if people don't create a protoype of a self written function before calling their function? I'm shure there is some regular expression for this... how do you filter the protoypes in java? Do you compare against a list of core funcions?

BTW: I think there is an error in the original makefile in targets/arduino:
I think the line that starts with "$(TARGET).elf:" should also depend on $(TARGET).cpp (in my Makefile it is
$(TARGET).pde). Othwerise it didn't recompile on my system if I changed something in $(TAGET).cpp.

Re: avrdude reset. This was a funny discovery. I saw the reset definition for serial bitbangers and thought "hmmm, wait a minute..." ;). The reset line is held low during the whole upload process. Thats OK, when we use a capacitor for the connection just as in the Diecimila boards.
I tested is also with another - rather unusual - usb-serial converter from Silabs (CP2102). It works niceley! So this shouldn't depend on FDTI or other converters.

oli

The automatic prototype generation works with a simple regular expression to try to detect function definitions, and then just ignores setup() and loop(). It doesn't work all that well (it gets confused if your return type is multiple words like "unsigned int" or is on a different line than the rest of your function header). Still, it's been okay for most things.

In fact, here it is: ^(\w+)\s+(\w+)\s*\(([^)]*)\)\s*{

There is cproto (http://cproto.sourceforge.net/) which will generate prototypes for you.
I guess you COULD create a makefile that would do all that the arduino program does. You'd have rules like:

%.cpph: &.cpp
   cproto %.cpp >%.cpph

%.elf: %.cpp %.cpph 
    $(GCC) -I$(ARDUINOINC)/prefix.h -I%.cpph %.cpp ...

(that's probably WAY wrong. I HATE makefiles. make is a lovely example of a 1970s program that should have been replaced long ago instead of patching it to handle modern circumstances. A good percentage of Arduinos goodness probably comes from letting the user never have to deal with makefiles!)

@westfw
Well i'm not after a substitution of the current java compile with a makefile. I just like to keep an alternative, when not working with the IDE.
It's not that I like makefiles, but for microcontroller programming is still not too hard to use it - IMHO.
Although I frequently forget important makefile knowledge... :slight_smile:
Speaking of it, i think there is a dependency erro in my makefile. Did anybody try it?

Cproto is interesting, thanks! Maybe mellis will use it in the IDE?
But as long as it's not a standard install on unix systems I wouldn't want to use it in a makefile.

On the other hand I think using a makefile, even if it's only in the background of an IDE, is a better standard than doing some custom java-based compile process in the IDE, like it's now. Esp. for maintainance between different IDE versions a certain compile standard could be better...

Of coruse, I agree that the Ardunio goodness comes with the current software and IDE!
But I think it's also good, that the Ardunio IDE doesn't allow too much simplification of C code.
I think the current state of preprocessing is a perfect compromise.
I hope it won't walk away any further from standard avr-gcc C code. Incorporating an alternative language than C, though, would be again a different question. E.g. ruby arduino developement: http://rad.rubyforge.org/

Using Makefiles as a backend from the IDE sounds good, but it was a nightmare in practice (we did it in the original versions of Arduino). Especially on Windows, it was impossible to get working consistently - some machines seemed to want / as the path separator, some wanted \ and some wanted \. We had to maintain multiple slightly different makefile version.

It was also difficult for people to make changes to the build process, because they'd get thrown by the common Makefile problem (like using spaces instead of tabs, etc.) Now, with the preferences file, there aren't many things you can change, but they are relatively easy. We could just pass all the variables on to the makefiles, but at this point there are some decisions being made that we be a pain to replicate in makefiles.

I kind of like the idea that the IDE does it's own thing, but we also provide a Makefile for people who want one.

It would be good to have a better way to generate function prototypes, but it's also a hassle to include another program, and so far, the current method seems to be "good enough".

Of course, these are all interesting ideas, and I appreciate the discussion.

I fully understand this. Maybe cmake is worth a try... Though cmake would add many more MBs.

I forgot one thing that's really great about using a makefile now:
You can have your preferences saved with the projects.
E.g. on some boards you prefer to use the bootloader while with others you're setup requires an AVRISP MKII - in any case you just set it once. Esp. ATmega8 vs. ATmega168 switching becomes obsolete! I guess some catch this problem often nowadays when having diecimila and older boards around at the same time. Also you can have different clock speeds and baudrates without changing preferences everytime you switch projects etc...

Yes, this is rather advanced stuff, but it's nice beeing still able to do it with a makefile - just as you said, david. I agree, as long as prototype creation works most of the time, better don't touch it...

It's not that I like makefiles, but for microcontroller programming is still not too hard to use it

I guess it doesn't start to really fall apart till you get a couple thousand source files! :slight_smile: :frowning: :cry:

Still, I think I'd prefer a way to invoke Arduino as a command like utility to build a sketch, instead of creating two ways to build the sketch. I don't know how hard this is in a multi-os java app. EAGLE (the PCB editor) does it in the linux and macos versions, but needs a separate exe for windows...

xSmurf, could you upload the textmate bundle somewhere? I am still in the evalutation period of textmate but it seems asa very good editor to me. Finally leaving vim behind me. (outside a terminal that is)
I just started using the arduino programmer as described on tinker.it. I expected that this programmer with textmate will make programming a lot easier.

I tried to compile LCD4bitexample (from the playground) with the makefile from Oliver. But there are some errors:

applet/LCD4BitExample.cpp:4:21: error: LCD4Bit.h: No such file or directory
applet/LCD4BitExample.cpp:7: error: 'LCD4Bit' does not name a type
applet/LCD4BitExample.cpp: In function 'void setup()':
applet/LCD4BitExample.cpp:16: error: 'lcd' was not declared in this scope
applet/LCD4BitExample.cpp: In function 'void loop()':
applet/LCD4BitExample.cpp:28: error: 'lcd' was not declared in this scope
make: *** [applet/LCD4BitExample.elf] Error 1

It seems that LCD4Bit.h can not be found. What do I have to change so it will be found? I expect that all additional libraries will not be found.

For a quick "hack" you need to add LCD4Bit.cpp to the CXXSRC variable in the makefile.
Then in the .pde it must read #include "LCD4Bit.h" (no < >) to reference the lib as a local file. The last step is to put the LCD4Bit.h/.cpp in the same directory as the makefile and the .pde. Then it compiles - at least in my case. :wink:

I'm still searching for a nice setup, to include the arduino libs nicely in the makefile. Can anybody help?
When it's more polished I'll hopefully find time to do a Playground entry.

For a quick "hack" you need to add LCD4Bit.cpp to the CXXSRC variable in the makefile.
Then in the .pde it must read #include "LCD4Bit.h" (no < >) to reference the lib as a local file. The last step is to put the LCD4Bit.h/.cpp in the same directory as the makefile and the .pde. Then it compiles - at least in my case. :wink:

I see, but this is going to a mess after a while. If I change something in the LCD4Bit.cpp, where do I change it? I assume this has to be local, in the directory where the pde is? If you start a new program with the modified library you have to copy the library files to the new program directory.

You are right, but this is no limitation of makefiles. It's only a question of proper usage. We need to use the -I switches for includes right but I forgot how it's done...

regarding your improved upload process: keep in mind you can allways change preferences.txt if you wan't to change the upload programmer. So there's no need to skip the Arduino IDE only to use a different programmer.

Slowly it is all coming back, -I, I can recall that, from a very long time ago.

I added an arduinolibs parameter, so, that is a bit easier to add, for instance:

CXXSRC = $(ARDUINO)/HardwareSerial.cpp $(ARDUINO)/WRandom.cpp $(ARDUINOLIBS)/LCD4Bit/LCD4Bit.cpp

And I made a symbolic link to LCD4Bit.h in the sketch directory. After that I changed the avrdude config to work with my programmer. Now it works perfectly. So, command-R and command-U work, this is very nice for lots of uploads, it works very quick.

Yeah, it's really quick. I'm happy someone else also finds it usefull!

If you add -I$(ARDUINOLIBS)/LCD4Bit to CXXINCS it should recognize the lib w/o a symbolic link. But I think you need to write again in #include <LCD4Bit.h> (with <>).

There must be a nice way to include all libraries from "/lib/target/librariers" without explicitly menitioning them. Similar like in the line that starts with "@for i in $(OBJ)". This is real makefile science...

The current "command line" instructions mention installing "real" avr-gcc. If you've already installed arduino to get the libraries and source modules needed, you already have a copy of avr-gcc that's certainly complete enough to compile arduino sketches, and the makefile can make that invisible to the users. I have (in the makefile from the wiki):

# Program settings
CC =  /Downloads/arduino-0008/tools/avr/bin/avr-gcc
CXX = /Downloads/arduino-0008/tools/avr/bin/avr-g++
OBJCOPY = /Downloads/arduino-0008/tools/avr/bin/avr-objcopy
OBJDUMP = /Downloads/arduino-0008/tools/avr/bin/avr-objdump
SIZE = /Downloads/arduino-0008/tools/avr/bin/avr-size
NM = /Downloads/arduino-0008/tools/avr/bin/avr-nm
AVRDUDE = /Downloads/arduino-0008/tools/avr/bin/avrdude