====== Compilation ====== ===== Environnement ===== Varibles d'environnement : * **CC** : Compilateur C (gcc, icc...) * **CXX** : Idem que CC mais pour le C++ (export CXX=$CC) * **CFLAGS** : Ce paramétrage a en général pour but d'optimiser ou déboguer le code C (CFLAGS=" -march=native -mtune=native -O3 -pipe") * **CXXFLAGS** : Idem pour le C++ (export CXXFLAGS=$CFLAGS) * **LDFLAGS** : Permet de préciser les répertoires où se trouvent les librairies (*.so) et include(*.h) (LDFLAGS=" -I/home/include -L/home/lib -lX11") ./configure CC=gcc CFLAGS=-O3 LDFLAGS=-lposix ==== Options de compilation de gcc/g++ ==== Il existe énormément d'options de compilation, nous allons en détailler quelques unes. * **-O0 à -O3** : optimisation * **-march=native / -mtune=native** : produit du code optimisé pour notre processeur. Attention le code ne sera pas lisible sur tous les ordinateurs. * **-pipe** : N'agit pas sur le code mais améliore la vitesse de compilation en passant par un pipe * **-I
#include
void boo(void)
{
puts("Hello, I'm a shared library : boo");
}
#ifndef boo_h__
#define boo_h__
extern void boo(void);
#endif // boo_h__
* Librairie //foo.c// :
#include
void foo(void)
{
puts("Hello, I'm a shared library : foo");
}
#ifndef foo_h__
#define foo_h__
extern void foo(void);
#endif // foo_h__
* Programme principal avec appel au 2 librairies :
#include
#include "foo.h"
#include "boo.h"
int main(void)
{
puts("This is a shared library test...");
foo();
boo();
return 0;
}
* Compilation en shared :
#!/bin/bash
gcc -c -Wall -Werror -fpic foo.c
gcc -shared -o libfoo.so foo.o
gcc -c -Wall -Werror -fpic boo.c
gcc -shared -o libboo.so boo.o
gcc -L. -Wall -o test main.c -lfoo -lboo
export LD_LIBRARY_PATH=.
./test
ldd test
Résultat :
root@ks305337:~/compile# ./compile1.sh
This is a shared library test...
Hello, I'm a shared library : foo
Hello, I'm a shared library : boo
linux-vdso.so.1 => (0x00007fffd5dfe000)
libfoo.so => /root/compile/libfoo.so (0x00007f4521e50000)
libboo.so => /root/compile/libboo.so (0x00007f4521c4f000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f45218ba000)
/lib64/ld-linux-x86-64.so.2 (0x00007f4522053000)
* Compilation en shared avec la librairie boo directement inclue en statique dans le binaire (noter l'utilisation du binaire ar pour obtenir un fichier archive .a à partir d'une librairie.so) :
#!/bin/bash
gcc -c -Wall -Werror -fpic foo.c
gcc -shared -o libfoo.so foo.o
gcc -c -Wall -Werror -fpic boo.c
gcc -shared -o libboo.so boo.o
ar rcs libboo.a boo.o
gcc -L. -Wall -o test main.c -lfoo ./libboo.a
export LD_LIBRARY_PATH=.
./test
ldd test
root@ks305337:~/compile# ./compile2.sh
This is a shared library test...
Hello, I'm a shared library : foo
Hello, I'm a shared library : boo
linux-vdso.so.1 => (0x00007fff757fe000)
libfoo.so => ./libfoo.so (0x00007ffa5a8f6000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007ffa5a562000)
/lib64/ld-linux-x86-64.so.2 (0x00007ffa5aaf9000)
* Compilation en shared avec les 2 librairies en statique :
#!/bin/bash
gcc -c -Wall -Werror -fpic foo.c
gcc -shared -o libfoo.so foo.o
ar rcs libfoo.a foo.o
gcc -c -Wall -Werror -fpic boo.c
gcc -shared -o libboo.so boo.o
ar rcs libboo.a boo.o
gcc -L. -Wall -o test main.c ./libfoo.a ./libboo.a
export LD_LIBRARY_PATH=.
./test
ldd test
root@ks305337:~/compile# ./compile3.sh
This is a shared library test...
Hello, I'm a shared library : foo
Hello, I'm a shared library : boo
linux-vdso.so.1 => (0x00007fff76e7d000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fabfe74f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fabfeae5000)
* En dynamique, mais en forçant automatiquement le linker (sans LD_LIBRARY_PATH) à chercher les librairies dans un répertoire :
Noter que j'ai enlever la variable LD_LIBRARY_PATH avant l’exécution du programme !
#!/bin/bash
gcc -c -Wall -Werror -fpic foo.c
gcc -shared -o libfoo.so foo.o
gcc -c -Wall -Werror -fpic boo.c
gcc -shared -o libboo.so boo.o
gcc -Wl,-rpath=/root/compile -L. -Wall -o test main.c -lfoo -lboo
./test
root@ks305337:~/compile# ./compile4.sh
This is a shared library test...
Hello, I'm a shared library : foo
Hello, I'm a shared library : boo
linux-vdso.so.1 => (0x00007fff13be7000)
libfoo.so => /root/compile/libfoo.so (0x00007fca9e569000)
libboo.so => /root/compile/libboo.so (0x00007fca9e368000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fca9dfd3000)
/lib64/ld-linux-x86-64.so.2 (0x00007fca9e76c000)
Dans l'exemple 1, les librairies n'étaient pas automatiquement trouvées, ce qui n'est plus le cas maintenant :
root@ks305337:~/compile# ldd test
linux-vdso.so.1 => (0x00007fff79eda000)
libfoo.so => not found
libboo.so => not found
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f67d24f9000)
/lib64/ld-linux-x86-64.so.2 (0x00007f67d2890000)
* En statique :
#!/bin/bash
gcc -c -Wall -Werror -fpic foo.c
gcc -shared -o libfoo.so foo.o
ar rcs libfoo.a foo.o
gcc -c -Wall -Werror -fpic boo.c
gcc -shared -o libboo.so boo.o
ar rcs libboo.a boo.o
gcc -static -L. -Wall -o test main.c ./libfoo.a ./libboo.a
export LD_LIBRARY_PATH=.
./test
ldd test
root@ks305337:~/compile# ./compile5.sh
This is a shared library test...
Hello, I'm a shared library : foo
Hello, I'm a shared library : boo
n'est pas un exécutable dynamique
* Include les 2 librairies dans une seule :
#!/bin/bash
gcc -c -Wall -Werror -fpic foo.c
gcc -c -Wall -Werror -fpic boo.c
gcc -shared -o libgigix.so boo.o foo.o
gcc -L. -Wall -o test main.c -lgigix
export LD_LIBRARY_PATH=/root/compile
./test
ldd test
root@ks305337:~/compile# ./6.sh
This is a shared library test...
Hello, I'm a shared library : foo
Hello, I'm a shared library : boo
linux-vdso.so.1 => (0x00007fff2e7fe000)
libgigix.so => /root/compile/libgigix.so (0x00007fcd2fd37000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fcd2f9a3000)
/lib64/ld-linux-x86-64.so.2 (0x00007fcd2ff3a000)
=== Compilation statique ===
Pour compiler un programme en static (par exemple python) :
./configure LDFLAGS=" -static -Wl,-static" CFLAGS=" -static-libgcc -static -march=native -mtune=native -O3 -pipe -fPIC" CC=gcc-4.8 --enable-shared=no
Pour transformer un binaire dynamique en statique, il existe des outils comme :
* [[http://sourceforge.net/projects/statifier/files/|ELF Statifier]] : mini [[http://archive09.linux.com/feature/150677|tuto]].
* [[http://www.magicermine.com/trial.html|Ermine]] : mini [[http://nathanaaron.wordpress.com/2011/08/31/building-a-portable-executable-on-linux/|tuto]]