Pages: [1]   Go Down
Author Topic: Makefile  (Read 2159 times)
0 Members and 1 Guest are viewing this topic.
0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
#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:
$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:
$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?
« Last Edit: September 28, 2009, 06:31:51 pm by mwarning » Logged

Aix en Provence, France
Offline Offline
Newbie
*
Karma: 0
Posts: 24
Arduino iacta est
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Datemi un Arduino e sollevero il mondo.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Thanks for your reply!

I've tried to use avr-g++, but still no luck:
Code:
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.
Logged

Aix en Provence, France
Offline Offline
Newbie
*
Karma: 0
Posts: 24
Arduino iacta est
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
Logged

Datemi un Arduino e sollevero il mondo.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Code:
$ 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...
Logged

Aix en Provence, France
Offline Offline
Newbie
*
Karma: 0
Posts: 24
Arduino iacta est
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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:
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
Logged

Datemi un Arduino e sollevero il mondo.

0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

I've added
Code:
extern "C" void __cxa_pure_virtual() {
  while(true);
}
and it compiles&works now.  smiley-grin

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

Thanks for your help!
Logged

Wuppertal/Germany
Offline Offline
God Member
*****
Karma: 1
Posts: 895
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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
 

Logged

0
Offline Offline
Newbie
*
Karma: 0
Posts: 11
Arduino rocks
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

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!
Logged

Pages: [1]   Go Up
Jump to: