Linken zweier Objektdateien - 'undefined reference'

#1820303
Lesenswert?

Hallo,
da mein Programm doch langsam etwas umfangreicher wird, wollte ich es in 
mehrere Dateien aufteilen: GCC will mich dabei nicht so recht 
unterstützen...

Die Dateien:

main.c
1
#include "spi.h"
2

3
int main()
4
{
5
  Test();
6
}

spi.h
1
const char *Test();

spi.c
1
#include "spi.h"
2
const char *Test()
3
{
4
  return "bla";
5
}

Ich verwende das Beispiel Makefile, habe nur spi.c zu SRC 
hinzugefügt, es wird auch kompiliert.

Linkeraufruf (auf mehrere Zeilen aufgeteilt...):
1
Linking: main.elf
2
avr-gcc -mmcu=atmega88 -I. -gdwarf-2 -DF_CPU=20000000UL -Os
3
 -funsigned-char -funsigned-bitfields -fpack-struct -fshort-enums -Wall
4
 -Wundef -Wa,-adhlns=obj/main.o -I./include/ -std=gnu99 --combine 
5
-fwhole-program -Wundef -MD -MP -MF .dep/main.elf.d obj/main.o 
6
obj/spi.o --output main.elf -Wl,-Map=main.map,--cref    -lm

Er beschwert sich, dass Test undefiniert sei - Nun, ich habe sie doch in 
spi.c definiert? Muss ich GCC noch sagen, dass er Test exportieren soll? 
Habe schon mit avr-nm in spi.o nachgeschaut: Nichts?!
1
00000034 a __CCP__
2
0000003e a __SP_H__
3
0000003d a __SP_L__
4
0000003f a __SREG__
5
00000000 a __tmp_reg__
6
00000001 a __zero_reg__

Nun - hab ich einen entscheidenden Fehler gemacht? Bin ich blöd? XD
Ich steh vollkommen auf dem Schlauch.

MfG,
Flinti

EDIT: Etwas korrigiert hust
Moderator Persönliche Seite #1820364
Lesenswert?

Jetzt zeig uns mal bitte sämtliche Meldungen vom Compilieren,
einschließlich der Kommandozeilen -- am besten als Textdatei im
Anhang.

Wenn ich nämlich dein spi.c compiliere:
1
j@uriah 108% cat > foo.c
2
const char *Test()
3
{
4
  return "bla";
5
}
6
^D
7
j@uriah 109% avr-gcc -Os -c foo.c
8
j@uriah 110% avr-nm foo.o
9
00000000 T Test
10
00000034 a __CCP__
11
0000003e a __SP_H__
12
0000003d a __SP_L__
13
0000003f a __SREG__
14
         U __do_copy_data
15
00000000 a __tmp_reg__
16
00000001 a __zero_reg__
...dann ist da sehr wohl ein Symbol "Test" drin.
Moderator Persönliche Seite #1820451
Lesenswert?

Klar, wenn du dem Compiler für jeden einzelne Datei vorgibst, er
solle davon ausgehen, dass es sich bei dieser Datei um das gesamte
Programm handelt (-fwhole-program), dann brauchst du dich nicht
zu wundern.  Dann stellt er nämlich glücklich fest, dass die
Funktion Test() ja von keinem weiter gerufen wird und wirft sie
raus...

-fwhole-program hat nur dann Sinn, wenn man "in einem Rutsch"
alles zusammen compilieren lässt:

avr-gcc -mmcu=atmega88 -fwhole-program -Os -o main.elf main.c spi.c

(Edit: hast du zeitgleich selbst bemerkt, Pluspunkt. ;-)

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren