Существуют ли общие рекомендации по решению неопределенных проблем с ссылками / нерешенными символами? - PullRequest
6 голосов
/ 29 января 2009

У меня несколько проблем с «неопределенной ссылкой» (во время связывания) и «неразрешенным символом» (во время выполнения после dlopen), где я работаю Это довольно большая система make-файлов.

Существуют ли общие правила и рекомендации для связывания библиотек и использования флагов / опций компилятора, чтобы избежать ошибок такого типа?

Ответы [ 2 ]

6 голосов
/ 29 января 2009

ЕСЛИ ВЫ ИСПОЛЬЗУЕТЕ MSVC:

Вы не можете избежать этого типа ошибки, установив флаг : это означает, что некоторые единицы (.cpp) не имеют определений объявленных идентификаторов. Это, безусловно, вызвано отсутствием включений или отсутствием определений объектов (часто статических объектов) где-либо.

Во время разработки вы можете следовать этим рекомендациям (из этих статей ), чтобы убедиться, что весь ваш cpp включает все необходимые им заголовки, но не более:

  • Каждый файл cpp сначала включает свой собственный заголовочный файл. Это самый важное руководство; все остальное отсюда следует Единственное исключение к этому правилу относятся предварительно скомпилированные заголовки включает в Visual Studio; те всегда должен быть первым включить в файл. Подробнее о скомпилированном Заголовки во второй части этой статьи.
  • Файл заголовка должен включать все файлы заголовка, необходимые для его анализа. Это идет рука об руку с первым руководство. Я знаю, что некоторые люди пытаются никогда не включать заголовочные файлы в заголовочные файлы, требующие эффективности или что-то в этом роде. Тем не мение, если файл должен быть включен до файл заголовка может быть проанализирован, он должен быть включенным где-нибудь. Преимущество в том числе прямо в шапке Дело в том, что мы всегда можем решить вытащить файл заголовка, который нас интересует и мы гарантируем, что это работать как есть. Нам не нужно играть «Угадайте, какие еще заголовки вам нужны» игры.
  • Заголовочный файл должен иметь минимальное количество заголовочных файлов. надо разобрать это. Предыдущий Правило гласило, что вы должны иметь все включает в себя вам нужно в заголовочном файле. Это правило гласит, что у вас не должно быть никаких больше, чем нужно. Понятно, начать удаляя (или не добавляя в первое место) бесполезно включать заявления. Затем используйте как можно больше вперед декларации, как вы можете вместо включает в себя. Если все, что у вас есть ссылки или указатели на класс, вы не нужно включать этот класс заголовочный файл; прямая ссылка будет делай красиво и намного эффективнее.

Но, как предположил комментатор, похоже, вы используете g ++ ...

5 голосов
/ 29 января 2009

Настройка системы сборки, где X зависит от Y, который зависит от Z, помогает. Когда вы попадаете в круги (Z зависит от X), все становится ужасно.

Часто библиотеки порядка связаны ("-lZ -lY -lX" против "-lX -lY -lZ"), что вызывает горе. В более редких случаях у вас есть одно и то же имя библиотеки в нескольких местах в пути поиска или вы ссылаетесь на устаревшие версии, которые еще не были перекомпилированы.

"nm --demangle" позволяет увидеть, где что-то определено / используется.

"ldd" можно использовать, чтобы увидеть, от каких динамических библиотек вы зависите.

Флаг gcc / g ++ -print-file-name = LIBRARY может помочь точно определить, какая библиотека используется.


Запоздалая мысль: (Поскольку вы спрашиваете о правилах / руководящих принципах.)

Можно настроить систему make-файлов так, чтобы:

  • Если модуль = D зависит от модулей A, B и C.
  • Тогда попытка создать модуль = D сначала создаст модули A, B и C.
  • И, что более важно, module = D будет автоматически определять свои библиотеки (-lA и т. Д.), Пути к библиотекам (-LA) и включать пути (-IA) из make-файлов для модулей A, B и C.

Это может стать немного волосатым. В прошлый раз, когда я делал это, я предпочитал просто кэшировать информацию, а не разветвлять чрезмерное количество подпроцессов make. В сочетании с импортом makefile и небольшим Perl-скриптом для удаления дубликатов. Клуджи, я знаю. (Силам, которые не хотят тратить время на инфраструктуру.) Но это можно сделать.

Опять же, я использовал GNU-make, который имеет несколько расширений.

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