2012-03-06 87 views
4

我無法在Ubuntu 11.10中獲得gcc以正確鏈接谷歌perftools -lprofiler。 問題似乎是鏈接器放棄了不直接在程序中使用的庫。Ubuntu 11.10連接perftools庫

一個例子會有所幫助。

讓我們把這種main.cpp中:

#include <math.h> 

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

    return 0; 
} 

編譯使用:使用LDD ./main

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

檢查可執行文件:

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) 

通常情況下,我會運行:

CPUPROFILE=/tmp/profile ./main 

生成配置文件輸出。但由於沒有生成配置文件輸出,因此配置文件庫未鏈接。

我確定profiler庫位於我的搜索路徑中,並嘗試直接連接到共享庫和靜態庫。

上述測試工作正常在Ubuntu 10.04,10.10的Ubuntu的,Ubuntu 11.04,SUSE 12.1,和Fedora 16.

另外,一旦予包括使用分析器(如ProfilerStart()和ProfilerStop(函數調用)),然後探查器庫被鏈接到可執行文件中。

有關如何讓gcc鏈接到探查器庫的任何想法?

謝謝。

+0

我不太瞭解perftools,但如果您不調用任何函數,它會如何有所幫助?如果代碼被鏈接但沒有被調用,或者根本不存在,有什麼區別? – 2012-03-06 04:19:07

+1

嘗試'g ++ main.o -o main -Wl,-no-as-needed -lm -lprofiler'並檢查'ldd' – 2012-03-06 05:40:00

回答

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

由於another.anon.coward評論,您使用的--as-needed鏈接器標記可能下降的g++的受害者。試試這個:

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

注:

  1. g++已經增加了-lm,無需再次
  2. 添加它打開--as-needed回來是很重要的。不這樣做可能會導致您鏈接到其他您不需要的庫。
3

在我的情況下,問題是,有隻libprofiler.so.0,並沒有libprofiler.so/usr/lib/

[email protected]:/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 

我不知道這個官方的解決辦法是什麼,但我只是創建在/ usr/lib下一個符號鏈接:

[email protected]:/usr/lib$ sudo ln -s libprofiler.so.0 libprofiler.so 

這將使-lprofiler工作。

如果你不介意改變你的Makefile,你可以指定-l:libprofiler.so.0而不是-lprofiler(注意多餘的冒號)(source)。

編輯:官方的方式來獲得.so顯然是安裝libgoogle-perftools-dev包作爲解釋here

[email protected]:/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 

我明白,如果你想鏈接到某個特定的lib,你應該安裝libx-dev包,其中將包含/usr/lib/libx.so。這個文件只能是特定版本的符號鏈接,如/usr/lib/libx.so.1.2。當你通過指定-lx鏈接到你的鏈接器時,你實際上會在你的程序中創建一個與當時鏈接的特定版本的鏈接,通過錄制libx.so.1的SONAME(最後版本號被剝離爲here)。因此,當您在稍後的時間點運行程序時,動態鏈接程序將只顯示/usr/lib/libx.so.1,它符號鏈接到/usr/lib/libx.so.1.2,並且沒有/usr/lib/libx.so因此沒有dev程序包需要存在。

所以libx-dev包是編譯和鏈接對libx,並且libx包是針對libx運行的預編譯程序。