Forum: Compiler & IDEs Erstellen von External Dependencies


von Christoph M. (fakulatus)


Lesenswert?

Hellow Leuts

Vielleicht erst einmal kurz die Ausgangslage:
vor kurem habe ich ein kleines Board mit einem Atmega8 gekauft.
Zum Ansteuern der Peripherie hat der Hersteller dieses Boards ein paar 
Headerdateien mitgeliefert. Leider waren die Funktionen in den Headers 
ausprogrammiert, für mich ein absolutes DON'T. Also habe ich mich daran 
gemacht, für jedes Header ein entsprechendes Source zu erstellen.

Jetzt mein Problem:
Die alten Headers konnte ich schön als "External Dependencies" im 
AVRStudio einbinden (Options->Include Directories). Nun möchte ich dies 
gerne auch mit den Neuen. Leider bringe ich das nicht zu stande. Lässt 
man das ".h" und ".c" so stehen, erkennt es zwar die .h, doch die hat 
irgendwie kein Bezug zum ".c" (Trotz #include .h) (undefined reference 
to).

Ebenfalls habe ich mit .a und .o etc gespielt, bringe es irgendwie nicht 
zu stande.

Hat jemand Ideen?

Wichtig ist: Möchte die Dateien als "External Dependencies" einbinden 
und nicht im eigentlichen Projekt

AVRStudio 4.13 Build 528

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Christoph Mauchle wrote:


> Die alten Headers konnte ich schön als "External Dependencies" im
> AVRStudio einbinden (Options->Include Directories). Nun möchte ich dies
> gerne auch mit den Neuen. Leider bringe ich das nicht zu stande. Lässt
> man das ".h" und ".c" so stehen, erkennt es zwar die .h, doch die hat
> irgendwie kein Bezug zum ".c" (Trotz #include .h) (undefined reference
> to).

Bei solchen Problemen ist es IMHO einfacher, wenn der Fragesteller den 
problematischen Code oder das Projekt anhängt.

#include .h muss einen Fehler beim Kompilieren erzeugen, da es keine 
gültige Anweisung ist. Gültige Anweisungen sehen so aus:

#include <beispiel1.h>
#include "beispiel2.h"

Der Unterschied bei beiden ist die Stelle, wo die zu includierende Datei 
gesucht wird. Bei <> im Standardsuchpfad für Includedateien. "" im 
aktuellen Verzeichnis.

von Christoph M. (fakulatus)


Lesenswert?

Ok ok ok :)

Dachte sei klar was ich meine mit dem #include .h

hier das .h (sound.h)
1
#ifndef _SOUND_H_
2
#define _SOUND_H_
3
4
void sound(int freq,int time);
5
6
7
void sound_cnt(unsigned char cnt,int freq,int time);
8
9
#endif

und das ensprechende .c (sound.c)
1
#include <avr/io.h>  
2
#include <in_out.h>
3
#include <sleep.h>
4
#include "sound.h"
5
6
void sound(int freq,int time)
7
{
8
  int dt=0,m=0;  // Keep value and 
9
  
10
    dt = 5000/freq;     // Keep active logic delay
11
  time = (5*time)/dt;  // Keep counter for generate sound
12
  
13
  for(m=0;m<time;m++) // Loop for generate sound
14
  {
15
        out_d(4,1);
16
    delay_sound(dt);  // Delay for sound  
17
        out_d(4,0);
18
    delay_sound(dt);      // Delay for sound
19
  }    
20
}
21
22
void sound_cnt(unsigned char cnt,int freq,int time)
23
{
24
  unsigned char i;
25
  for (i=0;i<cnt;i++)  
26
  {
27
    sound(freq,time);
28
    sleep(300);
29
  }
30
}

Dateien liegen auch im gleichen Verzeichnis.

Genaue Fehlermeldung des gcc:

../main.c:29: undefined reference to 'sound'

Dabei liegt natürlich main.c nicht am gleichen Ort wie sound.h oder 
sound.c weil die will ich ja extern einbinden

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Dann muss sound.c auch in das Projekt eingebunden werden.

Ich bin mir aus dem Stegreif nicht sicher, ob sound.h automatisch 
gefunden und automatisch zu den Abhängigkeiten eines Projektes 
zugeordnet wird, wenn sound.c in einem anderen Verzeichnis liegt als 
main.c.

In der Artikelsammlung ist ein Screenshot, wie ein Projekt mit mehreren 
eigenen Quellcodedateien aussehen kann:
http://www.mikrocontroller.net/articles/Bild:PFA_Projekt_ZLCD.png

Unter Source Files musst du dann main.c und sound.c angeben. Unter 
Header Files dann die Header Files, die nicht im Standard-Includepfad 
liegen (alle mit "" angegebenen), also sound.h

