Linux C++ LD_LIBRARY_PATH, подавляющий стандартные библиотеки

Я новичок в C ++, хотя недавно я работал с Objective C, поэтому некоторые из них выглядят смутно знакомыми.

Я нахожусь в процессе написания нескольких тестовых программ, чтобы оценить, будет ли что-то возможно или нет. В моей (очень простой программе «Hello World») я вывожу некоторый текст, используя cout, который отлично работает, однако, когда я изменяю LD_LIBRARY_PATH, чтобы указать на некоторые библиотеки, требуемые сторонним приложением, с которым я буду общаться, я не получаю вывод, но нет ошибок компилятора от g++.

Я пробовал включать стандартные пути, например. /usr/local/lib:/usr/lib:/lib, но когда я включаю это в путь, я все равно не получаю вывода.

#include <iostream>

using namespace std;

int main()
{
    cout << "Hello World";
    return 0;
}

Как видите, на данный момент это довольно простая программа, которая работает, как и ожидалось, до того, как я установил LD_LIBRARY_PATH.

Я вообще не получаю никаких ошибок на любом этапе, поэтому я не могу узнать, работает ли он. Есть ли что-нибудь, что я могу проверить или как-то проверить, работает ли программа?

P.S. Я также пытался записать вывод в файл, который работает, прежде чем устанавливать путь.

Большое спасибо

ОБНОВИТЬ

Спасибо за ответы (результаты см. в комментариях ниже)

Основываясь на том, что @Nemo сказал о стороннем приложении, имеющем собственную версию libstdc++.so, что было правильно, я заменил их версию этой библиотеки на стандартную установочную версию. Хотя теперь я получаю вывод «Hello World», я все еще получаю множество ошибок No such file or directory при выполнении программы, поэтому я предполагаю, что проблема решена лишь частично. Я не уверен, что то, что я сделал, «разрешено» или как действовать дальше.


person olliefinn    schedule 22.07.2013    source источник
comment
Попробуйте добавить endl; в конец строки, чтобы убедиться, что проблема не только в том, что cout не сбрасывает вывод.   -  person Mats Petersson    schedule 22.07.2013
comment
LD_LIBRARY_PATH не имеет ничего общего с C++, это связано с ld .so - и он не должен переопределять системные библиотеки, если только та же библиотека не может быть найдена в вашем LD_LIBRARY_PATH. Пожалуйста, не могли бы вы показать нам точные команды, используемые для компиляции, и точные команды, используемые для запуска. Также попробуйте запустить что-то вроде strace -f _binary_ - и проверьте вывод - вы должны увидеть, что происходит из этого   -  person Iwan Aucamp    schedule 22.07.2013
comment
@Iwan: Он сказал, что настройка LD_LIBRARY_PATH требуется для стороннего приложения. По моему опыту, они часто поставляются со своей собственной версией libstdc++.so (среда выполнения C++). Я очень подозреваю, что это источник проблемы.   -  person Nemo    schedule 22.07.2013
comment
Вы пытались добавить /lib:/usr/lib перед LD_LIBRARY_PATH? Если вы работаете в 64-битной системе, пробовали ли вы вместо этого /lib64:/usr/lib64?   -  person Nemo    schedule 22.07.2013
comment
@user761389 user761389 - не могли бы вы дать нам список файлов по пути, который вы добавили в LD_LIBRARY_PATH, а также запустить ldd в своем двоичном файле с установленным путем к библиотеке ld и прикрепить вывод.   -  person Iwan Aucamp    schedule 22.07.2013
comment
Запустите ldd yourprogram с установленным LD_LIBRARY_PATH и без него. Есть ли разница в выходе?   -  person n. 1.8e9-where's-my-share m.    schedule 22.07.2013
comment
Спасибо за все ваши ответы. Чтобы просмотреть ваши предложения: добавление endl дает те же результаты. Я пытался добавить /lib:/usr/lib в начало пути, но это не внесло изменений. не получить ни одного из этих ldd'ing не дает мне вывода с установленным путем, но без такого, как libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xb6d26000) Я предполагаю, что «Нет такого файла или каталога» указывает на проблему   -  person olliefinn    schedule 23.07.2013
comment
В случае отсутствия такого файла или каталога вы указали путь к сторонним включениям, используя -I ?   -  person jbp    schedule 24.07.2013


