【问题标题】:Ubuntu 11.10 linking perftools libraryUbuntu 11.10 链接 perftools 库
【发布时间】:2012-03-23 13:45:06
【问题描述】:

我无法在 Ubuntu 11.10 中让 gcc 正确链接到 google perftools -lprofiler。 问题似乎是链接器丢弃了程序中不直接使用的库。

举个例子会有所帮助。

我们称之为 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;
}

编译使用:

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

使用 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)

通常,我会跑:

CPUPROFILE=/tmp/profile ./main

生成配置文件输出。但由于配置文件库未链接,因此不会生成配置文件输出。

我已确保探查器库位于我的搜索路径中,并已尝试直接链接到共享库和静态库。

上述测试在 Ubuntu 10.04、Ubuntu 10.10、Ubuntu 11.04、SUSE 12.1 和 Fedora 16 上运行良好。

此外,一旦我包含使用探查器的函数调用(例如 ProfilerStart() 和 ProfilerStop()),探查器库就会链接到可执行文件中。

关于如何让 gcc 链接到分析器库中的任何想法?

谢谢。

【问题讨论】:

  • 我对 perftools 了解不多,但是如果你不调用它里面的任何函数,它有什么用呢?如果代码已链接但未调用或根本不存在,有什么区别?
  • 尝试g++ main.o -o main -Wl,-no-as-needed -lm -lprofiler并检查ldd

标签: c++ c ubuntu linker


【解决方案1】:
g++ main.o -o main -lm -lprofiler

正如另一个.anon.coward 评论的那样,您可能会成为使用--as-needed 链接器标志的g++ 的受害者。试试这个:

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

注意事项:

  1. g++已经加了-lm,不用再加了
  2. 重新打开--as-needed 很重要。不这样做可能会导致您链接到您并不真正需要的其他库。

【讨论】:

    【解决方案2】:

    在我的例子中,问题在于/usr/lib/ 中只有一个libprofiler.so.0,而没有libprofiler.so

    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
    

    我不知道官方对此的修复是什么,但我只是在 /usr/lib 中创建了一个符号链接:

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

    这将使-lprofiler 工作。

    如果您不介意更改 Makefile,您也可以指定 -l:libprofiler.so.0 而不是 -lprofiler(注意额外的冒号)(source)。

    编辑:获取.so 的官方方法显然是按照here 的解释安装libgoogle-perftools-dev 包:

    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
    

    我知道如果你想链接到某个库,你应该安装libx-dev 包,其中将包含/usr/lib/libx.so。该文件将只是一个特定版本的符号链接,例如/usr/lib/libx.so.1.2。当您通过将-lx 指定给链接器来链接/usr/lib/libx.so 时,您实际上将通过记录libx.so.1 的SONAME 在您的程序中针对当时链接的特定版本创建一个链接(最后一个版本号被剥离为oulined here)。因此,当您稍后运行程序时,动态链接器将仅查找与/usr/lib/libx.so.1.2 符号链接的/usr/lib/libx.so.1,并且没有/usr/lib/libx.so,因此不需要存在dev 包。

    所以libx-dev 包用于针对libx 进行编译和链接,libx 包用于针对libx 运行预编译程序。

    【讨论】:

      猜你喜欢
      • 2012-01-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-11
      • 1970-01-01
      • 2011-12-08
      相关资源
      最近更新 更多