codelite und libraries



  • Hallo Community,

    ich habe mich entschieden erstmal mit CodeLite zu arbeiten und habe wahrscheinlich gleich meine ersten Anfängerfehler zu verkraften, die ich trotz intensiver Bemühungen nicht selber gelöst bekomme. Konkret:

    #include <windows.h>
    ...
    wc.hbrBackground = static_cast<HBRUSH>(::GetStockObject(WHITE_BRUSH));
    

    ´
    Diese beiden Zeilen sollten ausreichen um mein Problem zu schildern, denn wahrscheinlicherweise der Linker sagt mir beim Kompilieren

    undefined reference to `GetStockObject@4'

    Der Compiler meldet keine Fehler, denn in der letzten Zeile steht 0 Warnings, 0 Errors. Das heißt mit include windows.h wurde die Deklaration von GetStockObject gefunden, weil windows.h auch wingdi.h inkludiert, wo GetStockObject deklariert ist und weswegen der Compiler sich auch nicht beschwert. Warum beschwert sich dann also der Linker?? Findet er die Definitionen nicht, und wenn ja, warum nicht??

    Bei der Installation von CodeLite wurden die Headerdateien wohl unter

    C:\MinGW-4.4.0\include

    gespeichert, wo ich auch windows.h gefunden habe, und ich denke die zugehörigen libraries werden auch irgendwo gespeichert sein, naheliegenderweise unter

    C:\MinGW-4.4.0\lib

    aber da finde ich nicht wingdi.dll, sondern eine libgdi32.a und ich weiß nicht mal ob das die library ist, die dazu passt. Ich habe nicht herausgefunden wo ich bei CodeLite schauen muss um herauszufinden

    1. wo CodeLite standardmäßig nach Definitionen für von .h-Dateien definierten Sachen sucht
    2. nach welchem Format für die Namen von Definitionsdateien Ausschau hält, also wenn xxx.h, dann xxx.dll bzw. xxx.exe, oder libxxx.a oder was auch immer

    Ich finde, wenn CodeLite im MinGW-Directory schon die Headerdateien zur Verfügung stellt, warum sorgt es denn nicht auch dafür, dass die Definitionsdateien auch automatisch gefunden werden, wenn man die Header schon inkludiert.

    Oder liegt mein Problem ganz wo anders...

    Danke schon mal für eure erleuchteten Antworten!! 🙂



  • ich hatte vorkurzen selbst das problem, weis aber nicht mehr genau wie ich es gelöst habe. Ich glaube bei mir lags am compiler, versuch es doch mal mit visual c++ oder dev c++.



  • Hi neo47,

    ich habe mich einfach an das hauseigene Forum von CodeLite gewendet und mein Problem da noch einmal geschildert. Da das Forum vom Meister persönlich geleitet wird habe ich auch von ihm, also dem Entwickler von CodeLite, eine Antwort innerhalb von wenigen Minuten bekommen. Ja er hat mein Problem gelöst, indem er mir geschrieben hat, dass ich das Library doch höchstpersönlich (also manuell) einbinden müsste, und welche Schritte in der IDE dafür nötig sind, obwohl die Headerdateien doch durch einfaches include gefunden worden waren.

    Schade, dabei dachte ich eher, dass wenn die Pfade für Headerdateien schon bekannt sind, dass dann auch die Pfade für die entsprechenden Libraries auch bekannt gemacht worden sind. Da CodeLite mit MinGW installierbar ist, und ich das getan habe und die von mir gesuchte library im entsprechenden Ordner unter MinGW/lib vorhanden ist bin ich eigentlich fest davon ausgegangen, dass ich nichts extra angeben muss, zumal der entsprechende Header beim include keine probleme machte. Ich muss ja auch (zumindest per Hand) keine library angeben wenn ich iostream inkludiere, aber das ist vielleicht, weil das eine "essentielle" Headerdatei der Sprache ist.

    Naja, ich war schon etwas enttäuscht, als ich hier kein feedback bekommen habe bisher, aber das mag auch daran liegen, dass die Leute lieber mit anderen IDEs arbeiten als mit CodeLite und deswegen einfach nicht wissen was zu tun ist.

    Übrigens wird von dev c++ gesagt, dass sie seit Jahren nicht mehr weiterentwickelt und damit veraltet ist, dann doch eher CodeLite oder die anderen verbreiteten Umgebungen :-).



  • Hiho! Das nenn ich mal 'ne kompetente Fehlerbeschreibung fuer 'nen Anfaenger 👍

    Du hast das Problem korrekt erkannt: der Linker findet die Library nicht. Das liegt daran, dass du dem Linker explizit sagen musst, welche Dateien er mitlinken soll.

    Sprich: es reicht nicht, dass du ihm sagst, wie das Verzeichnis heisst, wo die Bibliothek liegt, du musst ihm auch sagen wie sie heisst!
    Sonst muesste der Linker sonst ja bei jeder Funktion wissen, in welcher Datei sie denn gespeichert ist um die korrekte Datei zu linken. Aber was wenn 2 Bibliotheken Funktionen gleichen Namens enthalten? Oder wenn ein Entwickler 2 Versionen der gleichen Bibliothek installiert hat?

    Ich kenn CodeLite leider nicht, aber ich bin mir sicher du findest irgendwo in den Einstellungen 'ne Option, Libraries mitzulinken.

    aber da finde ich nicht wingdi.dll, sondern eine libgdi32.a und ich weiß nicht mal ob das die library ist, die dazu passt.

    Vermutlich passt die libgdi32.a ".dll"-Dateien sind das, was die fertige exe ladet wenn sie ausgefuehrt wird, hier steht der eigentliche Programmcode der Funktion. Aber die ".a" oder "*.so" Dateien sind jene, die der GCC beim Linken benoetigt. Hier steht dann sowas drinnen wie "ja, die eigentliche Funktion steckt in der windgi.dll, die musst du laden sobald du die funktion ausfuehren willst".

    Ich habe nicht herausgefunden wo ich bei CodeLite schauen muss um herauszufinden

    1. wo CodeLite standardmäßig nach Definitionen für von .h-Dateien definierten Sachen sucht
    2. nach welchem Format für die Namen von Definitionsdateien Ausschau hält, also wenn xxx.h, dann xxx.dll bzw. xxx.exe, oder libxxx.a oder was auch immer

    wie gesagt, Library-Dateien musst du explizit angeben. Ausserdem musst du angeben, in welchen Verzeichnissen danach gesucht werden soll, wobei das $COMPILERVERZEICHNIS/lib und noch ein paar andere Standardmaessig durchsucht werden.

    Beim Format gibts mehrere moeglichkeiten. In der Regel will der GCC/MinGW das so:
    Library-Namen beginnen meistens mit "lib". Du musst dem Compiler entweder Den namen aber ohne dem "lib" und ohne die Endung mitgeben, oder beides mitgeben. Z. b. wenn die Library "libFoo.a" heisst, dann musst du entweder dem GCC sagen, er soll "Foo" oder "libFoo.a" mitlinken.
    Wo du das in CodeLite Einstellst, musst du aber selbst rausfinden.



  • cilker schrieb:

    Ich muss ja auch (zumindest per Hand) keine library angeben wenn ich iostream inkludiere, aber das ist vielleicht, weil das eine "essentielle" Headerdatei der Sprache ist.

    Das liegt daran, dass es da keine library-Datei mehr gibt, die dazugelinkt werden muesste, weil der ganze Code bereits in der Header-Datei steht. 😉



  • Okay Bluetiger I'll accept what you write about.. oh ist ein deutsches Forum sorry, ich war nur kurz auf deiner Homepage ;-). Was du über iostream schreibst ist interessant und war mir neu und erklärt ein paar Fragen. Ich muss mich wohl daran gewöhnen, dass es für den Linker keine Namenskonventionen gibt (geben kann) zwischen Headern und Libraries und dass ich alle Libs per Hand linken muss (puh).
    Aber du schreibst

    Aber was wenn 2 Bibliotheken Funktionen gleichen Namens enthalten?

    Ich denke das dürfte eh nicht erlaubt sein durch die ODR (one definition rule). Und

    Oder wenn ein Entwickler 2 Versionen der gleichen Bibliothek installiert hat?

    Ich denke dann sollte der Entwickler einen anderen Pfad mit der Konvention identischem Namen für seine Lib angeben, oder dann per Hand verlinken. Meine intuitive Vorstellung wäre gewesen, dass es quasi Default-Konventionen gibt, nach denen der Linker erstmal versucht die Sachen auch so zu finden, aber was solls, ich gebe mich geschlagen und ansonsten danke für deine Kompetente Antwort!



  • Hoppla, hab deine Antwort hier uebersehen 😉

    cilker schrieb:

    Okay Bluetiger I'll accept what you write about.. oh ist ein deutsches Forum sorry, ich war nur kurz auf deiner Homepage ;-). Was du über iostream schreibst ist interessant und war mir neu und erklärt ein paar Fragen. Ich muss mich wohl daran gewöhnen, dass es für den Linker keine Namenskonventionen gibt (geben kann) zwischen Headern und Libraries und dass ich alle Libs per Hand linken muss (puh).
    Aber du schreibst

    Aber was wenn 2 Bibliotheken Funktionen gleichen Namens enthalten?

    Ich denke das dürfte eh nicht erlaubt sein durch die ODR (one definition rule).

    Na ja, ich meinte ja nicht im selben Programm, sondern ueberhaupt! Der Linker "sieht" ja nicht mehr, welche Dateien du inkludiert hast!
    Du stellst es dir ja so vor: der User inkludiert "blabla.h", und darin ist eine Funktion namens "foo" enthalten. Der Code fuer "foo" befindet sich in "blabla.so". Der Linker soll jetzt automatisch wissen "blabla.h" wurde inkludiert, also muss ich "blabla.so" mitlinken. Dass es in irgend einer anderen *.so-Datei (z. B. "baz.so") noch eine andere Funktion 'foo' gibt, die aber ganz was anderes tut, soll dem Linker egal sein.

    Zu dem Zeitpunkt, wo der Linker arbeitet, sieht er nur noch "eine Funktion 'foo' wurde aufgerufen, den Code fuer 'foo' hab ich aber nicht". Da er keine Information hat, welche includes im Quellcode standen, kann er nicht wissen, ob er jetzt 'baz.so' oder 'blabla.so' dazu linken soll.

    Zugegeben, das ganze koennte man irgendwie umgehen, indem man sich 'nen intelligenten Compiler/Linker schreibt, wo der Compiler irgendwo abspeichert, welche Dateien inkludiert wurden und der Linker dann daraus mit Hilfe einer Datenbank weiss, welche Datei dann dazu gelinkt werden muss. Allerdings muss die dann vom Benutzer verwaltet werden (schliesslich kann sich der ja jederzeit entscheiden, *.so-Dateien einfach umzubenennen, und dann steht der Linker bloed da), und angesichts der Tatsache, dass Includes (besonders bei groesseren Bibliotheken) selbst wieder zig Includes haben, wuerde die Datenbank sehr schnell uuuuuuunglaublich gross werden, was den Linkvorgang sehr verlangsamt.


Anmelden zum Antworten