Go Down

Topic: Makefile (Read 2 times) previous topic - next topic

mwarning

Sep 29, 2009, 01:28 am Last Edit: Sep 29, 2009, 01:31 am by mwarning Reason: 1
Hi,

I try to compile the .pde/c files without the arduino IDE but a Makefile.
The Makefile is from arduino-0017/hardware/cores/arduino/Makefile
but slightly modified:
- the sub directory applet was renamed to arduino
- instead of a pde file, a c file is used.
- some fix to reset the serial port for uploading.

The modified Makefile.

My main.cpp:
Code: [Select]
#include "arduino/WProgram.h"
#include "arduino/HardwareSerial.h"

void setup() {
  Serial.begin(9600);
}

void loop() {
}

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



Everything compiles fine when I comment out "Serial.begin(9600);"
and don't include arduino/HardwareSerial.h.

But the code above gives me:

Code: [Select]

$make
[..]
avr-gcc -mmcu=atmega328p -I. -gstabs -DF_CPU=16000000 -I./arduino -Os -Wall -Wstrict-prototypes -std=gnu99  -o main.elf main.cpp -L. core.a -lm
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
core.a(Print.o):(.data+0x6): undefined reference to `__cxa_pure_virtual'
make: *** [main.elf] Error 1


When I rename my main.cpp file to main.c (in the Makefile as well):

Code: [Select]
$make
[..]
avr-gcc -mmcu=atmega328p -I. -gstabs -DF_CPU=16000000 -I./arduino -Os -Wall -Wstrict-prototypes -std=gnu99  -o main.elf main.c -L. core.a -lm
In file included from arduino/HardwareSerial.h:25,
                from main.c:4:
arduino/Print.h:32: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Print'
In file included from main.c:4:
arduino/HardwareSerial.h:29: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'HardwareSerial'
arduino/HardwareSerial.h:57: error: expected '=', ',', ';', 'asm' or '__attribute__' before 'Serial'
main.c: In function 'setup':
main.c:21: error: 'Serial' undeclared (first use in this function)
main.c:21: error: (Each undeclared identifier is reported only once
main.c:21: error: for each function it appears in.)
make: *** [main.elf] Error 1


Apparently the C compiler chokes on C++ code.
But the original Makefile uses a main.cpp.
So why does it work there?

claudio-13

Hi there,

Basically the compiler is not recognizing it as C++.
taken from gcc man pages line 859ish

  Compiling C++ Programs
      C++ source files conventionally use one of the suffixes .C, .cc, .cpp,
      .CPP, .c++, .cp, or .cxx; C++ header files often use .hh, .hpp, .H, or
      (for shared template code) .tcc; and preprocessed C++ files use the
      suffix .ii.  GCC recognizes files with these names and compiles them as
      C++ programs even if you call the compiler the same way as for
      compiling C programs (usually with the name gcc).

      However, the use of gcc does not add the C++ library.  g++ is a program
      that calls GCC and treats .c, .h and .i files as C++ source files
      instead of C source files unless -x is used, and automatically
      specifies linking against the C++ library.  This program is also useful
      when precompiling a C header file with a .h extension for use in C++
      compilations.  On many systems, g++ is also installed with the name
      c++.


So if you want to compile your main.c you should use g++ which is basically what gcc does automatically when he sees a .cpp extension.

Try avr-g++ in your makefile that should solve the problem, or just leave the .cpp.

-Claudio
Datemi un Arduino e sollevero il mondo.

mwarning

Thanks for your reply!

I've tried to use avr-g++, but still no luck:
Code: [Select]
avr-g++ -mmcu=atmega328p -I. -gstabs -DF_CPU=16000000 -I./arduino -Os -Wall -Wstrict-prototypes -std=gnu99  -o main.elf main.cpp -L. core.a -lm
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++
cc1plus: warning: command line option "-std=gnu99" is valid for C/ObjC but not for C++
core.a(Print.o):(.data+0x6): undefined reference to `__cxa_pure_virtual'


I tried to use avr-g++ everywhere in the Makefile as well.
Same result.

claudio-13

I am puzzled too, I looked up the symbols in the various objects and in Print.o it is unresolved therefore also in core.a it is unresolved! Unfortunately with your Makefile I dont fail to build so I also read the elf file, and __cxa.... is undefined also there!!
I wondering if my build would actually work on an arduino, other than wait for my arduino I can only hope someone more expert will answer us.

Just for fun can you check avr-gcc version? I am on 4.3.2 (Linux)

-Claudio
Datemi un Arduino e sollevero il mondo.

mwarning

Code: [Select]
$ avr-gcc --version
avr-gcc (GCC) 4.3.3
Copyright (C) 2008 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE


avr-g++ is the same version.

I use debian 64bit and my arduino IDE works fine.
So, if my Makefile (from the initial post) works for you, there might be something funny with my system...

claudio-13

Hi,
I found out that __cxa_pure_virtual() is the handler for pure virtual functions, my suggestion is just to implement it something like

Code: [Select]

void extern "C" __cxa_pure_virtual(){
 //turn on a led?
 while(true);//anyway if you get here you forgot to implement something
}


Not sure if you actually need that ' extern "C" ', anyway you must have a wrong version of something somewhere.

-Claudio
Datemi un Arduino e sollevero il mondo.

mwarning

I've added
Code: [Select]
extern "C" void __cxa_pure_virtual() {
 while(true);
}

and it compiles&works now.  :D

Strange problem. I wonder what the arduino IDE does..

Thanks for your help!

wayoda

Hi,
Quote

Strange problem. I wonder what the arduino IDE does..

The preprocessed PDE-file that gets compiled is at
Sketch/applet/NameOfSktech.cpp

and the compiler messages are shown when you set "build.verbose=true" in the IDE Preferences

Eberhard



mwarning

build.verbose=true was quite useful.
I've found the problem!

For building the objects files "-ffunction-sections -fdata-sections" was missing
and the final avr-gcc call needs "-Wl,--gc-section".

Here is the modified and simplified Makefile.

Thanks everyone!

Go Up