Arduino0015+Eclipse problems

Hi Everyone,

I know compiling Arduino sketches with Eclipse is not supported, but still, I hope someone can give me a hand with this.

I was using Eclipse to write code for the Arduino and it worked beautifully with versions up to 0014. My setup follows the eclipse guide in the Playground, but with a few differences:

After creating my new project, I copy all files from hardware/cores/arduino/ into an arduino/ folder inside the project, and I add that to the include directories for the C and C++ compilers. I do not use a pre-compiled core.a file, but link against .o files from the arduino folder. That allows me to modify the arduino lib when needed. I simply delete the main.cxx file and use my own:

#include "WProgram.h"

void setup(void);
void loop(void);

int main(void) {
      init();
      setup();
      for (;;)
            loop();
}

I have a separate file that defines my setup() and loop(), blink.cpp in this case:

#include "WProgram.h"

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

unsigned char state = HIGH;

void loop(void) {
      state = !state;
      digitalWrite(13, state);
      delay(300);
}

This no longer works with the Arduino library from 0015 or SVN version.

This is the build log in eclipse, errors are highlighted at the end:

http://pastebin.com/ma5cc4f6

Compiling the blink example with the Arduino IDE with enabled verbose build:

http://pastebin.com/m173feebc

As far as I can see, everything is about the same, with the only difference that I skip copying objects into the core.a file. I don't really understand all options passed to the compiler/linker. I'd be very happy if anyone can provide some insight.

I reviewed changes in the arduino library and noticed HardwareSerial.cpp does not rely on code in wiring_serial.c anymore. Deleting wiring_serial.c solves the duplicate interrupt handler issue, but the one for '__cxa_pure_virtual' remains. I suppose this is a problem of the compiler not being able to compile Print.cpp?!

Additional info about my setup:
OS: Ubuntu 9.04
avr-gcc 4.3.2
avr-libc 1.6.2 (both avr-gcc and avr-libc are the latest versions of the Ubuntu packages)

Eclipse: 3.4.1
AVR-Eclipse Plugin: 2.3.1

Arduino: Duemilanove with 328p

PS. This should probably be moved to 'Arduino Forum ? Software ? Troubleshooting'. Sorry, should have seen this category before posting.

After some more googling, it seems that the problem is a missing library, containing the '__cxa_pure_virtual' function.

But this method worked fine (and still does!) with the older arduino library.

I should probably modify the linker command, or add some objects to the linker configuration or .... anyone?

Did you try changing the last command from avr-gcc to avr-g++? IIRC, __cxa_pure_virtual is something that should be generated by the C++ compiler.

Still the same error, even if linking with avr-g++:

Invoking: AVR C++ Linker
avr-g++ --cref -s -Os -o"ABox.elf"  ./blink.o ./main.o  ./arduino/HardwareSerial.o ./arduino/Print.o ./arduino/WInterrupts.o ./arduino/WMath.o ./arduino/pins_arduino.o ./arduino/wiring.o ./arduino/wiring_analog.o ./arduino/wiring_digital.o ./arduino/wiring_pulse.o ./arduino/wiring_shift.o    -lm -Wl,-Map,ABox.map,--cref -mmcu=atmega328p
./arduino/Print.o: In function `Print::write(char const*)':
../arduino/Print.cpp:32: undefined reference to `__cxa_pure_virtual'
make: *** [ABox.elf] Error 1

Also, here's the link command that the Arduino IDE issues:

avr-gcc -Os -Wl,--gc-sections -mmcu=atmega328p -o /tmp/build6378713336155302747.tmp/Blink.elf /tmp/build6378713336155302747.tmp/Temporary_7071_9587.cpp.o /tmp/build6378713336155302747.tmp/core.a -L/tmp/build6378713336155302747.tmp -lm

it also uses avr-gcc for linking, with slightly different options ...

Are there duplicates of these files on your computer...

wiring_serial.o
HardwareSerial.o
Print.o

It appears the object files are place in very different places (with the source files versus in a temporary folder). It is possible there is an errant object file tripping you up.

  • Brian

