Forum: Compiler & IDEs INCLUDE richtig benutzen


von Werner Frerichs (Gast)


Lesenswert?

Hallo NG,

ich benutze WINAVR, und habe mein Testprogramm in mehrere Teile
zerlegt:
-main.c
-lcd.c
-v24.c

MAIN benutzt Funktionen der beiden anderen C-Programme LCD und V24.

Es funktioniert alles ganz prima, wenn ich die beiden C-Programme in
MAIN direkt einbinde:
- #include lcd.c
- #include v24.c

Da mir das so nicht gefällt, habe ich mir Header-Dateien
- lcd.h
- v24.h

gebaut, in denen ich nur die von MAIN benutzten Funktionen aufgelistet
habe.

In MAIN binde ich dann die Headerdateien
- #include "lcd.h"
- #include "v24.h"
ein.

Bei jedem Aufruf einer Funktion von LCD oder V24, kommt aber jetzt die
Fehlermeldung, dass die Funktion nicht definiert sei.


Eigentlich sollte das Ganze doch so funktionieren, oder funktionieren
Headerdateien nur zusammen mit den kompilierten C-Programmen.

WFR

von MSE (Gast)


Lesenswert?

Wenn Du main.c compilierst, sollte keine Fehlermeldung kommen, wenn die
*.h-Files mittels #include eingebunden sind und wirklich alle
aufgerufenen Funktionen mit korrekten Prototypen dort vorgestellt
werden.

Wenn Du das ganze in etwas lauffähiges (bzw. flash-fähiges) überführen
willst (mit dem Linker), dann mußt Du natürlich auch die entsprechenden
Objektfiles zu den *.h-Files dazulinken. (Denn schließlich steht nur
dort drin, wie die Funktionen was tun sollen. Im h-File steht ja nur,
wie sie aufzurufen sind.)

Du mußt also sowohl main.c als auch die beiden Files lcd.c und v24.c
compilieren (d.h. in Object-Files überführen), damit Du sie dann alle
zusammenlinken kannst.

Gruß, Michael

von Werner Frerichs (Gast)


Lesenswert?

Hallo Michael,

genauso denke ich mir das auch, das es gehen sollte, trotzdem werkt das
mir nicht.
Aber lassen wir das Kompilieren der einzelnen C-Programme erst mal
weg.

Also ich habe jetzt ein ganz simples Beispiel

1. main.c
  #include "test.h"
  .

von Werner Frerichs (Gast)


Lesenswert?

Hallo Michael,

genauso denke ich mir das auch, das es gehen sollte, trotzdem
werkt das bei mir nicht.
Aber lassen wir das Kompilieren der einzelnen C-Programme erst
mal weg.

Also ich habe jetzt ein ganz simples Beispiel

1. main.c
---------
#include "test.h"
  .
  .
int main (void)
{
 testInit();
}


2. test.c
---------
void testInit (void)
{
}


3. test.h
void testInit (void);

Was mache ich denn da falsch? Sobald ich main kompiliere,
kommt die Fehlermeldung:

  "undefined reference to `testInit'"

von Oliver S. (z0ttel)


Lesenswert?

Hi,

so gehts:

2. test.c
---------
#include "test.h"
  .
  .
void testInit (void)
{
}

3. test.h
---------
extern void testInit (void);

von Werner Frerichs (Gast)


Lesenswert?

Hallo Oliver,

geht leider auch nicht.

von Oliver S. (z0ttel)


Lesenswert?

Hi Werner,

wie kompilierst Du das Ganze? Wenn Du das per makefile machst, musst Du
test.c natürlich auch noch unter den Sourcen aufnehmen, z.B.:

SRC = main.c test.c


Damit sollte es aber klappen -- achja, hinter den #includes gehören
auch nach die Semikolons (ist das die Mehrzahl von Semikolon??)


Gruß,
Oliver

von Werner Frerichs (Gast)


Angehängte Dateien:

Lesenswert?

Hallo Oliver,

ich denke Semikolons und Semikola ist beides richtig.


In meinem Makefile finde ich übrigens kein:

SRC = ....

siehe Anlage

von Werner Frerichs (Gast)


Lesenswert?

Hallo Oliver,

Noch ein Nachtrag.

Die Zeile "SRC = ...." im Make File habe ich da nur probehalber
einmal reingeschrieben. Sie ist ohne Wirkung.

Werner

von Oliver S. (z0ttel)


Angehängte Dateien:

Lesenswert?

Hallo Werner,

ich verwende das Standardmakefile, welches mit WinAVR geliefert wird
(siehe Anhang), damit hatte ich bis jetzt keine Probleme.

Dein makefile kann man sicher so erweitern, dass es auf Deine Anwendung
passt, aber evtl. kannst Du ja auch mit dem Std-makefile glücklich
werden...

Dort gibt es übrigens den Eintrag SRC und wenn Du den anpasst, sollte
es keine Probleme mehr geben.

Für den Fall, dass Du test.h in einem anderen Pfad als die beiden
.c-Sourcen hast, musst Du denn Pfad noch unter EXTRAINCDIRS
spezifizieren.


