make your Arduino 0007 sketch smaller!

Announcing a new version of the library patch that makes your Arduino sketches smaller. If you are running out of room in your sketch, and you want to squeeze in more of your own code, this may be just the thing you need:

http://www.arduino.cc/playground/Code/LibPatch0007

Using this patch, I was able to make one of my own sketches go from 6986 bytes (using official Arduino 0007 distribution) to 4806 bytes!

Please note that this patch is not compatible with the command-line build process; please use this only if you are using the Arduino IDE to build your sketches. Also, it has only been tested so far on my Windows machine. If you follow the instructions carefully, you can easily uninstall this patch if it breaks your stuff. But I need brave souls to help me test this for Linux and Mac.

Please post any bug reports, questions, and suggestions to this forum topic... thank you!

  • Don Cross

I don't know if it was even considered in the design of the patch, but I'm running Arduino with an ATMega168, and I get the error:

/Applications/arduino-0007/tools/avr/bin/../lib/gcc/avr/4.0.3/../../../../avr/lib/avr5/crtm168.o: In function `__bad_interrupt':

../../../../crt1/gcrt1.S:123: undefined reference to `main'

Couldn't determine program size: tools/avr/bin/avr-size: '/tmp/build38608.tmp/led_blink.hex': No such file

when I try to compile. Is it possible to use this patch for the ATMega168, and are there any other ways to eliminate 1 KB in Arduino0007?
Thanks in advance,

Fred

Hmmm... I just tried compiling for Atmega168 on my own machine and everything works fine. Can you tell me...

  • What operating system you are using?
  • Are you using the Arduino GUI or the makefile?
  • Is it possible to post a recursive directory listing of your Arduino install root?

Thanks for the response,

I'm using Mac OS 10.4.8, and I am using the Arduino GUI for everything.
Here is the directory listing. To install it, I moved the processing directory to /lib/processing and I replaced the /lib/targets/arduino folder with the provided one.

Freds-Computer:/Applications/arduino-0007/lib fred$ ls -R 
about.jpg               processing              tab-unsel-left.gif
buttons.gif             resize.gif              tab-unsel-menu.gif
icon.gif                tab-sel-left.gif        tab-unsel-mid.gif
keywords.txt            tab-sel-menu.gif        tab-unsel-right.gif
loading.gif             tab-sel-mid.gif         targets
preferences.txt         tab-sel-right.gif

./processing:
app

./processing/app:
Compiler.class  Compiler.java   preproc

./processing/app/preproc:
PdePreprocessor.class   PdePreprocessor.java

./targets:
arduino         atmega8         blank           libraries       wiring

./targets/arduino:
HardwareSerial.cpp      WRandom.cpp             wiring_analog.c
HardwareSerial.h        binary.h                wiring_digital.c
Makefile                main.cxx                wiring_private.h
WConstants.h            pins_arduino.c          wiring_pulse.c
WInterrupts.c           wiring.c                wiring_serial.c
WProgram.h              wiring.h                wiring_shift.c

./targets/atmega8:
pins_atmega8.c

./targets/blank:
WProgram.h

./targets/libraries:
Matrix          SHT_Library     SoftwareSerial  Sprite          Wire

./targets/libraries/Matrix:
Matrix.cpp      Matrix.h        Matrix.o        examples        keywords.txt

./targets/libraries/Matrix/examples:
hello_matrix            sprite_animation

./targets/libraries/Matrix/examples/hello_matrix:
hello_matrix.pde

./targets/libraries/Matrix/examples/sprite_animation:
sprite_animation.pde

./targets/libraries/SHT_Library:
SHT_Library.cpp SHT_Library.h   SHT_Library.o

./targets/libraries/SoftwareSerial:
SoftwareSerial.cpp      SoftwareSerial.o        keywords.txt
SoftwareSerial.h        examples

./targets/libraries/SoftwareSerial/examples:

./targets/libraries/Sprite:
Sprite.cpp      Sprite.h        Sprite.o        binary.h        keywords.txt

./targets/libraries/Wire:
Wire.cpp        Wire.o          keywords.txt
Wire.h          examples        utility

./targets/libraries/Wire/examples:
SFRRanger_reader        master_reader           slave_receiver
digital_potentiometer   master_writer           slave_sender

./targets/libraries/Wire/examples/SFRRanger_reader:
SFRRanger_reader.pde    applet

./targets/libraries/Wire/examples/SFRRanger_reader/applet:
HardwareSerial.cpp.o    SFRRanger_reader.hex    WRandom.cpp.o
SFRRanger_reader.cpp    SFRRanger_reader.pde    pins_arduino.c.o
SFRRanger_reader.cpp.o  SFRRanger_reader.rom    wiring.c.o
SFRRanger_reader.elf    WInterrupts.c.o

./targets/libraries/Wire/examples/digital_potentiometer:
digital_potentiometer.pde

./targets/libraries/Wire/examples/master_reader:
master_reader.pde

./targets/libraries/Wire/examples/master_writer:
master_writer.pde

