Подтвердить что ты не робот

Свяжите библиотеки с зависимостями в Visual С++ без получения LNK4006

У меня есть набор статически скомпилированных библиотек с довольно глубокими зависимостями между библиотеками. Например, исполняемый X использует библиотеки A и B, A использует библиотеку C, а B использует библиотеки C и D:

X -> A
     A -> C
X -> B
     B -> C
     B -> D

Когда я связываю X с A и B, я не хочу получать ошибки, если C и D также не были добавлены в список библиотек — тот факт, что A и B используют эти библиотеки внутри, является детальностью реализации, которая X не нужно знать. Кроме того, когда новые зависимости добавляются где угодно в дереве зависимостей, файл проекта любой программы, использующей A или B, должен быть переконфигурирован. Для дерева с глубокой зависимостью список требуемых библиотек может стать очень длинным и трудноподдерживаемым.

Итак, я использую настройку "Дополнительные зависимости" раздела "Библиотекарь" в проекте A, добавляя C.lib. И в том же разделе проекта B я добавляю C.lib и D.lib. Эффект от этого заключается в том, что библиотечные пучки C.lib в A.lib и C.lib и D.lib в B.lib.

Однако, когда я связываю X, оба A.lib и B.lib содержат свою собственную копию C.lib. Это приводит к появлению тонны предупреждений вдоль линий

A.lib(c.obj): предупреждение LNK4006 "символ" (_symbol), уже определенный в B.lib(c.obj); второе определение игнорируется.

Как я могу это сделать, не получая предупреждений? Есть ли способ просто отключить предупреждение или есть лучший способ?

РЕДАКТИРОВАТЬ. Я видел более одного ответа, в котором говорилось, что из-за отсутствия лучшей альтернативы я просто отключу предупреждение. Ну, это часть проблемы: я даже не знаю, как ее отключить!

4b9b3361

Ответ 1

Насколько я знаю, вы не можете отключить предупреждения компоновщика. Однако вы можете игнорировать некоторые из них, используя параметр командной строки компоновщика, например./Игнорировать: 4006

Поместите его в свои свойства проекта в настройках командной строки компоновщика- > (не помните точное местоположение).

Также читайте это:

Ссылка/игнорировать

Форум MSDN - скрытие предупреждений LNK

Wacek

Ответ 2

Обновление. Если вы можете создать весь задействованный проект в одном решении, попробуйте следующее:

  • Поместите весь проект в один sln.
  • Удалите все ссылки на статические библиотеки из свойств компоновщика или библиотекаря проектов.
  • В контекстном меню для каждого проекта в обозревателе решений есть опция "Зависимости проектов...". Используйте его для определения зависимостей между проектами.

Он должен работать. Это не делает недействительным все, что я сказал ранее, основная модель построения программ на C/С++ остается прежней. VS (не менее 2005 и более поздний) достаточно умен, чтобы добавить все необходимые статические библиотеки в командную строку компоновщика. Вы можете увидеть его в свойствах проекта.

Конечно, этот метод не поможет, если вам нужно использовать уже скомпилированные статические библиотеки. Затем вам нужно добавить их все в проект exe или dll, который прямо или косвенно использует их.


Я не думаю, что вы можете что-то сделать. Вы должны удалить ссылки на другие статические библиотеки из статических проектов libs и добавить все необходимые статические проекты libs в зависимости от проектов exe или dll. Вам просто нужно будет жить с тем фактом, что любой проект, который включает в себя A.lib или B.lib, также должен включать C.lib.

В качестве альтернативы вы можете превратить свои библиотеки в dll, которые предоставляют более богатую модель.

Статически скомпилированные библиотеки просто не являются настоящими библиотеками с информацией о зависимостях и т.д., например, dll. Посмотрите, как, когда вы их создаете, вам не нужно предоставлять библиотеки, от которых они зависят? Заголовки - все, что нужно. Видеть? Вы даже не можете сказать, что статические библиотеки зависят от чего-то.

Статическая библиотека - это просто архив скомпилированного и еще не связанного объектного кода. Это непротиворечивое целое. Каждый объектный файл компилируется отдельно и остается отдельным объектом внутри библиотеки. Связывание происходит, когда вы создаете exe или dll. Это когда вам нужно предоставить весь объектный код. Это происходит при разрешении символа и зависимости.

Если вы добавите другие статические библиотеки в зависимости от статической библиотеки, библиотекарь просто скопирует весь код вместе. Затем, создавая exe, компоновщик даст вам много предупреждений о дублирующих символах. Возможно, вы сможете заблокировать эти предупреждения (я не знаю, как это сделать), но будьте осторожны. Это может скрыть реальные проблемы, такие как настоящие дубликаты символов с различными определениями. И если у вас есть статические данные, определенные в библиотеках, это, вероятно, не сработает.

Ответ 3

Вы можете создать одну библиотеку, которая содержит A, B, C и D, а затем связать X с этим.

Так как это библиотека, то только конечные исполняемые файлы привязаны только к объектным модулям.

Ответ 4

Инкрементный компоновщик Microsoft (R) версии 9.00.x(link.exe) знает аргумент /ignore: 4006

Ответ 5

Обратите внимание, что одним из способов получения этого предупреждения является определение функции-члена в заголовке без встроенного оператора:

// Foo.h

class Foo
{
    void someFunction();
};

void Foo:someFunction() // Warning!  - should be "inline void Foo::someFunction()"
{
    // do stuff
}

Ответ 6

Проблема в том, что вы не локализуете символы библиотеки C. Таким образом, у вас есть нарушение ODR, когда вы ссылаетесь на A и B. У вас должен быть способ сделать это частным. По умолчанию все символы экспортируются. Один из способов сделать это - иметь специальный файл определения компоновщика для A и B, в котором явно указывается, какие файлы нужно экспортировать.

[1] ODR = одно правило определения.

Ответ 7

Я думаю, что лучший способ действий здесь - проигнорировать/отключить предупреждения компоновщика (LNK4006), так как C.lib должен быть частью как A.Lib, так и B.lib и A.Lib не нужно знать, что Сам B.lib использует C.Lib.

Ответ 8

Это может не исправить вашу ошибку ссылки, но это может помочь в возникновении дерева проблем.

Что я делаю, просто используйте #pragma для включения lib в файл .cpp, который ему нужен. Например:

#pragma comment(lib:"wsock32") 

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

Ответ 9

Бедный флодин, кажется, расстроен, что никто не объяснит, как отключить предупреждения компоновщика. Ну, у меня была аналогичная проблема, и в течение многих лет я просто жил с тем, что было показано несколько сотен предупреждений. Теперь, благодаря информации из Link/ignore, я выяснил, как отключить предупреждения компоновщика.

Я использую Visual Studio 2008. В проекте → Настройки → Свойства конфигурации → Библиотекарь → Командная строка → Дополнительные параметры, я добавил "/ignore: 4006" (без кавычек). Теперь мои предупреждения ушли!