Oliver

von Oliver S. (z0ttel)


Lesenswert?

In Deinem makefile werden alle Files compiliert und gelinkt, die unter
OBJ aufgeführt sind. Ich bin mir nicht sicher ob es reicht, dort test.o
aufzuführen...

von Werner Frerichs (Gast)


Lesenswert?

Hallo Oliver,

auch mein MakeFile war bei WinAvr dabei. Ich selber bin noch gar nicht
in der Lage am MakeFile rumzumachen.

Es reicht übrigens aus, wenn man "test.o" unter "OBJ" ergänzt.

#####
Was ist denn deine Meinung, sollte ich lieber auf das
"Standard-MakeFile" umsteigen?


Werner

von Oliver S. (z0ttel)


Lesenswert?

Hmm,

das bleibt letzten Endes Deinem persönlichen Geschmack vorbehalten. Der
Vorteil, den ich in dem von mir geposteten makefile (es stammt übrigens
aus dem Verzeichnis /winAVR/sample) sehe, liegt einfach darin, dass es
von vielen Leuten hier zumindest als Basis benutzt wird und Dir somit
im Falle eines Falles schneller geholfen werden kann.



Gruß,
Oliver

von Daniel B. (khani)


Lesenswert?

Irrtümer schleicht euch !

Also ein paar Anmerkungen zu dem schon geäußerten :
1. Beim Aufteilen eines Projektes in mehrere Dateien (sehr löblich !)
erweist es sich oft als praktisch die weiteren .c - Dateien entweder
alle in ein Verzeichnis oder noch besser in verschiedene Verzeichnisse
je nach Bedeutung abzulegen. Meinetwegen so :
Hauptverzeichnis
|- main.c
|- (main.h)
|- UART
|  |- UART.c
|  |- UART.h
|- Display
|  |- display.c
|  |- display.h
...
Der Vorteil dabei ist, wenn man mal ein anderes Projekt macht und
Bausteine verwenden will, dann kann man ganz gut diese Bausteine
herauskopieren und weiterverwenden.

2. #include <blablubb.h> bindet den Header blablubb.h aus dem
Standardincludeverzeichnis (wo auch immer es ist) ein. #include
<mehr/blablubb.h> bindet den header blablubb.h aus dem Unterverzeichnis
mehr des Standardincludeverzeichnisses ein.
#include "hallihallo.h" bindet den Header hallihallo.h aus dem
Projektverzeichnis ein. #include "tolleHeader/meins.h" entsprechend
für das Unterverzeichnis tolleHeader des Projektverzeichnisses.

3. nach #include .... kommt kein Semikolon ! die #include-Anweisung ist
ein Präprozessorbefehl, der dem Compiler in der Textersetzungsphase
mitteilt, an dieser Stelle eine Datei Buchstabe für Buchstabe
einzukleben.

4. Mit dem Tool mFile und dem dazugehörigen Standardmakefile aus dem
Lieferumfang von WinAVR kann man sehr einfach ein funktionierendes
Makefile erstellen. Dazu wird das Standardmakefile in das
Projektverzeichnis kopiert und anschließend mit dem Tool mFile
komfortabel editiert. Wenn man dann noch Sonderwünsche hat, kann man
das Makefile auch mit dem selben Tool von Hand weitereditieren.
Dazu ein Hinweis an die Verwender von Versionshaltungssystemen mit
checkin/checkout sowie beim Kopieren von ganzen Projekten : Das Tool
mFile bindet die zusätzlichen .c-Dateien mit einem absoluten Pfad
(d:/avr/meinTollesProjekt/meineGenialeSchnittstelle/dummy.c) ein. Wenn
man das Projekt an eine andere Stelle kopiert oder mit einem
Versionshaltungssystem in einen anderen Ordner auscheckt, stimmen die
Pfade nicht mehr. Man sollte hier in diesem Falle per Hand auf relative
Pfade zum Projektverzeichnis umstellen, wenn dies angezeigt erscheint.

MfG, Daniel

von z0ttel (Gast)


Lesenswert?

HiHo!

Zu 3: Stimmt - shame on me :(

Zu 2: Anstatt den Pfad zu einem anderen Header direkt in die
#include-Anweisung aufzunehmen, kann man die Pfade, in denen noch
Headerdateien zu finden sind im makefile unter 'EXTRAINCDIRS = '
aufführen.

Dadurch wird die bereits unter (1) angesprochene Portabilität der
Module weiter unterstützt (Eine Änderung der Pfade bewirkt eine
zentrale Änderung im makefile anstatt X Änderungen in den Sourcefiles
(wenn der Header X-Mal includiert wird)).

Im Prinzip ist aber auch dieses Geschmacksache.

Gruß,
Oliver

von Werner Frerichs (Gast)


Lesenswert?

Hallo NG,

Alsao ich habe jetzt alles auf das "Standard-MakeFile" umgestellt.

Es funktioniert sogar ;-)

Vielen Dank an alle für die Hilfe.

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.