Forum: Compiler & IDEs Makefile: mehrere Sourcefiles kompilieren klappt nicht unter Linux??


von Hannes (Gast)


Lesenswert?

Hallo Liebe Forengemeinde,

ich habe ein kleines Problem mit dem µC-programmieren unter Linux.

Ich nutze Debian 7 mit gcc 4.7.2.

Das Problem klingt recht simpel:

Ich habe ein µC Projekt wo ich an einem AtMega8 ein normal 16x2 Display 
betreiben will. Ich benutze dazu die Anleitung hier aus dem Wiki, also 
mit den Dateien lcd-routines.c und lcd-routines.h. Das Problem ist nun 
aber das ich beim kompilieren immer den Fehler bekomme "undefined 
reference to" bei den "lcd-Befehlen" wie zB lcd_init(); oder 
lcd_string("");. Ich weiß das es funktioniert wenn ich die beiden 
Dateien direkt in meine main.c einfüge, doch die feine Art ist das ja 
wohl nicht.
Ich habe trotzdem im Makefile bei "SRC" die lcd-routines.c mit 
angegeben. Ich habe es mittlerweile Makefiles von verschiedenen Seiten 
(unteranderem mit der Vorlage und auch mit der Anleitung hier im WIKI) 
probiert.

Ich vermute das trotzdem bei den Makefiles bzw. beim Einbinden der 
lcd-routines.c der Fehler liegt.

Woran kann das liegen? Habe mit Makefiles noch nicht sehr viel Erfahrung 
bzw. habe nicht sehr oft mit mehreren C-Source-Dateien gearbeite.

MfG

Hannes

: Verschoben durch User
von Tux (Gast)


Lesenswert?

Zeig doch mal dein Makefile, alles andere ist wildes Raten ...

von Peter II (Gast)


Lesenswert?

Hannes schrieb:
> Ich vermute das trotzdem bei den Makefiles bzw. beim Einbinden der
> lcd-routines.c der Fehler liegt.

dann poste doch mal die Ausgaben von make (vorher make clean machen). 
eventuell auch das Makefile.

von __f__ (Gast)


Lesenswert?

versuch doch erstmal deine sources über die kommandozeile zu 
kompilieren(ich geh davon aus es sind nicht so viele sources?).
Und dann schaust du ob du die Befehle, mit denen du manuell kompiliert 
hast, so "ähnlich" im makefile findest
http://www.ijon.de/comp/tutorials/makefile.html

von Hannes (Gast)


Lesenswert?

