A: 

The problem is you are not localizing library C's symbols. So you have a ODR violation when you link in A and B. You need to have a way to make these private. By default all symbols are exported. One way to do this is to have a special linker definition file for both A and B that explicitly mention which files need to be exported.

[1] ODR = One Definition Rule.

dirkgently
A: 

I think the best course of action here will be to ignore/disable the linker warnings(LNK4006) since C.lib needs to be part of both A.Lib and B.lib and A.Lib does not need to know that B.lib itself uses C.Lib.

SDX2000
How do you disable the linker warning?
flodin
A: 

You could create one library which contains A, B, C & D and then link X against that.

Since it's a library, only object modules which are actually referenced will get linked into the final executable.

Ferruccio
If I do that, the warning is issued when I build that library instead. Neither LINK.EXE nor LIB.EXE appear to take any command-line switches that allow me to disable the warning.
flodin
When you build the A and B components, are you linking in C and D then? Or are you linking them in only at the final link step to build the library?
Ferruccio
Yes, that's what the "Additional Dependencies" setting does. Specifying C.lib in that setting in the project configuration for A.lib, causes VC to link C.lib into A.lib.
flodin
@flodin: Not "link". Rather "include" or "merge". Linking is an entirely different operation done by LINK.EXE to produce exe or dll. Static libs are not linked in that sense.
Tomek Szpakowicz
+2  A: 

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.

Tomek Szpakowicz
I understand what you are saying about the technicalities of libraries, but regardless I think I have a real, sensible use case. There are ways of handling it that does not have the problems you describe, such as silently throwing away exact duplicates of obj files.
flodin
Also, you say I can block the warning, but how? That is also part of my original question. Even if we sidestep the problems you mention, there seems to be just no way of disabling it. Neither lib.exe nor link.exe accept the /Wd:4006 switch.
flodin
I don't know how to disable those warning. I don't think I've ever needed to do that. As a rule I try to find the real cause of warnings and eliminate it. I updated my answer accordingly.
Tomek Szpakowicz
A: 

This may not fix your link error, but it might help with your dependency tree issue.

What I do, is just use a #pragma to include a lib in the .cpp file that needs it. For example:

#pragma comment(lib:"wsock32")

Like I said, I'm not sure it would keep the symbols in that object file, I'd have to whip up an example to try it out.

LarryF
Doing that is pretty much the same as specifying wsock32.lib in the "additional dependencies" section of the library. I don't have a problem getting the dependencies in there, the problem is doing it while simultaneously avoiding the linker warning.
flodin
Also if you are doing any testing, I don't think wsock32.lib is a good example because it is just a DLL import library that doesn't contain any code. It won't reproduce the warnings.
flodin
Yea, I was just using it as an example. And yea, this is the same as adding it to the additional dependencies, but you made mention that even that was kind of a nightmare to keep organized, so I thought this might help.
LarryF
+4  A: 

Hi

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

Wacek
Cool. I quickly glanced at msdn documentation for link.exe and it was not there. Still, keep in mind that disabling warnings is not a cure. It's a band-aid. Band-aids are certainly useful but...
Tomek Szpakowicz
+2  A: 

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

abatishchev
A: 

Poor flodin seems frustrated that nobody will explain how to disable the linker warnings. Well, I've had a similar problem, and for years I have simply lived with the fact that several hundred warnings were displayed. Now, however, thanks to the info from Link /ignore, I figured out how to disable the linker warnings.

I'm using Visual Studio 2008. In Project -> Settings -> Configuration Properties -> Librarian -> Command Line -> Additional Options, I added "/ignore:4006" (without the quotes). Now my warnings are gone!

birch
Did you read the other answers? Several people explained how to disable the warning, about 18 months ago
Michael Mrozek

related questions