2012-03-06 120 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运行的预编译程序。