./targets/libraries/Wire/examples/slave_receiver:
slave_receiver.pde

./targets/libraries/Wire/examples/slave_sender:
slave_sender.pde

./targets/libraries/Wire/utility:
twi.c   twi.h   twi.o

./targets/wiring:
Binary.h                QSlide.o                WProgram.h
Encoder.h               Servo.h                 WRandom.o
Encoder.o               Servo.o                 WTimer.o
HardwareSerial.h        Sprite.h                buffer.h
HardwareSerial.o        Sprite.o                buffer.o
LiquidCrystal.h         TwoWire.h               twi.h
LiquidCrystal.o         TwoWire.o               twi.o
Matrix.h                WApplet.o               uart.h
Matrix.o                WConstants.h            uart.o
QSlide.h                WInterrupts.o

Thanks,
Fred

Hello again Fred,

One thing the library patch relies on is that installing the files Compiler.class and PdePreprocessor.class should override the classes inside the supplied jar file. Maybe for some reason this is not the case in the Macintosh environment? Here is one thing to check: Go into the directory where the failed compile takes place (e.g. /tmp/build38608.tmp/, whatever it says in the error message), and look at the file led_blink.cpp. At the very bottom of that file, you should see the following:

/*
    main.cxx  -  Startup code for Arduino, slurped in at last moment by Arduino preprocessor.
    Split out from wiring.c by Don Cross (CosineKitty on the Arduino forums).
    We give this the funny extension .cxx so that source code editors can recognize it as
    C++ code (for syntax highlighting, etc.), but not .c or .cpp, so that it is excluded
    from the list of files to be compiled into a library.
*/

int main(void)
{
    init();         // initialize hardware and data structures for runtime library

    setup();        // call user-defined setup routine
    
    for (;;)
        loop();     // keep calling user-defined loop routine forever
        
    return 0;       // we never get here, but make the compiler happy about main returning int
}

The fact that the linker says that it could not find main() makes me suspect that this code has not been appended properly to your sketch. This is the job of PdePreprocessor.class. I suspect that you are still running the original Arduino 0007 preprocessor, not the patched replacement.

Is there anyone out there that understands better how the Arduino Java code works on Macintosh?

The fact that the linker says that it could not find main() makes me suspect that this code has not been appended properly to your sketch. This is the job of PdePreprocessor.class. I suspect that you are still running the original Arduino 0007 preprocessor, not the patched replacement.

Is there anyone out there that understands better how the Arduino Java code works on Macintosh?

I'm getting the same error... This seems like a worthwhile patch... if anyone has any insight on this... It would be appreciated.

You probably need to open up the pde.jar in the Arduino.app file (right click on it and select show package contents), then replace the appropriate .class files. I don't think the lib directory is in the classpath on the Mac.

OK everyone, I am trying out Mellis's idea: I updated the pde.jar file with the 3 classes I modified (Compiler, PdePreprocessor, Sizer). Please help me test this on Macintosh. Here is how:

(Note: these instructions assume you already have the library patch installed!)

  1. Exit Arduino GUI if running.
  2. Go into your Arduino 0007 install path, then into its "lib" directory.
  3. Rename pde.jar to pde.jar.original (for safe keeping).
  4. Download the replacement pde.jar (773 K) from:

http://cosinekitty.com/pde.jar

  1. Go back into Arduino GUI and try compiling again. Please post results of experiment here.

If this works, I will update the library patch for everyone to use.

Thanks for helping this poor Mac-less person!

  • Don

Can't find pde.jar in my installation (Arduino 7 for Mac OS X 10.4.8 PPC, downloaded about 5 minutes ago):

imac:/Applications/arduino-0007 jdw$ find . -name *.jar -print
./Arduino 07.app/Contents/Resources/Java/antlr.jar
./Arduino 07.app/Contents/Resources/Java/Arduino.jar
./Arduino 07.app/Contents/Resources/Java/mrj.jar
./Arduino 07.app/Contents/Resources/Java/oro.jar
./Arduino 07.app/Contents/Resources/Java/registry.jar
./Arduino 07.app/Contents/Resources/Java/RXTXcomm.jar
imac:/Applications/arduino-0007 jdw$

At a glance, it looks like your pde.jar has most of the same components as Arduino.jar and then some, but they are not identical.

imac:~ jdw$ jar tf /Applications/arduino-0007/Arduino\ 07.app/Contents/Resources/Java/Arduino.jar  | sort >a.j 
imac:~ jdw$ jar tf pde.jar | sort >p.j
imac:~ jdw$ diff a.j p.j
1,2d0
< META-INF/
< META-INF/MANIFEST.MF
4a3,7
> arduino/
> arduino/app/
> arduino/app/preproc/
> arduino/app/syntax/
> arduino/app/tools/
6a10
> processing/app/ArduinoMessageSiphon.class
9a14
> processing/app/Command.class
imac:~ jdw$

Looked pretty close, so I tried it anyway, renaming your pde.jar to Arduino.jar. When I compile, I get:

