Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Link libraries with dependencies in Visual C++ without getting LNK4006

I have a set of statically-compiled libraries, with fairly deep-running dependencies between the libraries. For example, the executable X uses libraries A and B, A uses library C, and B uses libraries C and D:

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

When I link X with A and B, I don't want to get errors if C and D were not also added to the list of libraries—the fact that A and B use these libraries internally is an implementation detail that X should not need to know about. Also, when new dependencies are added anywhere in the dependency tree, the project file of any program that uses A or B would have to be reconfigured. For a deep dependency tree, the list of required libraries can become really long and hard to maintain.

So, I am using the "Additional Dependencies" setting of the Librarian section in the A project, adding C.lib. And in the same section of B's project, I add C.lib and D.lib. The effect of this is that the librarian bundles C.lib into A.lib, and C.lib and D.lib into B.lib.

When I link X, however, both A.lib and B.lib contain their own copy of C.lib. This leads to tons of warnings along the lines of

A.lib(c.obj) : warning LNK4006 "symbol" (_symbol) already defined in B.lib(c.obj); second definition ignored.

How can I accomplish this without getting warnings? Is there a way to simply disable the warning, or is there a better way?

EDIT: I have seen more than one answer suggesting that, for the lack of a better alternative, I simply disable the warning. Well, this is part of the problem: I don't even know how to disable it!

like image 954
flodin Avatar asked Feb 19 '09 11:02

flodin


3 Answers

As far as I know you can't disable linker warnings. However, you can ignore some of them, using command line parameter of linker eg. /ignore:4006

Put it in your project properties under linker->command line setting (don't remember exact location).

Also read this:

Link /ignore

MSDN Forum - hiding LNK warnings

Wacek

like image 104
Wacek Avatar answered Nov 11 '22 22:11

Wacek


Update If you can build all involved project in single solution, try this:

  • Put all project in one sln.
  • Remove all references to static libraries from projects' linker or librarian properties.
  • There is "Project Dependencies..." option in context menu for each project in Solution Explorer. Use it to define dependencies between project.

It should work. It doesn't invalidate anything I said before, the basic model of building C/C++ programs stays the same. VS (at least 2005 and newer) is simply smart enough to add all needed static libraries to linker command line. You can see it in project properties.

Of course this method won't help if you need to use already compiled static libraries. Then you need to add them all to exe or dll project that directly or indirectly uses them.


I don't think you can do anything about that. You should remove references to other static libs from static libs projects and add all needed static libs projects as dependences of exe or dll projects. You will just have to live with fact that any project that includes A.lib or B.lib also needs to include C.lib.

As an alternative you can turn your libraries into dlls which provide a richer model.

Statically compiled libraries simply aren't real libraries with dependency information, etc, like dlls. See how, when you build them, you don't really need to provide libraries they depend on? Headers are all that's needed. See? You can't even really say static libraries depend on something.

Static library is just an archive of compiled and not yet linked object code. It's not consistent whole. Each object file is compiled separately and remains separate entity inside the library. Linking happens when you build exe or dll. That's when you need to provide all object code. That's when all the symbol and dependency resolving happens.

If you add other static libraries to static library dependencies, librarian will simply copy all code together. Then, when building exe, linker will give you lots of warnings about duplicate symbols. You might be able to block those warnings (I don't know how) but be careful. It may conceal real problems like real duplicate symbols with differing definitions. And if you have static data defined in libraries, it probably won't work anyway.

like image 29
Tomek Szpakowicz Avatar answered Nov 12 '22 00:11

Tomek Szpakowicz


Microsoft (R) Incremental Linker Version 9.00.x (link.exe) knows argument /ignore:4006

like image 4
abatishchev Avatar answered Nov 11 '22 23:11

abatishchev