2010-09-12 6 views
18

У меня есть Makefile для linux, который я переношу в Дарвин. Файл make содержит кучу файлов .o и объединяет их в общий объект .so. Хорошо, поэтому я решил (я ошибаюсь об этом?), Что лучшим аналогом для этого в Дарвине является dylib. Поэтому я изменил флаг -shared на -dynamiclib.Что такое сделка с неопределенными символами в общей библиотеке или dylib?

Теперь код, который я связываю вместе с dylib, зависит от множества внешних библиотек. Когда я пытаюсь создать dylib, я получаю ошибки, говоря, что есть неопределенные ссылки. Но в файле Makefile Linux не указывается ни один из параметров -lwhatever или -L/path/whatever на этапе сборки, который создает файл .so. Хм? Это потому, что, когда вы создаете файл ELF .so, по умолчанию он оставляет нерешенные внешние ссылки, а затем, когда загружается разделяемая библиотека, он рекурсивно загружает разделяемые библиотеки, на которые зависит общая библиотека, которую вы загружаете? Не было бы так, что если общая библиотека зависит от .a или .o-файла, вам нужно было бы статически связать их с разделяемой библиотекой, иначе вы не могли бы связываться во время выполнения? Как вы можете избавиться от наличия неопределенных ссылок в библиотеке, загружаемой во время выполнения, если только ссылки не относятся к динамически загружаемым библиотекам?

Во всяком случае, так что если я указываю

-undefined suppress -flat_namespace 

он не требует, чтобы я добавить эти опции -l и -L 'при создании общей библиотеки. Но я до сих пор не понимаю, как это может работать в конечном счете.

ответ

1

Использование libtool.

libtool -dynamic -multiply_defined suppress -install_name `basename ../../../../rlp/lib/universal-darwin9-gcc40/libbtutils.dylib` -o ../../../../rlp/lib/universal-darwin9-gcc40/libbtutils.dylib ../../../../rlp/lib/universal-darwin9-gcc40/libbtd.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttrie.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtkey.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtunit.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtutilities.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtopts.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtxcode.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtprops.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtxml.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttake3.a ../../../../rlp/lib/universal-darwin9-gcc40/libbttake5.a ../../../../rlp/lib/universal-darwin9-gcc40/libbtac.a -lstdc++.6 -lgcc_s.10.4 ../../../../build_system/lib/universal-darwin9-gcc40/libgcc.a -lSystem -lSystemStubs` 
+1

Спасибо, я думаю, что это сработает, но меня также интересует предыстория происходящего. – eeeeaaii

+0

MacOS не совсем Linux. Это, в конце концов, NextOS. Линкер немного эксцентричен. Добавьте -v в libtool, и он расскажет вам, что он делает. – bmargulies

13

This thread также обсуждает эту проблему. Я думаю, что ключевым моментом является то, что для того, чтобы получить связанное с Linux соединение, вам нужно указать флаг «-undefined dynamic_lookup». По умолчанию линкер Darwin генерирует ошибку, если в динамической библиотеке есть неопределенные ссылки. Вы также можете использовать -U для установки этого поведения для каждого символа. См. «Man ld» для справки.

 Смежные вопросы

  • Нет связанных вопросов^_^