LINUX.ORG.RU

Unused direct dependencies && -Wl,--as-needed


0

0

Привет!

Написал программу на C++, которая линкуется так:

g++ -fPIC -MD -Wall -Wno-format-y2k -Wno-sign-compare   -pthread
-O3 -DNDEBUG 
-L/usr/local/dev/boost/lib 
-L/usr/local/dev/loki/lib
-L/usr/local/dev/ace/lib 
-L/usr/local/dev/zlib/lib 
-L/usr/local/dev/server_utils_ng/lib 
-L/usr/local/dev/oragate_ng/lib
-lloki -lACE -lz -lserver_utils_ng -loragate_ng 
-lboost_program_options-mt -lboost_regex-mt 
-o thd cache.o main.o

Вывод "ldd -u -r" вызывает некоторые подозрения:

ldd -u -r  thd 
Unused direct dependencies:
 /usr/local/dev/loki/lib/libloki.so.0.1.6
 /lib/libz.so.1
 /usr/local/dev/boost/lib/libboost_regex-gcc41-mt-1_35.so.1.35.0
 /lib/libm.so.6

Стал гуглить и нашел статью Дреппера "How to write shared libraries",
в которой говорится:

To determine whether an executable or DSO has such unnecessary 
dependencies the ldd script can be used:

$ ldd -u -r \
  /usr/lib/libgtk-x11-2.0.so.0.600.0
Unused direct dependencies:
        /usr/lib/libpangox-1.0.so.0
        /lib/libdl.so.2

These references can be manually eliminated by avoiding
to name the DSO on the linker command line. 
Alternatively the --as-needed linker option can be used. 
If this option is used, all DSOs named on the command line
after the option are only added to the dependency list if
they are really needed. This mode can be disabled again
with the --no-as-needed option. This way the lazy 
programmer can still name all the DSOs which might be
needed at all times. The linker does all the hard work.

Решил попробовать и обернул -lloki следующим образом:
 -Wl,--as-needed  -lloki -Wl,--no-as-needed

Вот что получилось:

ldd -u -r  thd 
Unused direct dependencies:

        /lib/libz.so.1
        /usr/local/dev/boost/lib/libboost_regex-gcc41-mt-1_35.so.1.35.0
        /lib/libm.so.6

После этого я решил аналогично обернуть -lz и вышло следующее:

g++ -fPIC -MD -Wall -Wno-format-y2k -Wno-sign-compare   -pthread
-O3 -DNDEBUG 
-L/usr/local/dev/boost/lib 
-L/usr/local/dev/loki/lib 
-L/usr/local/dev/ace/lib 
-L/usr/local/dev/zlib/lib 
-L/usr/local/dev/server_utils_ng/lib 
-L/usr/local/dev/oragate_ng/lib  
-Wl,--as-needed  -lloki -Wl,--no-as-needed  -lACE 
-Wl,--as-needed -lz -Wl,--no-as-needed 
-lserver_utils_ng -loragate_ng -lboost_program_options-mt -lboost_regex-mt 
-o thd cache.o main.o
/usr/local/dev/oragate_ng/lib/liboragate_ng.so: undefined reference to `inflate'
/usr/local/dev/oragate_ng/lib/liboragate_ng.so: undefined reference to `inflateInit_'
/usr/local/dev/oragate_ng/lib/liboragate_ng.so: undefined reference to `inflateEnd'
collect2: ld returned 1 exit status

То есть zlib все же нужен (как и ожидалось), но тогда почему 
"ldd -u -r" считает иначе?
Причем в случае с Loki команда ldd не соврала :)

Кто может объяснить в чем дело?

Задача состоит в том, чтобы подсовывать линкеру N библиотек, 
в то время как реально нужно только M<N.
При этом ненужные депенды должен разруливать сам линкер.
Именно об этом помоему и пишет Дреппер:

This way the lazy programmer can still name all the DSOs 
which might be needed at all times. 
The linker does all the hard work.

Например, в том же Boost'е есть как header-only "библиотеки", так
и библиотеки с которыми нужно линковаться.
Моя идея была написать что-то типа
-Wl,--as-needed ВСЕ БИБЛИОТЕКИ BOOST'а -Wl,--no-as-needed
и забыть про это навсегда.
То есть, если я подключаю к проекту boost regex, то Makefile 
менять уже не нужно. Все сделает линкер.

Krivenok_Dmitry
() автор топика
Ответ на: комментарий от Krivenok_Dmitry

> Задача состоит в том, чтобы подсовывать линкеру N библиотек, в то время как реально нужно только M<N. При этом ненужные депенды должен разруливать сам линкер.

- доктор, когда я делаю вот так - чешет левой пяткой правое ухо - у меня через какое то время начинает болеть спина!
- а вы не делайте

// wbr

klalafuda ★☆☆
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.