Ubuntu 11.10 reliant la bibliothèque perftools

Je ne peux pas obtenir gcc dans Ubuntu 11.10 pour relier correctement dans le google perftools -lprofiler. Le problème semble être que l’éditeur de liens ignore les bibliothèques qui ne sont pas directement utilisées dans un programme.

Un exemple aidera.

Appelons cela main.cpp:

#include  int main() { double value; for (int i=0; i < 1000000; i++) { for (int j=0; j < 1000; j++) value = sqrt(100.9); } return 0; } 

Comstackr en utilisant:

 g++ -c main.cpp -o main.o g++ main.o -o main -lm -lprofiler 

Vérifiez l’exécutable en utilisant ldd ./main:

  linux-vdso.so.1 => (0x00007fff5a9ff000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f32bc1c9000) /lib64/ld-linux-x86-64.so.2 (0x00007f32bc593000) 

Normalement, je courrais:

 CPUPROFILE=/tmp/profile ./main 

pour produire une sortie de profil. Mais comme la bibliothèque de profils n’est pas liée, aucune sortie de profil n’est générée.

Je me suis assuré que la bibliothèque de profileurs se trouve dans mon chemin de recherche et j’ai essayé de créer des liens directs avec la bibliothèque partagée et la bibliothèque statique.

Le test ci-dessus fonctionne correctement sur Ubuntu 10.04, Ubuntu 10.10, Ubuntu 11.04, SUSE 12.1 et Fedora 16.

De plus, une fois que j’inclus les appels de fonctions qui utilisent le profileur (tels que ProfilerStart () et ProfilerStop ()), la bibliothèque du profileur est liée à l’exécutable.

Avez-vous des idées sur la manière de relier gcc à la bibliothèque de profileurs?

Merci.

 g++ main.o -o main -lm -lprofiler 

Comme l’a fait remarquer another.anon.coward, vous êtes probablement victime de votre g++ utilisant --as-needed linker flag. Essayez plutôt ceci:

 g++ main.o -Wl,--no-as-needed -lprofiler -Wl,--as-needed 

Remarques:

  1. g++ ajoute déjà -lm , pas besoin de l’append à nouveau
  2. Il est important de retourner --as-needed . Si vous ne le faites pas, vous devrez probablement vous connecter à des bibliothèques supplémentaires dont vous n’avez pas vraiment besoin.

Dans mon cas, le problème était qu’il n’y avait qu’un libprofiler.so.0 , et aucun libprofiler.so dans /usr/lib/ :

 user@compy:/usr/include$ dpkg -L libgoogle-perftools4 /. /usr /usr/share /usr/share/doc /usr/share/doc/libgoogle-perftools4 /usr/share/doc/libgoogle-perftools4/README.Debian /usr/share/doc/libgoogle-perftools4/copyright /usr/lib /usr/lib/libprofiler.so.0.4.5 /usr/lib/libtcmalloc.so.4.2.6 /usr/lib/libtcmalloc_debug.so.4.2.6 /usr/lib/libtcmalloc_and_profiler.so.4.2.6 /usr/share/doc/libgoogle-perftools4/AUTHORS /usr/share/doc/libgoogle-perftools4/TODO /usr/share/doc/libgoogle-perftools4/README.gz /usr/share/doc/libgoogle-perftools4/NEWS.gz /usr/share/doc/libgoogle-perftools4/changelog.Debian.gz /usr/lib/libtcmalloc.so.4 /usr/lib/libtcmalloc_and_profiler.so.4 /usr/lib/libprofiler.so.0 /usr/lib/libtcmalloc_debug.so.4 

Je ne sais pas ce que le correctif officiel à cela est, mais j’ai simplement créé un lien symbolique dans / usr / lib:

 user@compy:/usr/lib$ sudo ln -s libprofiler.so.0 libprofiler.so 

Cela fera fonctionner -lprofiler .

Si cela ne vous dérange pas de changer votre Makefile, vous pouvez également spécifier -l:libprofiler.so.0 au lieu de -lprofiler (notez les deux-points supplémentaires) ( source ).

EDIT: La manière officielle d’obtenir le .so est apparemment d’installer le libgoogle-perftools-dev comme expliqué ici :

 user@compy:/usr/lib$ dpkg -S libprofiler.so libgoogle-perftools-dev: /usr/lib/libprofiler.so libgoogle-perftools4: /usr/lib/libprofiler.so.0.4.5 libgoogle-perftools4: /usr/lib/libprofiler.so.0 

Je comprends que si vous souhaitez libx-dev un lien vers une certaine lib, vous devez installer le libx-dev , qui contiendra le /usr/lib/libx.so . Ce fichier ne sera qu’un lien symbolique vers une version spécifique, telle que /usr/lib/libx.so.1.2 . Lorsque vous /usr/lib/libx.so lien avec /usr/lib/libx.so en spécifiant -lx sur votre éditeur de liens, vous allez créer un lien dans votre programme avec la version spécifique liée en enregistrant un SONAME de libx.so.1 (le dernier le numéro de version est rayé comme indiqué ici ). Ainsi, lorsque vous exécuterez votre programme ultérieurement, l’éditeur de liens dynamic recherchera uniquement /usr/lib/libx.so.1 , qui est lié à /usr/lib/libx.so.1.2 , et non /usr/lib/libx.so donc, aucun paquet dev ne doit exister.

Ainsi, les libx-dev sont destinés à la compilation et à la liaison avec libx , et le paquet libx est destiné à exécuter un programme précompilé contre libx .