c3d2-wiki/GNUCompilerCollection%2FLin...

67 lines
3.0 KiB
Plaintext

Das Bsp.:
<code>
#include <stdio.h>
#include <math.h>
/*
k = k0*(1+z)^n
k/k0 = (1+z)^n
log(k/k0) = log((1+z)^n)
=n*log(1+z)
n=log(k/k0)/og(1+z)
*/
double anlagedauer(double k0, double k, double z){
return log(k/k0)/log(1+z);
}
int main(){
double k0=100, // startkapital
k=110, //endkapital
z=0.01; //zins
printf("Anlagedauer: %lf\n", anlagedauer(k0, k, z) );
getchar();
return 0;
}
</code>
lässt sich nicht durch den einfachen Aufruf
:<code>gcc anlagedauer.c</code>
compilieren, der Linker meldet "Fehler 1", auch die suche nach der ''math.h'' hilft hier nicht weiter, makros zur Steuerung der Header-Dateien sind hier also eine Sackgasse.
stattdessen muss die option ''-lm'' ergänzt werden
:<code>gcc -lm anlagedauer.c</code>
damit die Quelle fehlerfrei baut.
'''Zur Erklaerung:''' der Linker der Gnu-Compiler-Collection der normalerweise auf x86 Systemen verwendet wird ist ld. Ld linkt standardmaessig C-Programme gegen 3 Bibliotheken:
<code>
$ ldd a.out
linux-vdso.so.1 (0x00007fff8edda000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f6f91338000)
/lib64/ld-linux-x86-64.so.2 (0x00007f6f916e2000)
</code>
* linux-vdso.so.1 - Frueher auch linux-gate.so, ist ein virtual dynamic shared object. Es verbleibt im Addressraum eines jeden Prozesses und ermoeglicht es Nutzerprogrammen Systemfunktionen ueber die entsprechend vom Prozessor unterstuetzte Schnittstelle (frueher Software Interrupts, heute Fast System Call Interface) aufzurufen.
* libc.so.6 - Ist deine libc, da ist die Implementation deiner Standardbibliothek verborgen.
* ld-linux-x86-64.so.2 - Beinhaltet den Code der verantwortlich fuer das dynamische linken ist.
Moechte man das linken gegen diese 3 Bibliotheken unterbinden, so kann man dies tuen mit <code>-nostdlib</code> und <code>-nodefaultlibs</code> (siehe z.B. gcc manpage).
Generell, muss man alle anderen Bibliotheken gegen die man linken moechte explizit angeben.
Warum die <code>libm</code> nicht in der <code>libc</code> enthalten ist hat historische Gruende die ich jetzt nicht ausfuehren moechte.
Desshalb muss man wenn die <code>math.h</code> genutzt wird mit <code>-lm</code> gelinkt werden.
<code>
$ ldd ./a.out
linux-vdso.so.1 (0x00007fff1a3fc000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f5b6af83000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5b6abdb000)
/lib64/ld-linux-x86-64.so.2 (0x00007f5b6b286000)
</code>
Wichtig ist jedoch das es sich hierbei um keinen Fehler oder ungewoehnliches Verhalten handelt. Die meisten C Compiler Verhalten sich so.
Ich hoffe die kurze und sehr Oberflaechliche Erklaerung, tut nicht mehr fragen auf als sie beantwortet.
Ganz gute Referenzen sind:
[http://www.ibm.com/developerworks/library/l-lpic1-v3-102-3/ Learn Linux, 101: Manage shared libraries]
[http://www.network-theory.co.uk/docs/gccintro/ Introduction to GCC]
[http://autotoolset.sourceforge.net/tutorial.html#SEC36 Learning the GNU development Tools]