• Apfeltalk ändert einen Teil seiner Allgemeinen Geschäftsbedingungen (AGB), das Löschen von Useraccounts betreffend.
    Näheres könnt Ihr hier nachlesen: AGB-Änderung
  • Was gibt es Schöneres als den Mai draußen in der Natur mit allen Sinnen zu genießen? Lasst uns teilhaben an Euren Erlebnissen und macht mit beim Thema des Monats Da blüht uns was! ---> Klick

XCode: externe Bibliotheken einbinden

MacEmmi

Cox Orange
Registriert
20.08.07
Beiträge
97
Hallo,

wie kann ich in XCode externe Bibliotheken (Open-Source, z.B. via FINK) einbinden und mit dem Bundle ausliefern? Die Bibliotheken liegen als statische oder dynamische Binaries vor (keine Frameworks) und haben in der Regel selbst nochmal Abhängigkeiten zu anderen Bibliotheken.
In der Entwicklungsphase ist das sehr einfach - ich habe die libs einfach in XCode eingebunden und den lib-Suchpfad auf das FINK-Verzeichnis gestellt. Für eine Auslieferung ist das aber nicht geeignet, da ich nicht voraussetzen möchte, dass der Benutzer vorher alle möglichen FINK-Pakete installieren muss.
Ich hab mir zwar jetzt ein Buch über XCode gekauft, das bringt mich aber auch nicht weiter. Dort wird davon ausgegangen, dass man mit Frameworks arbeitet.
Also, wie kann ich das gescheit ausliefern und wie löse ich die Abhängigkeiten zu weiteren libs auf ?

Viele Grüße,
Frank
 

below

Purpurroter Cousinot
Registriert
08.10.06
Beiträge
2.858
Vielleicht hab ich mir über die Weihnachtstage das Hirn weggezuckert, aber wenn ich nicht spinne dann:

Werden STATISCHE Libraries in Dein Binary kopiert. Das Problem sind dann Abhängigkeiten. Die kannst Du lösen, in dem Du auch die anderen Libaries statisch mit linkst.

Alex

EDIT: Xcode. Big X, little c
 

GoaSkin

Gast
Statische Bibliotheken (.a-Dateien) werden - wenn sie statisch in das Programm gelinkt werden - in die Binärdatei mit eingebunden. In diesem Falle werden einfach die darin enthaltenen Funktionen im Programm positioniert und in der Symbol-Tabelle entsprechende Verweise zu deren Startpunkten eingetragen.

Wenn dynamische Bibliotheken (.dylib) genutzt werden, so wird in der Symbol-Tabelle ein Verweis auf eine externe Funktion eingebettet. Ein Programm muß nicht alles statisch oder alles dynamisch linken. Dies ist für jede Abhängigkeit individuell. Zu dem liegen manche Funktionen nur in einer dynamischen Bibliothek vor und andere nur als statische Objekte. Die Qual der Wahl gibt es nicht immer. Ferner können auch die Funktionen in einer eingebundenen statischen Bibliothek eine neue dynamische Bibliothek als Abhängigkeit haben.

Der Linker bindet statische Objektdateien normalerweise vollständig ungeachtet davon, was von den Funktionen wirklich benötigt wird ein. Was nicht benötigt wird, lässt sich aus dem Endprodukt jedoch mit dem Strip-Befehl entfernen. Die Option Dead Code Stripping in XCode arbeitet meist nicht optimal, da der genannte Befehl meist trotzdem noch etwas unnötiges zum Herausschneiden findet.

Der Data Fork eines Programmes besteht zunächst aus einer Funktionsliste (Symbol Table), in der die Namen der Symbole (Funktionen, Typendefinitionen, Konstanten etc.), eine numerische ID und eine Verknüpfung dorthin (Position im Binärprogramm, externe Datei oder LD-Cache Eintrag) zu finden sind. Die Funktion _main wird in der Regel zum Laden des Programmes ausgeführt. Die anderen Funktionen werden verkettet durch einen Aufrufbefehl im Assemblercode aufgerufen, wobei dort die numerische ID aus der Symboltabelle zum Einsatz kommt.