2: error: #error Arduino preprocessor could not open file lib/targets/arduino/main.cxx

Thanks for helping this poor Mac-less person!

I always try to help the less fortunate. :slight_smile: Especially when they're trying to do me a favor.

-j

same here... no pde.jar to be found :frowning:

the contents of my app are:

antlr.jar
Arduino.jar
mrj.jar
oro.jar
registry.jar
RXTXcomm.jar

Whoops. I meant Arduino.jar not pde.jar. I don't know why it didn't work when you tried renaming it. In any case, this patch will be incorporated into the next release of Arduino.

Just for grins I installed pde.jar on a Windows machine at work. Same results - compile dies with the same message.

-j

Please note that pde.jar on Windows is not sufficient (or even necessary). There are several components to this library patch, including modifications to the runtime source code in addition to the Java code changes. On Windows, please ignore this jar stuff for the time being: just follow the instructions at:

http://www.arduino.cc/playground/Code/LibPatch0007

The Macintosh problem is going to require some more thought on my part. Specifically (Mellis are you reading?) I need to figure a way to access the fully qualified path to the Arduino installation from inside the PdePreprocessor class. I was hoping that what worked on Windows (using relative path name) would also work on Macintosh, but apparently it doesn't.

Dunno, maybe you can incorporate the changes I made when I integrated it into the Arduino svn? Or just wait until 0008 comes out?

Thanks for the quick reply Mellis! I just looked at your version of the changes and I just now realized you do seem to have solved the Macintosh problem: your code passes the target directory to PdePreprocessor.writeFooter(). Too bad I didn't notice that before now! ::slight_smile:

Anyway, I'm working on integrating your Java code back into my library patch now. I will post again here as soon as I have something ready for the Macintosh people to try again.

  • Don

NOTE: This thread continues on another page:
http://www.arduino.cc/cgi-bin/yabb2/YaBB.pl?num=1167935232/16
I have now posted a new jar file for Macintosh users!

OK, this time I'm feeling lucky! Here is a new jar file to try on Macintosh, assuming you have already installed the library patch (again, this WILL NOT WORK by itself... you have to have the other files installed, using the link from the very first post to this thread!):

http://cosinekitty.com/Arduino.jar

Let me know how it works by posting back here.

  • Don

assuming you have already installed the library patch (again, this WILL NOT WORK by itself..

Duh, I didn't do that part first time around. Followed instructions second time around and....

wow!

one sketch went from 4412b to 3170b, a reduction of almost 30%. The other I checked went from 4268b to 3308b for a 22% savings.

thanks!

-j

OK everybody, I went ahead and updated the library patch at:

http://www.arduino.cc/playground/Code/LibPatch0007

This should work for Windows, Macintosh, and Linux. The zip file is unfortunately now over 700K because I have to include entire JAR files... but I think it is worth it to fit more code in your microcontrollers! :slight_smile:

Thanks to David Mellis for technical assistance, plus allowing me to upload bigger files to the Playground!

  • Don

Feedback from another mac user.... works like a charm... my sketch now complies to 3056 bytes instead of 4160 bytes. Awesome for squeezing all the space possible out of this little wonder.

Great Patch!

Awesome! My sketch went from 3866 bytes down to 1498 bytes, woooo hoooo!

Because Mac users sometimes expect things to just magically happen, here's how I got the stuff to work, step by step.

In this setup, I have two Finder windows open. The one on my left is in my arduino-0007 folder (inside of my Applications folder) . The one on my right is where I downloaded the zipped patch.
So, in order, I...

  • Unzipped the patch ALONE into its own folder in the right window.
  • Double clicked on the new unzipped folder in the right window.
  • Double clicked on the "lib" folder in the right window.
  • Selected the "processing" folder in the right window, and dragged it onto my Arduino lib/ folder in the left window.
  • Double clicked on the "targets" folder in the right window.
  • Double clicked on the "lib" folder in the left window.
  • Renamed my Arduino lib/targets/arduino folder to lib/targets/arduino.original in the left window.
  • Selected the new "arduino" folder in the right window, and dragged it into my Arduino lib/targets folder in the left window.
  • Backed up in the right window once, so I could see "pde.jar"
  • Backed up in the left window once, so I could see "Arduino 07.app"
  • Right-clicked (or ctrl-clicked) on "Arduino 07.app" in the left window, and selected "Show package contents"
  • Double clicked on the "Contents" folder in the new window.
  • Double clicked on the "Resources" folder in the new window.
  • Double clicked on the "Java" folder in the new window.
  • Renamed "Arduino.jar" to "Arduino.jar.old" in the new window.
  • Answered "Use .old" in the irritating warning box, if one popped up.
  • Dragged "pde.jar" in the right window into the new window.
  • Renamed "pde.jar" in the new window to "Arduino.jar". (The capital A is important!)

Sorry for the every-last-detail approach. It's the tech support call center training in me. In any case, following those instructions exactly should get any Mac OSX user up and running with this patch.