Das ist die Ausgabe im Terminal
1
avr-gcc -g -mmcu=atmega8 -Wall -Wstrict-prototypes -Os -mcall-prologues -o launchcontroll.out -Wl,-Map,launchcontroll.map launchcontroll.o 
2
launchcontroll.o: In function `main':
3
/home/hannes/Arbeitsfläche/Launchcontrol/launchcontroll.c:49: undefined reference to `lcd_init'
4
/home/hannes/Arbeitsfläche/Launchcontrol/launchcontroll.c:50: undefined reference to `lcd_clear'
5
/home/hannes/Arbeitsfläche/Launchcontrol/launchcontroll.c:52: undefined reference to `lcd_setcursor'
6
/home/hannes/Arbeitsfläche/Launchcontrol/launchcontroll.c:53: undefined reference to `lcd_string'
7
collect2: error: ld returned 1 exit status
8
make: *** [launchcontroll.out] Fehler 1

Und Das Makefile ist das von hier:

http://www.mikrocontroller.net/articles/Beispiel_Makefile

von Hannes (Gast)


Lesenswert?

Ich hatte vergessen zusagen:

Das Makefile habe ich natürlich an einen atmega8 bei MCU angepasst und 
den Programmer geändert.

von S. R. (svenska)


Lesenswert?

In dem Beispiel-Makefile steht doch drin, dass du alle .c-Dateien 
auflisten musst. Woher soll "make" denn sonst wissen, welche Dateien es 
zusammenbauen muss?

Irgendwo ist deine main.c aufgelistet. Dahinter trägst du die lcd.c ein 
und probierst nochmal.

von Hannes (Gast)


Lesenswert?

Ja das ist richtig. Hatte aber geschrieben, dass ich das makefile schon 
angepasst hatte unteranderem auch mit dem eintragen der lcd-routines.c 
bei "SRC = ..."
1
# MCU name
2
MCU = atmega8
3
4
5
# Processor frequency.
6
#     This will define a symbol, F_CPU, in all source code files equal to the 
7
#     processor frequency. You can then use this symbol in your source code to 
8
#     calculate timings. Do NOT tack on a 'UL' at the end, this will be done
9
#     automatically to create a 32-bit value in your source code.
10
#     Typical values are:
11
#    F_CPU =  1000000
12
#       F_CPU =  1843200
13
#       F_CPU =  2000000
14
#       F_CPU =  3686400
15
#       F_CPU =  4000000
16
#    F_CPU =  7372800
17
#       F_CPU =  8000000
18
#    F_CPU = 11059200
19
#       F_CPU = 14745600
20
F_CPU = 16000000
21
#       F_CPU = 18432000
22
#       F_CPU = 20000000
23
#       F_CPU = 8000000
24
25
26
# Output format. (can be srec, ihex, binary)
27
FORMAT = ihex
28
29
30
# Target file name (without extension).
31
TARGET = launchcontroll
32
33
34
# Object files directory
35
OBJDIR = obj
36
37
38
# List C source files here. (C dependencies are automatically generated.)
39
SRC = $(TARGET).c lcd.c
40
41
42
# List C++ source files here. (C dependencies are automatically generated.)
43
CPPSRC = 
44
45
46
# List Assembler source files here.
47
#     Make them always end in a capital .S.  Files ending in a lowercase .s
48
#     will not be considered source files but generated files (assembler
49
#     output from the compiler), and will be deleted upon "make clean"!
50
#     Even though the DOS/Win* filesystem matches both .s and .S the same,
51
#     it will preserve the spelling of the filenames, and gcc itself does
52
#     care about how the name is spelled on its command-line.
53
ASRC =
54
55
56
# Optimization level, can be [0, 1, 2, 3, s]. 
57
#     0 = turn off optimization. s = optimize for size.
58
#     (Note: 3 is not always the best optimization level. See avr-libc FAQ.)
59
OPT = s
60
61
62
# Debugging format.
63
#     Native formats for AVR-GCC's -g are dwarf-2 [default] or stabs.
64
#     AVR Studio 4.10 requires dwarf-2.
65
#     AVR [Extended] COFF format requires stabs, plus an avr-objcopy run.
66
DEBUG = dwarf-2

wollte das lange ding nicht einfügen aber ok

bei mir hab ich die lcd-routines.c als lcd.c gespeichert. Nicht das sich 
wer wundert das da lcd.c bei SRC steht. Hab alles Unter Debug jetzt für 
den Beitrag entfernt damit das hier im forum nicht so lang ist.

von Marc (gierig) Benutzerseite


Lesenswert?

1
#include "lcd.h"
 (oder wie die auch immer bei Dir heißt)
vergessen in deinem File von wo aus Du die Funktion aufrufst ?

Zeig doch bitte das ganze Projekt.

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Marc D. schrieb:
> (oder was wie die auch immer heißt)

nein, dann kommt ein compiler Fehler und kein Linker Fehler.

von Hannes (Gast)


Lesenswert?

1
//#define F_CPU 8000000UL   //the Mega8 runs with the internal Osc. 
2
              //on 8MHz
3
4
#define F_CPU 16000000UL  //external crystal on  16MHz
5
        
6
#include <avr/io.h>
7
#include <util/delay.h>
8
#include <avr/interrupt.h>
9
#include "lcd-routines.h"

Hier mal der Kopf von der Hauptdatei

ist ja egal wie es heißt habs  ja drinnen.

Außerdem wenn ich die "lcd.c" in die main einfüge dann klappt es ja ... 
hab grade ein bißchen gelesen und bin auf die Vermutung Linkerfehler 
gekommen... könnte da das Problem liegen?

von Hannes (Gast)


Lesenswert?

Der Rest des Programms kann es nicht sein dort habe ich zur zeit in der 
int main(void) nur lcd_init(), lcd_clear(), lcd_setcursor(0,0) und eine 
ausgabe mit lcd_string("irgendwas") sehen.

von S. R. (svenska)


Lesenswert?

Der Linkerfehler kommt daher, dass beim Linken die lcd.o nicht mit der 
main.o zusammengelinkt wird und daher der Linker die in lcd.o 
vorhandenen Symbole nicht findet und die Referenzen aus main.o nicht 
auflösen kann.

Das heißt:
- obj/lcd.o wird nicht erzeugt
  ($CC $CFLAGS -c -o lcd.o lcd.c), oder
- obj/lcd.o wird nicht eingelinkt
  ($CC $CFLAGS $LFLAGS -o main main.o lcd.o).

Probiere mal "make obj/lcd.o", wenn er dir dann die lcd.o erzeugt, ist 
es der zweite Fall; andernfalls der erste Fall. In jedem Fall erkennt 
make die Abhängigkeit zwischen "targetcontroll" und "lcd.o" nicht.

(Übrigens schreibt man "control" nicht mit 2 L am Ende.)

von batman (Gast)


Lesenswert?

Listet man da nicht anstatt der SRC die OBJ-Dateien auf und überläßt es 
dem make, die entsprechenden Sourcen zu kompilieren?
Ich hätte da im Makefile OBJ= .. lcd.o ..

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.