Für die elemantaren Funktionen erzeugt der Linker normalerweise keine Datei-Referenzen, da er davon ausgeht, daß das Betriebssystem diese über den LD-Cache findet. Wenn ein Programm mit der Begründung unresolved symbols abbricht, so ist jemand davon ausgegangen, daß das Betriebssystem ihren Standort kennt, was aber nicht so ist.
 

MacEmmi

Cox Orange
Registriert
20.08.07
Beiträge
97
Vielen Dank für die ausführlichen Erläuterungen!
Offensichtlich hab ICH mir über Weihnachten das Hirn weggezuckert - das direkte Einbinden der statischen libs funktioniert. Die weiteren, abhängigen libs sind wohl in den statischen libs bereits mit eingebunden, so dass ich hier nichts weiter tun muss.
Es würde mich aber trotzdem mal interessieren wie ich vorgehen müßte, wenn ich nur dylibs (keine Frameworks) hätte. Wie kann ich die in das Bundle aufnehmen und so konfigurieren, dass der loader sie automatisch findet?
Würde es reichen, sie in Xcode unter Products mittels "Add - Existing File..." einzubinden und dann den Suchpfad entsprechend zu setzen?
 

GoaSkin

Gast
Du musst immer bedenken, daß das Programm nicht nur du benutzt, sondern auch andere. Bei dir mögen irgendwo brauchbare Bibliotheken liegen und XCode dies als selbstverständlich ansehen. Auf einem anderen System wiederrum kann es vorkommen, daß die Bibliothek nicht gefunden wird.

Man sollte immer versuchen, das Programm auf einem nackten System zu testen. Es gibt Möglichkeiten, statische Pfade zur Lib-Suche zu definieren, wobei das System wenn es sie dort nicht ist in ein paar Standard-Ordnern sucht. Einer ist der Ordner, in dem das Programm Bundle liegt. Ob er mit ?.app/Contents/Resources/ zu frieden ist müsste ausprobiert werden. Genauso bin ich überfragt, ob ein Anpassen der Info.plist etwas bringt.

Mit dem otool-Programm lässt sich nachschauen, welche dylib-Dateien ein Programm benötigt.
 

below

Purpurroter Cousinot
Registriert
08.10.06
Beiträge
2.858
Würde es reichen, sie in Xcode unter Products mittels "Add - Existing File..." einzubinden und dann den Suchpfad entsprechend zu setzen?

Im Prinzip schon. Aber weitere Antworten kann ich erst 2008 geben: Jetzt bin ich zu Müde, und morgen wird gefeiert!

Alex
 

MacEmmi

Cox Orange
Registriert
20.08.07
Beiträge
97
Also ich probiere das jetzt bereits seit Wochen aus - ohne Erfolg.
Ich habe Fink-Bibliotheken und die haben wohl einen harten Pfad (in meinem Fall /sw/lib/..) drin. Ich kann die hinschieben wo ich will, DYLD_LIBRARY_PATH setzen wie ich will, es kommt immer die Meldung "image not found" und der Linker sucht IMMER unter /sw/lib.
Sind dynamische Bibliotheken wirklich immer an ihren ursprünglichen Pfad gebunden?
Das wäre ziemlicher Mist, weil ich ja nicht voraussetzen kann bzw. will dass der Benutzer Fink installiert hat und ich ihm auch nicht unbedingt ein /sw/lib anlegen will.
Die Option mit den statischen libs ist schön und gut, allerdings hab ich jetzt das Pech, dass eine von mir benötigte Bibliothek unbedingt mit dlopen() dynamisch libs nachladen will...
Es ist zum Heulen...:-c

Viele Grüße,
Frank