Compiling Linking Notes

From HerzbubeWiki
Jump to navigation Jump to search

File-Namen für Libraries

Library type Linux Windows
static libfoobar.a libfoobar.lib
dynamic-link / shared libfoobar.so.x.y.z, plus SymLinks libfoobar.dll


Welche Libraries verwendet ein Programm/eine Library?

Linux

% ldd foobar
       libgmodule-1.2.so.0 => libgmodule-1.2.so.0 (0x40142000)
       libglib-1.2.so.0 => libglib-1.2.so.0 (0x40145000)
       libdl.so.2 => /lib/libdl.so.2 (0x40176000)
       libXi.so.6 => /usr/X11R6/lib/libXi.so.6 (0x4017a000)
       libXext.so.6 => /usr/X11R6/lib/libXext.so.6 (0x40182000)
       libX11.so.6 => /usr/X11R6/lib/libX11.so.6 (0x40191000)
       libm.so.6 => /lib/libm.so.6 (0x4025f000)
       libc.so.6 => /lib/libc.so.6 (0x40281000)
       /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x80000000)

Windows

C:\> dumpbin /rawdata /section:.drectve foobar.obj >output.txt

Die Ausgabe in output.txt sieht dann z.B. so aus:

    -default|lib:mfc4
    0.lib -d|efaultli
    b:mfcs40|.lib -de
    faultlib|:msvcrt.
    lib -def|aultlib:
    kernel32|.lib -de
    faultlib|:user32.
    lib


Mac OS X

% otool -L foobar
       /sw/lib/libxml2.2.dylib (compatibility version 9.0.0, current version 9.20.0)
       /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 88.2.1)
       /usr/lib/libz.1.dylib (compatibility version 1.0.0, current version 1.2.3)
       /sw/lib/libiconv.2.dylib (compatibility version 6.0.0, current version 6.0.0)
       /usr/lib/libgcc_s.1.dylib (compatibility version 1.0.0, current version 1.0.0)
       /usr/lib/libmx.A.dylib (compatibility version 1.0.0, current version 92.0.0)


Welche Symbole stellt ein Programm/eine Library zur Verfügung?

ELF Files können mit readelf untersucht werden:

% readelf -s libfoobar.so.1
Symbol table '.symtab' contains 212 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     1: 000018e0     0 FUNC    LOCAL  DEFAULT   10 xxx
     2: 0000e7b0     0 OBJECT  LOCAL  DEFAULT   16 yyy
     3: 0000e7b8     0 OBJECT  LOCAL  DEFAULT   17 zzz
[...]

Für andere Objekt-Files kann nm verwendet werden (nm funktioniert auch für ELF):

% nm libfoobar.so.1
         U xxx
00010fe8 W yyy
00068718 T zzz
[...]

Wobei die Buchstaben-Codes folgende Bedeutung haben:

  • U = Undefined. Library verwendet das Symbol, definiert es aber nicht
  • W = Weak. Library definiert das Symbol, lässt aber zu, dass das Symbol anderswo neu definiert wird
  • T = Text. Library definiert das Symbol im Text (= Code) Segment
  • weitere Symbol-Typen sind möglich, siehe man nm

Kompilier-Vorgang unter Windows

  • der Compiler erzeugt aus jedem .cpp File ein .obj File
  • ein solches .obj File enthält
    • Code
    • Sections (vermutlich das gleiche wie "Segmente", also z.B. Daten-Segment, etc.)
    • Linker-Direktiven
    • externe Referenzen
    • Funktions- und Daten-Namen


Link-Vorgang unter Windows

  • es werden mehrere .obj Files zu einem .exe oder einer Library (.lib, .dll) zusammengefügt
  • Alle in den .obj Files verwendeten Symbole müssen irgendwo definiert sein. Falls nicht in anderen .obj Files des gleichen Projekts, müssen sie in externen Libraries definiert sein. Diese Libraries müssen dem Linker angegeben werden. Folgende Libraries werden beim Linken verwendet:
    • Libraries, die dem Linker explizit auf der cmdline mitgeteilt werden
    • Libraries, die dem Linker mit /DEFAULTLIB mitgeteilt werden
    • Default-Libraries, die in den .obj Files aufgeführt sind
      • dazu muss man wissen, dass der Compiler in jedes .obj File Default-Libraries schreiben kann. Automatisch tut er dies mindestens für die C Run-Time Library. Siehe dazu KB 143072
      • der Name der verwendeten C Run-Time Library hängt von der verwendeten /Mx Compiler Option ab. Im GUI von VC++ entspricht dies der Einstellung "Use Run-Time Library". Siehe dazu KB 128641. Weiter unten in diesem Topic findet sich eine Liste der möglichen Libraries.
    • Default-Libraries (ob nun mit /DEFAULTLIB angegeben, oder bereits im .obj File einkompiliert) können mit /NODEFAULTLIB bzw. /NODEFAULTLIB:libfoobar übersteuert werden


Library-Namen unter Windows

C Run-Time Library

