Ubuntu 11.10, связывающая библиотеку perftools - PullRequest
4 голосов
/ 06 марта 2012

Я не могу получить gcc в Ubuntu 11.10 для правильной ссылки в 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 для ссылки в библиотеке профилировщика?

Спасибо.

Ответы [ 2 ]

4 голосов
/ 07 марта 2012
g++ main.o -o main -lm -lprofiler

Как заметил другой сайт.anon.coward, вы, вероятно, стали жертвой вашего g++, использующего флаг компоновщика --as-needed.Попробуйте вместо этого:

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

Примечания:

  1. g++ уже добавляет -lm, нет необходимости добавлять его снова
  2. Важно повернуть--as-needed обратно.В противном случае вы, вероятно, будете ссылаться на дополнительные библиотеки, которые вам на самом деле не нужны.
3 голосов
/ 08 марта 2016

В моем случае проблема заключалась в том, что в /usr/lib/ было только libprofiler.so.0, а в *1003* нет:

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, по-видимому, установить пакет 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. Когда вы ссылаетесь на /usr/lib/libx.so, указав -lx на свой компоновщик, вы фактически создадите ссылку в вашей программе на конкретную версию, на которую ссылается в тот момент, записав SONAME libx.so.1 (номер последней версии обрезается, как указано ниже). здесь ). Поэтому, когда вы запустите свою программу в более поздний момент времени, динамический компоновщик будет искать только /usr/lib/libx.so.1, который символически связан с /usr/lib/libx.so.1.2, а не /usr/lib/libx.so, следовательно, пакет dev не должен существовать.

Таким образом, пакеты libx-dev предназначены для компиляции и связывания с libx, а пакет libx предназначен для запуска предварительно скомпилированной программы с libx.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...