Ответы (1)


Если вы запустите:

ldd a.out

где a.out — имя вашего исполняемого файла, он будет печатать зависимости общей библиотеки времени выполнения для этого исполняемого файла (см. http://linux.die.net/man/1/ldd )

Вот пример вывода:

linux-vdso.so.1 =>  (0x00007fff463ff000)
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007f75f6979000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f75f65ba000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f75f62bd000)
/lib64/ld-linux-x86-64.so.2 (0x00007f75f6c85000)
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007f75f60a7000)

Теперь, когда вы знаете, что ищет ваше приложение, вы должны знать, что оно ищет это в кэше LD (или кэше динамического компоновщика). Обычно он хранится в /etc/ld.so.cache. Однако не следует редактировать его вручную. Вместо этого вы должны использовать ldconfig для регенерации этого кеша.

Вы можете использовать:

ldconfig -p

Чтобы показать все записи кэша.

Когда вы бежите

ldconfig

(как root), вы восстановите ldcache. Каталоги '/lib' и '/usr/lib', а также все перечисленные в файле '/etc/ld.so.conf' сканируются по умолчанию, если только не используется `-n'. Дополнительные каталоги могут быть указаны в командной строке.

Когда исполняемый файл вызывается, он также проверяет пути в LD_LIBRARY_PATH (в дополнение к ldcache) для любых файлов, перечисленных в выводе ldd.

Итак, что вы можете сделать, это запустить:

ls -lah

в каждом из файлов, перечисленных в выводе ldd для вашего исполняемого файла. Если какие-либо файлы отсутствуют, вам придется заменить их соответствующими разделяемыми библиотеками (*.so) в каталоге /usr/lib или подобном каталоге и заново сгенерировать ldcache. После создания кеша они должны появиться в выводе ldconfig -p.

Если вы хотите добавить новые пути для включения в генерацию ldcache ldconfig, вы можете добавить их в файл /etc/ld.so.conf. Затем при следующем создании ldcache он будет искать в этих каталогах ваши общие объекты. Вы также можете поместить их в каталоги /lib или /usr/lib. Я бы рекомендовал этого не делать. Вместо этого я бы рекомендовал использовать каталог /usr/local/lib. Обычно он находится в пути ldcache и предназначен для использования с общими библиотеками, созданными пользователями.

надеюсь, это поможет

См.: http://linux.die.net/man/8/ldconfig.

См.: http://linux.die.net/man/1/ldd.

Наконец, команда «locate» полезна для поиска файлов по любому пути. Он использует базу данных, которая часто обновляется, поэтому, если файл находится там какое-то время, он, вероятно, находится в базе данных locate.

Вы можете искать файл следующим образом:

locate libstdc++.so.6

Если файл был недавно добавлен в путь и отсутствует в базе данных локации, вы можете запустить updatedb для повторной генерации базы данных локации. Затем вы сможете найти любой файл в вашей файловой системе.

Для получения дополнительной информации по этой теме я рекомендую прочитать эту книгу: http://www.network-theory.co.uk/docs/gccintro/

person Homer6    schedule 23.07.2013
comment
Очень информативно, большое спасибо. Я думаю, что, возможно, часть проблемы, с которой я сталкиваюсь, заключается в том, что стороннее приложение поставляется со своей собственной версией libstdc++.so, которая находится в каталоге, на который я ссылаюсь, в файле LD_LIBRARY_PATH. К сожалению, эта версия несовместима с моим приложением, и наоборот, стороннее приложение несовместимо с libstdc++.so, установленным на устройстве. Из того, что я собираю, мне придется скомпилировать или связать во время выполнения с той версией, которая совместима. - person olliefinn; 24.07.2013