Reusable Library Switch Library Macro(s) Defined
Single Threaded /ML LIBC (none)
Static MultiThread /MT LIBCMT _MT
Dynamic Link (DLL) /MD MSVCRT _MT and _DLL
Debug Single Threaded /MLd LIBCD _DEBUG
Debug Static MultiThread /MTd LIBCMTD _DEBUG and _MT
Debug Dynamic Link (DLL) /MDd MSVCRTD _DEBUG, _MT, and _DLL

Standard C++ Debug Library

Library Description Switch Macro(s) Defined
LIBCPD.LIB Single-threaded, static link /MLd _DEBUG
LIBCPMTD.LIB Multithreaded, static link /MTd _DEBUG, _MT
MSVCPRTD.LIB Multithreaded, dynamic link (import library for DLL) /MDd _DEBUG, _MT, _DLL
LIBCP.LIB Single threaded, static link /ML
LIBCPMT.LIB Multithreaded, static link /MT _MT
MSVCPRT.LIB Multithreaded, dynamic link (import library for DLL) /MD _MT, _DLL


iostream Debug Library

Library Description Switch Macro(s) Defined
LIBCID.LIB Single threaded, static link /MLd _DEBUG
LIBCIMTD.LIB Multithreaded, static link /MTd _DEBUG, _MT
MSVCIRTD.LIB Multithreaded, dynamic link (import library for DLL) /MDd _DEBUG, _MT, _DLL
LIBCI.LIB Single threaded, static link /ML
LIBCIMT.LIB Multithreaded, static link /MT _MT
MSVCIRT.LIB Multithreaded, dynamic link (import library for DLL) /MD _MT, _DLL

MFC Libraries

  • nafxcwd.lib: ANSI Debug
  • uafxcwd.lib: Unicode Debug
  • nafxcw.lib: ANSI Release
  • uafxcw.lib: Unicode Release


Libraries unter Windows

  • eine .lib ist immer eine statische Library
  • eine .dll besitzt immer eine zugehörige .lib. Diese .lib enthält Symbol-Informationen und wird von dem Programm dazugelinkt, das später die .dll verwenden will. Beim Linken wird - nebst den Informationen zu den Symbolen - der Programmcode erzeugt, mit dem die .dll zur Laufzeit geladen wird
  • eine .lib, die explizit als statische Library gebildet wurde, und bei der mit VC++ 6.0 Debug Informationen mit der Option "Program Database" eingebunden wurden, enthält einen hart codierten Pfad auf ein File vc60.pdb (z.B. c:\foobar\debug\vc60.pdb). Falls diese statische Library auf andere Arbeitsplätze verteilt werden soll, und auf diesen Arbeitsplätzen gibt es das File vc60.pdb nicht (oder nicht an dem hart codierten Pfad), so tritt beim Linken ein Fehler auf (LNK1202). Das Problem kann vermieden werden, indem die statische Library mit der Einstellung "Debug Info = C7 compatible" kompiliert wird. In diesem Fall wird kein hart codierter Pfad als Verweis auf vc60.pdb in die Library ein-kompiliert.


Libraries unter Mac OS X

  • Shared Libraries haben die Endung .dylib
  • die Umgebungsvariable MACOSX_DEPLOYMENT_TARGET ist wichtig fuer den Linker ld und bestimmt im Wesentlichen den kleinsten gemeinsamen Nenner, fuer den die erzeugte Library lauffaehig sein soll (z.B. schaltet ldd Features aus, die es nur in 10.4 gibt, wenn die Umgebungsvariable auf <=10.3 gesetzt wird). Siehe man page von ld
  • der Suchpfad fuer Libraries, die vom Runtime Linker dyld benoetigt werden, wird ueber die Umgebungsvariable DYLD_LIBRARY_PATH gesteuert


Debugging von Runtime Problemen unter Linux

Beim Starten eines Programms wird der Runtime Shared Library Loader (ld.so) aktiv. Er analysiert die Abhängigkeiten des zu startenden Programms, findet die benötigten Shared Libraries, lädt sie in den Speicher, nimmt allfällige Anpassungen am Programm und an den Libraries vor (z.B. Relocation), und startet schlussendlich das Programm.

Die Pfade, in denen ld.so nach Shared Libraries sucht, wird mit der Umgebungsvariablen LD_LIBRARY_PATH beeinflusst (DYLD_LIBRARY_PATH unter Mac OS X).

Die Arbeit von ld.so kann durch weitere Umgebungsvariablen beeinflusst werden. Siehe dazu "man ld.so". Um die Arbeit von ld.so zu beobachten, sind die folgenden Variablen interessant:

  • LD_DEBUG: je nachdem, welchen Wert diese Variable enthält, gibt ld.so verschiedene Arten von Informationen aus. Achtung: die Ausgabe erfolgt auf stdout! Meistens macht es Sinn, die Ausgabe in eine Datei schreiben zu lassen. Siehe LD_DEBUG_OUTPUT
    • all: gibt alle Debug Informationen aus, die ld.so überhaupt beherrscht
    • libs: zeigt die "library search paths" an, d.h. wo ld.so überall nach einem bestimmten Shared Library File sucht
    • help: gibt aus, auf welche Werte LD_DEBUG gesetzt werden kann
  • LD_DEBUG_OUTPUT: diese Variable enthält einen Filenamen. Die durch LD_DEBUG ausgelöste Ausgabe wird in dieses File geschrieben