Mit der händischen Eingabe von sound.c in Source Files und sound.h 
in Header Files denke ich, dass deine Probleme verschwinden.

von Dirk D. (dirkd)


Lesenswert?

Hi,

Wenn der Fehler in main.c gemeldet wird solltest Du vielleicht auch 
main.c zeigen.

> Wichtig ist: Möchte die Dateien als "External Dependencies" einbinden
> und nicht im eigentlichen Projekt

Vielleicht liegt auch hier das Problem. Wenn Du die Funktionen in der 
sound.c implementierst, dann mußt Du auch die sound.c zu Deinem Projekt 
hinzufügen oder das separat compilierte Objekt sound.o dazu linken.

von Christoph M. (fakulatus)


Lesenswert?

Dirk Dörr wrote:
> Wenn Du die Funktionen in der
> sound.c implementierst, dann mußt Du auch die sound.c zu Deinem Projekt
> hinzufügen oder das separat compilierte Objekt sound.o dazu linken.

Genau das ist es, was ich eben nicht machen möchte.
Ich möchte die sound.h-Datei genau so wie zum Beispiel #include 
<avr/io.h> einbinden können. Ohne die .c oder auch die .h Dateien dem 
Projekt zu zu ordnen. Das macht nicht viel Sinn, denn sound.h bez 
sound.c sind eigentlich Bibliotheken und haben nichts mit dem zu 
erstellenden Projekt zu tun. Die Funktionen werden in zig-Projekten 
verwendet und jedesmal sound.h und sound.c ins Projekt zu kopieren macht 
in meinen Augen keinen Sinn.

von Dirk D. (dirkd)


Lesenswert?

Das Header File kannst (und mußt) Du natürlich einbinden. Das ist auch 
nicht das Problem.

Aber irgendwo muß es eine Implementierung der deklarierten Funktionen 
geben. Und diese Implementierung muß zu Deinem Projekt hinzugefügt 
werden.

3 Möglichkeiten:

a) sound.c wird als Projektfile hinzugefügt. Dann wird AVRStudio diese
   Datei compilieren und auch dazu linken.

   Das willst Du nicht. Ok. bleiben noch 2 weitere Möglichkeiten

b) Du hast sound.c in einem anderen Projekt schon zu einem Objekt-File
   sound.o kompiliert. Dann kannst Du dieses auch Deinem Projekt
   hinzufügen.

c) Du hast sound.c und andere Dateien mit oft benötigten Funktionen in
   einem seperaten Projekt compiliert und zu einer Bibliothek (.a, .lib
   oder so ähnlich) gelinkt. Dann kannst Du auch diese Bibliothek zu 
Deinem
   neuen Projekt hinzufügen

Ich kenne jetzt das AVRStudio nicht (bzw. habe es nie verwendet). Aber 
was vermutlich nicht geht ist was Du Dir anscheinend vorstellst: Ich 
glaube nicht das AVRStudio anhand eines angegebenen Header-Files 
automatisch nach einer Implementierung der Methdoden in einer anderen 
Datei (sei es .c zum selbst compilieren, oder .o bzw. .a) sucht.

von atat (Gast)


Lesenswert?

Ich traue mich gar nicht zu fragen... aber steht in main.c auch folgende 
Zeile:
1
#include "sound.h"
??

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Christoph Mauchle wrote:

> Genau das ist es, was ich eben nicht machen möchte.
> Ich möchte die sound.h-Datei genau so wie zum Beispiel #include
> <avr/io.h> einbinden können. Ohne die .c oder auch die .h Dateien dem
> Projekt zu zu ordnen.

Dann musst du bei der sound.h dafür sorgen, dass der Präprozessor 
sound.h auch selbst findet. Also bei der Verwendung von "" den Pfad mit 
angeben oder bei Verwendung von <> sound.h in den Standard-Includepfad 
einordnen (IMHO keine gute Idee) oder den Standard-Includepfad erweitern 
(Kompileroptionen).

Bei der sound.c sehe ich nur den Weg, die Datei in die Liste der 
Quelldateien des Projekts zu nehmen. Wenn du das vermeiden willst, 
könntest du aus der kompilierten sound.c eine Library machen und dann 
die Library unter den mit zu linkenden Dateien in die 
Projekteinstellungen (d.h. Linkeroptionen) aufnehmen. Ist aber gehupst 
wie gesprungen ;-)

von Christoph M. (fakulatus)


Lesenswert?

Danke Dirk, dachte schon mein Problem versteht niemand :) Du hast das 
Problem erkannt.
@all: Ein wenig programmieren kann ich, also fehlerhafte #include finde 
ich hoffentlich selber noch raus g

