4
votes

Situation:

  • Static library LIB1, compiled from source and linked as lib1.lib (with /MD). Uses library LIB2 and has inside objects from lib2.lib
  • Static library LIB2, also compiled with /MD.
  • EXE that (not directly) depends on both libraries.

Result of linking this EXE on MSVC 15.9.19: a lot of LNK2005 errors like

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

Also I get a lot of warnings like

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

The question: why didn't the linker merge duplicate definitions? How do I diagnose the exact reason for this problem?

Thanks!

UPDATE: The errors are NOT about the standard library. They are about the Google Protobuf functions. LIB2 is Google's libprotobuf.lib. LIB1 is also Google's OR-Tools library that uses Protobuf. But we also use Protobuf, hence the conflict!

1
It seems like LIB1 is making assumptions it shouldn't make. It should either not have linked with another static library, or should not have exported any symbols from that library. What happens if you use the /NODEFAULTLIB:LIB2 linker option?1201ProgramAlarm
To tell the linker to use libraries other than the defaults, on the command line, specify the libraries to use, and use the /NODEFAULTLIB option to disable the default libraries. In the IDE, add references to your project to specify the libraries to use, and then open the Property Pages dialog for your project, and in the Linker, Input property page, set either Ignore All Default Libraries, or Ignore Specific Default Libraries properties to disable the default libraries.Nagappa
It would help to know what "funcsig" is. Specifically, is it symbol from your code, or from the CRT (C-Run Time library). If it's a CRT function, it is likely you are not setting the /MD flag correctly. If not then you have duplicate symbol between your libraries. The most obvious way this can happen is a non-inline'd function in a header.Tiger4Hire
@1201ProgramAlarm: /NODEFAULTLIB:LIB2 doesn't help, still same error messagesAlex Jenter

1 Answers

1
votes

This link to MSDN will almost certainly help.

As you say these are not standard C/C++ functions, you can ignore the sections about the mixing Debug and Release code. Unfortunately this still leaves you with plenty of possible causes. This one is a good one to rule out.

This error can occur if you mix use of static and dynamic libraries when you use the /clr option.

If you view the command line options as you compile, either by switching on verbose mode or examining the properties of each file.

Once this is ruled out, all the other causes are that you literally declaring the same thing (function/variable) twice. The most likely way for this to happen is to put something (like a function) in a header file, which is included by more than one module file. Diagnosing this without seeing the code is hard. You must pick one of the errors, and select part of the name that is not mangled, basically the human readable bit. You then need to examine where it is declared, and see if is in a header. If it is not, you must be including a non-header from a source file. A quick (and dirty) way to find where a file is included from is to add a #pragma message to the file, then recompile one file at a time to see when it is printed. To understand why it is included use show includes.

If the symbol is declared from a header file, you must fix it, by making it a forward declare. If you don't know how to do this, I would suggest starting a new question, along the lines of, "how do I forward declare this?". It should get you answers pretty quickly.

Hope this helps.