Почему я должен явно ссылаться на pthreads в моей компиляции main.c, если мой main.c не использует pthreads?

В Linux у меня есть общая библиотека, которую я сделал, которая использует pthreads, и main.c, которая этого не делает.

libpthread.so отображается в ldd моей общей библиотеки, и это правильно.

$ ldd libmapreduce.so.1.0 
    linux-gate.so.1 =>  (0x0067d000)
    libpthread.so.0 => /lib/libpthread.so.0 (0x0058c000)
    [...]

Но когда я компилирую и связываю свой main.c, который не использует pthreads, с моей общей библиотекой, которая их использует, я вижу:

$ icc -Wall -o main main.c -lmapreduce
    /opt/intel/Compiler/11.1/046/lib/ia32/libiomp5.so: undefined reference to `pthread_atfork'

Добавление -lpthread к моей команде компиляции, т.е.

$ icc -Wall -o main main.c -lmapreduce -lpthread

разрешает неопределенную ссылку.

Почему мне нужно явно ссылаться на libpthread, если мой main.c не использует его, а моя общая библиотека уже связана с libpthread?


person David Pointer    schedule 13.03.2012    source источник


Ответы (2)


Чтобы создать исполняемый файл или DLL, вам необходимо связать транзитивное закрытие всех зависимостей в вашей программе. Поскольку main.c ссылается на общую библиотеку, вы также должны ссылаться на все зависимости общей библиотеки, включая pthreads.

person JaredPar    schedule 13.03.2012
comment
Если общие библиотеки, которым нужен pthread, были правильно связаны, вам не нужно это в командной строке ссылки основной программы. Я подозреваю, что одна или несколько библиотек связаны с символами pthread, которые рассматриваются как неопределенные/предоставленные основной программой, а не со ссылкой на libpthread. - person R.. GitHub STOP HELPING ICE; 13.03.2012
comment
@R.. Спасибо, вы ответили на вопрос, который я не знал, как сформулировать. Я буду копать. - person David Pointer; 14.03.2012
comment
Я думаю, что комментарий @R.. является правильным ответом на этот вопрос. - person Pavan Manjunath; 14.03.2012

Спасибо Р.. и Павану Манджунатху за то, что вдохновили меня продолжать копать.

Шаг компоновки разделяемой библиотеки libmapreduce.so выглядел так:

icc -shared -g -o libmapreduce.so.1.0 map.o map_wrp.o -openmp [...] -lpthread -ldl

Этот флаг ссылки -openmp был не нужен и фактически вводил неопределенную ссылку на pthread_atfork. Неопределенная ссылка на pthread_atfork не появлялась, пока я не попытался связать main.c с разделяемой библиотекой libmapreduce.so. Повторное создание libmapreduce.so без флага -openmp устранило проблему.

person David Pointer    schedule 14.03.2012