Как избежать «ошибки, уже определенной в LNK2005» в случае двух библиотек stati c, которые используют одну и ту же другую библиотеку stati c? - PullRequest
1 голос
/ 26 января 2020

Ситуация:

  • Stati c библиотека LIB1, скомпилированная из исходного кода и связанная как lib1.lib (с / MD). Использует библиотеку LIB2 и содержит внутренние объекты из библиотеки lib2.lib
  • Stati c LIB2, также скомпилированной с /MD.
  • EXE, которая (не напрямую) зависит от обеих библиотек.

Результат связывания этого EXE-файла на MSV C 15.9.19: много ошибок LNK2005, таких как

lib2.lib: error LNK2005: "function <funcsig> already defined in lib1.lib"

Также я получаю много предупреждений, таких как

lib1.lib: warning LNK4099: PDB 'lib2.pdb' was not found with 'lib1.lib' or at '<path>'; linking object as if no debug info

Вопрос: почему компоновщик не объединяет повторяющиеся определения? Как мне определить точную причину этой проблемы?

Спасибо!

ОБНОВЛЕНИЕ: ошибки НЕ касаются стандартной библиотеки. Они о функциях Google Protobuf. LIB2 - это libprotobuf.lib от Google. LIB1 также является библиотекой OR-Tools от Google, которая использует Protobuf. Но мы также используем Protobuf, отсюда и конфликт!

1 Ответ

0 голосов
/ 05 февраля 2020

Эта ссылка на MSDN почти наверняка поможет.

Поскольку вы говорите, что это не стандартные функции C / C ++, вы можете игнорировать разделы о смешивании кода отладки и выпуска. К сожалению, это все еще оставляет вам множество возможных причин. Это один из правил, который стоит исключить.

Эта ошибка может возникнуть, если при использовании параметра / clr вы используете библиотеки stati c и dynamici c.

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

Как только это будет определено все остальные причины в том, что вы буквально объявляете одну и ту же вещь (функцию / переменную) дважды. Наиболее вероятный способ для этого - поместить что-то (например, функцию) в заголовочный файл, который включен более чем в один файл модуля. Диагностировать это, не видя код, сложно. Вы должны выбрать одну из ошибок и выбрать часть имени, которая не является искаженной , в основном читаемым человеком битом. Затем вам нужно проверить, где он объявлен, и посмотреть, есть ли в заголовке. Если это не так, вы должны включить не заголовок из исходного файла. Быстрый (и грязный) способ выяснить, откуда включается файл, - добавить в файл сообщение # pragma , а затем перекомпилировать по одному файлу за раз, чтобы увидеть, когда он будет напечатан. Чтобы понять, почему он включен, используйте show include .

Если символ объявлен из файла заголовка, вы должны исправить его, сделав forward forward . Если вы не знаете, как это сделать, я бы предложил начать новый вопрос в духе «как мне это объявить?». Это должно дать вам ответы довольно быстро.

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

...