Dirk Dörr wrote:
> c) Du hast sound.c und andere Dateien mit oft benötigten Funktionen in
>    einem seperaten Projekt compiliert und zu einer Bibliothek (.a, .lib
>    oder so ähnlich) gelinkt. Dann kannst Du auch diese Bibliothek zu
> Deinem
>    neuen Projekt hinzufügen

Jopa! Habe versucht .a zu erstellen. Will bei mir irgendwie nicht so 
ganz. Wie erstellt man die ganz genau (habs mit cygwin versucht) und 
wohin legt man die?

Stefan "stefb" B. wrote:
> Bei der sound.c sehe ich nur den Weg, die Datei in die Liste der
> Quelldateien des Projekts zu nehmen. Wenn du das vermeiden willst,
> könntest du aus der kompilierten sound.c eine Library machen und dann
> die Library unter den mit zu linkenden Dateien in die
> Projekteinstellungen (d.h. Linkeroptionen) aufnehmen. Ist aber gehupst
> wie gesprungen ;-)

na joa, auch wenn gehupst oder gesprungen, genau das will ich g
Nur wie?

Dirk Dörr wrote:
> Ich glaube nicht das AVRStudio anhand eines angegebenen Header-Files
> automatisch nach einer Implementierung der Methdoden in einer anderen
> Datei (sei es .c zum selbst compilieren, oder .o bzw. .a) sucht.

Das kann gut sein. Hätte die Header eben gerne schön lesbar beibehalten 
wollen..

von Stefan B. (stefan) Benutzerseite


Lesenswert?

Christoph Mauchle wrote:

>> ... Wenn du das vermeiden willst,
>> könntest du aus der kompilierten sound.c eine Library machen und dann
>> die Library unter den mit zu linkenden Dateien in die
>> Projekteinstellungen (d.h. Linkeroptionen) aufnehmen. Ist aber gehupst
>> wie gesprungen ;-)
>
> na joa, auch wenn gehupst oder gesprungen, genau das will ich *g*
> Nur wie?

Habe ich in der Praxis noch nie gemacht und kenne nur vom Hörensagen:

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

Beitrag "AVR Studio, Library erstellen"
Beitrag "Eclipse+WinAVR- Wie Library erzeugen?"
Beitrag "Library erzeugen in AVR Studio"

http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=52792
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=345628

von Dirk D. (dirkd)


Lesenswert?

Erst einmal, aus meiner Sicht sind Deine Ansätze:

- Keine Implementierung im Header-File
- Häufig benötigte Funktionen auslagern

gut.

Das AVRStudio kann sich die Implementierung nicht anhand der 
Header-Files suchen, weil:

- Es in C keine Vorschrift gibt das die Implementierung von Funktionen 
die
  im File x.h deklariert wurden (könnte auch x_impl.c genannt werden 
oder
  auch abc.c) auch in einem x.c zu erstellen sind. Und es
  ist auch nicht gesagt, daß es ein Objektfile x.o mit diesen
  Implementierungen gibt.

- Das AVRStudio kann selbst wenn es das .c File findet nicht wissen kann
  wie (mit welchen Optionen) es dieses File compilieren soll.

  Sobald das .c File in das Projekt eingebunden wird ist es wiederum 
klar
  mit welchen Optionen es compiliert wird.

Wenn man jetzt den Ansatz "Verwendung einer Library" verwendet, dann 
mußt Du in einem seperaten Projekt die Source-Files übersetzen und 
anschließend mit avr-ar die Objekt-Files zu einem .a zusammenlinken.

Ich habe die Optionen jetzt nicht im Kopf. Es könnte ungefähr so 
aussehen:

avr-ar rcs soundLib.a sound.o

Dieses .a mußt Du dann in Dein anderes Projekt hinzufügen. Dabei kannst 
Du das .a in Dein Projekt-Verzeichnis kopieren; Du kannst aber auch 
direkt auf das erzeugte .a verweisen.

von Dirk D. (dirkd)


Lesenswert?

> im File x.h deklariert wurden (könnte auch x_impl.c genannt werden
> oder
>  auch abc.c) auch in einem x.c

Ooops, falsche Stelle für den Kommentar in der Klammer

 im File x.h deklariert wurden auch in einem x.c   (könnte auch x_impl.c
  genannt werden oder  auch abc.c)

von Christoph M. (fakulatus)


Lesenswert?

Habt vielen Dank

Genau das habe ich gesucht. Heute leider keine Zeit mehr, doch morgen 
wirds ausprobiert :)

Meld mich

von Christoph M. (fakulatus)


Lesenswert?

So ganz will das nicht klappen. Der mekert noch etwas von wegen er könne 
die erzeugte elf-Datei nicht an erwarterter Stelle finden.

Glaub aber, dass das Problem sonst irgendwo liegt.

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.