I don't think that's it either :(. Still, I did a find / -name Print.o and found nothing suspicious.

Aren't all source object files listed on the command line?

I've been fighting with this for some days now. Alas, with no prior C/C++ experience I feel kind of lost.

If anyone is willing to try this out, here's an archive of the Eclipse project:

http://1024.cjb.net/ABox.tar.gz

There is a Debug folder inside it, with automatically generated make files.

ABox/Debug $ make ABox.elf

should replicate the build process of Eclipse. Please try this out in your environment and let me know if you experience the same error.

Mellis, the build works if you replace the arduino folder with r577 from the google code svn repo. r578 introduces the virtual functions in Print.cpp, but I am wondering why does this work from the Arduino IDE, but not with this build process?!?

Thanks to everyone who took the time to read through this :slight_smile:

I have not seen the files on the svn but as of 0015 Print::write(char const*) should be Print::write(uint8_t)

Actually, from Print.h

  public:
    virtual void write(uint8_t) = 0;
    virtual void write(const char *str);
    virtual void write(const uint8_t *buffer, size_t size);

The compile error is in Print.cpp, for this function:

/* default implementation: may be overridden */
void Print::write(const char *str)
{
  while (*str)
    write(*str++);
}

I found a few threads that suggest declaring&defining __cxa_pure_virtual() for pure virtuals to work. The big question for me now is why does the arduino library compile with the Arduino IDE, but not with the Eclipse build?

So they've added two write's then. Hmmm. For the ethernet maybe? [Or bufring generally?]

Just me guessing again:

/* default implementation: may be overridden */
void Print::write(const char *str)
{
  while (*str)
    this->write(*str++);
}

But it is very strange that it compiles with Arduino IDE and not eclipse.

Nope, that didn't work either.

I am now able to compile the sketch with Eclipse if I add

extern "C" void __cxa_pure_virtual(void);
void __cxa_pure_virtual(void) {}

in any .cpp file. Without it, it always complains with

./arduino/Print.o: In function `Print::write(char const*)':
../arduino/Print.cpp:32: undefined reference to `__cxa_pure_virtual'

Can you guys download the code and try running the build?

Also, does anyone know where to get a full list of avr-gcc options and their meanings? I can't find a man page, avr-gcc -v --help doesn't seem to list everything ...

This FAQ has an explanation: http://ccgi.rowley.co.uk/support/faq.php?do=article&articleid=127

Indeed. However, it seems to me the problem is with the Arduino library, and the question is why does your build work.

Someone at AVRFreaks has written a tutorial on coding C++ for the AVR. Part of what needs to be done is definition and implementation of a void __cxa_pure_virtual(void) function. There is no such function in the Arduino library, hence the build error.

However, when building the project with an object archive (not sure about the terminology here), it magically works! The Arduino IDE copies all C and C++ compiled object files into core.a, and then links the main object file against it (and any other libraries outside the core). This I cannot explain.

Can someone shed some light on this?

One thing looks suspicious. I think this is the link step...

avr-gcc --cref -s -Os -o"ABox.elf"  
./blink.o 
./main.o  
./arduino/HardwareSerial.o 
./arduino/Print.o 
./arduino/WInterrupts.o 
./arduino/WMath.o 
./arduino/pins_arduino.o 
./arduino/wiring.o 
./arduino/wiring_analog.o 
./arduino/wiring_digital.o 
./arduino/wiring_pulse.o 
./arduino/wiring_serial.o 
./arduino/wiring_shift.o    
-lm -Wl,-Map,ABox.map,--cref -mmcu=atmega328p

I think one or more crt*.o files need to be included in that step. That may be where the elusive __cxa_pure_virtual has gone.

Good luck,
Brian

Hmm. Where are these crt*.o files supposed to come from? The official IDE does not use any ...

I am still digging into this out of pure curiosity. I want to know why the Arduino IDE build works, while it shouldn't?!

Hmm. Where are these crt*.o files supposed to come from?

My Arduino directory tree is filled with them (137 files).

  • Brian
kiril@kiril:~/local/arduino-0013$ find . -name crt\*.o
kiril@kiril:~/local/arduino-0013$
# this is the svn version from today
kiril@kiril:~/local/arduino-build$ find . -name crt\*.o
kiril@kiril:~/local/arduino-build$

:-?

That is strange.

What's in your...

arduino-0013\hardware\tools\avr\avr\lib

...directory?

  • Brian

That question helped :slight_smile: I use Linux, gcc-avr, avr-libc and avrdude come from the distro. So here is where the crt*.o files are:

kiril@kiril:/usr/lib/avr/lib$ avr-gcc --print-search-dirs
install: /usr/lib/gcc/avr/4.3.2/
programs: =/usr/lib/gcc/avr/4.3.2/:/usr/lib/gcc/avr/4.3.2/:/usr/lib/gcc/avr/:/usr/lib/gcc/avr/4.3.2/:/usr/lib/gcc/avr/:/usr/lib/gcc/avr/4.3.2/../../../avr/bin/avr/4.3.2/:/usr/lib/gcc/avr/4.3.2/../../../avr/bin/
libraries: =/usr/lib/gcc/avr/4.3.2/:/usr/lib/gcc/avr/4.3.2/../../../avr/lib/avr/4.3.2/:/usr/lib/gcc/avr/4.3.2/../../../avr/lib/

I went on playing with this, and found even more curious things. For instance, Eclipse's binaries are much larger than the one generated by the IDE, sometimes by a 3-fold. However, the .o files by the IDE are (on average) 5% larger than those of Eclipse ... I wish I had studied compiler design and theory back in the university ...

That question helped

I'm glad to hear!

Eclipse's binaries are much larger than the one generated by the IDE

That could be the results of...

  • The various build switches. Often there are "optimize for size" and "optimize for speed" options.
  • Building with debug versions of the CRT files. C(++) compilers generally include "release" and "debug" versions of libraries. Usually debug versions are considerably larger.
  • Including the wrong CRT files.
  • Bug(s) in the development tools.

the .o files by the IDE are (on average) 5% larger than those of Eclipse

That only indicates they were built differently. The size of the .o files isn't necessarily going to be related to the size of the final product.

Good luck,
Brian