Problem statically linking MFC libraries - c++

I have a Visual Studio 6 workspace I'm trying to convert to a Visual Studio 2008 solution. The output of said solution is a .dll. It has to be a .dll and it needs to statically link MFC as I can't redistribute MFC to existing customers.
The solution consists of three projects, say A, B, C. C is the Active Project, outputs the .dll and depends on B. B outputs a .lib and depends on A. A outputs a .lib.
In the General configuration properties I have A and B set to Static Library (.lib) and C set to Dynamic Library (.dll). All three projects are set to "Use MFC in a Static Library." Also, all three projects are set to "Multi-threaded" for Runtime Library and none of them have _AFXDLL defined.
Everything builds correctly up until the final linking stage where I see this:
1>nafxcw.lib(wincore.obj) : error LNK2005: _IsPlatformNT already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _InitMultipleMonitorStubs already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _xGetSystemMetrics#4 already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _xMonitorFromPoint#12 already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _xMonitorFromRect#8 already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _xMonitorFromWindow#8 already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _xGetMonitorInfo#8 already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _xEnumDisplayMonitors#16 already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _xEnumDisplayDevices#16 already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_pfnGetSystemMetrics already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_pfnMonitorFromWindow already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_pfnMonitorFromRect already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_pfnMonitorFromPoint already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_pfnGetMonitorInfo already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_pfnEnumDisplayMonitors already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_pfnEnumDisplayDevices already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_fMultiMonInitDone already defined in A.lib(Globals.obj)
1>nafxcw.lib(wincore.obj) : error LNK2005: _g_fMultimonPlatformNT already defined in A.lib(Globals.obj)
1>nafxcw.lib(viewprnt.obj) : error LNK2005: "public: virtual int __thiscall CPrintingDialog::OnInitDialog(void)" (?OnInitDialog#CPrintingDialog##UAEHXZ) already defined in B.lib(ImagePropertiesDlg.obj)
1>nafxcw.lib(viewprnt.obj) : error LNK2005: "public: __thiscall CPrintingDialog::CPrintingDialog(class CWnd *)" (??0CPrintingDialog##QAE#PAVCWnd###Z) already defined in B.lib(ImagePropertiesDlg.obj)
1>nafxcw.lib(viewprnt.obj) : error LNK2005: "public: virtual void __thiscall CPrintingDialog::OnCancel(void)" (?OnCancel#CPrintingDialog##UAEXXZ) already defined in B.lib(ImagePropertiesDlg.obj)
I've Googled the problem to death and seen other people with a similarish issue, but can't seem to solve it. I tried adding nafxcw.lib to the Ignored libraries for C, but that turned this batch of linker errors into 1500+ unresolved symbol errors. I can get it to compile/link if I make it dynamically link MFC, but like I said, I need it to statically link. I feel like I'm missing something rather simple but can't seem to wrap my head around it. Any and all random thoughts and ideas will be greatly appreciated.

As is often the case, the solution turned out to be so mundane and obvious, I'm still kicking myself for banging my head on it for so long.
Basically, project A referenced above was not a project I directly pulled from the old VS6 workspace, but rather a project that had previously been converted by another team for use in another application. I assumed it was functionally equivalent to the original one, but that is very much not the case. These linking errors are actual, valid multiply defined linking errors. When I started digging in, I found that the first batch of errors was from including multimon.h in project A (something I don't even need, just removed it) and the second batch is from a class that is actually defined in both A and B.
Like I said, I'm still groaning over here, but at least I should be able to fix my problem now. Thanks for the help and always remember to NEVER assume ANYTHING.

When you tried ignoring the nafxcw library, did you add it back in to try to force a link order as suggested by this KB article? While your problem isn't an exact fit it may be related. Perhaps things could be resolved by monkeying with the link order.

Related

How do I use 2 libraries with same external symbols?

I have 2 libraries in my project - MySQL C++ Connector and OpenSSL library for sockets, and as I think MySQL library already has OpenSSL functions inside.
Errors I get
Errors I get (in text format):
1>libcrypto.lib(libcrypto-lib-x509_d2.obj) : error LNK2005: X509_STORE_load_locations already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-ct_policy.obj) : error LNK2005: CT_POLICY_EVAL_CTX_free already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-ct_policy.obj) : error LNK2005: CT_POLICY_EVAL_CTX_set1_cert already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-ct_policy.obj) : error LNK2005: CT_POLICY_EVAL_CTX_set1_issuer already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-ct_policy.obj) : error LNK2005: CT_POLICY_EVAL_CTX_set_shared_CTLOG_STORE already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-ct_policy.obj) : error LNK2005: CT_POLICY_EVAL_CTX_set_time already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-srp_lib.obj) : error LNK2005: SRP_Calc_A already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-srp_lib.obj) : error LNK2005: SRP_Calc_server_key already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-srp_lib.obj) : error LNK2005: SRP_Verify_A_mod_N already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-srp_lib.obj) : error LNK2005: SRP_Verify_B_mod_N already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-srp_lib.obj) : error LNK2005: SRP_check_known_gN_param already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-srp_lib.obj) : error LNK2005: SRP_get_default_gN already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_INFO_free already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_INFO_get0_CERT already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_INFO_get0_NAME already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_INFO_get_type already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_close already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_eof already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_error already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_load already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
1>libcrypto.lib(libcrypto-lib-store_lib.obj) : error LNK2005: OSSL_STORE_open already defined in mysqlcppconn-static.lib(libcrypto-1_1-x64.dll)
My project include directories:
\asio-1.24.0\include
\openssl\Lib\x64\Release\include
\MySQL\Connector C++ 8.0\include\jdbc
Linker input:
\openssl\Lib\x64\Release\lib\libcrypto.lib
\openssl\Lib\x64\Release\lib\libssl.lib
crypt32.lib
mysqlcppconn-static.lib
Static and shared libraries cannot be mixed like that.
mysqlcppconn-static is statically linked with libssl, and attempting to link, again, with libssl is not going to work.
mysqlcppconn-static is meant to be used with special-purpose applications that get statically linked only with mysql, and so they can be distributed without the mysql and openssl libraries.
Whenever multiple libraries are involved the only practical approach is to link only with shared libraries.

fatal error LNK1169

The below error list pops up.
I am okay if this had happened on Release build.
It is quite surprising that it has happened in DEBUG build.
1>libcmtd.lib(dbgheap.obj) : error LNK2005: malloc already defined in libcmt.lib(malloc.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _heap_alloc already defined in libcmt.lib(malloc.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: calloc already defined in libcmt.lib(calloc.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: realloc already defined in libcmt.lib(realloc.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _recalloc already defined in libcmt.lib(realloc.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _expand already defined in libcmt.lib(expand.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: free already defined in libcmt.lib(free.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _msize already defined in libcmt.lib(msize.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _aligned_malloc already defined in libcmt.lib(align.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _aligned_realloc already defined in libcmt.lib(align.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _aligned_recalloc already defined in libcmt.lib(align.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _aligned_offset_malloc already defined in libcmt.lib(align.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _aligned_offset_realloc already defined in libcmt.lib(align.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _aligned_offset_recalloc already defined in libcmt.lib(align.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _aligned_free already defined in libcmt.lib(align.obj)
1>libcmtd.lib(dbgheap.obj) : error LNK2005: _aligned_msize already defined in libcmt.lib(align.obj)
1>libcmtd.lib(dbghook.obj) : error LNK2005: __crt_debugger_hook already defined in libcmt.lib(dbghook.obj)
1>libcmtd.lib(isctype.obj) : error LNK2005: _isctype_l already defined in libcmt.lib(isctype.obj)
1>libcmtd.lib(isctype.obj) : error LNK2005: _isctype already defined in libcmt.lib(isctype.obj)
It looks like you're linking to the Debug runtime as well as the Release runtime - probably you have a Release build that links statically to a Debug lib or vice versa.
If your application use any LIBs or DLLs any of those are statically link with run-time assemblies. that's the reason for this linking error.
Run-time assemblies statically liking is not a recommended method
But if you need to get rid from this linking error here you go, right-click on project file in project explorer -> properties -> configuration properties -> linker -> Input -> Ignore Specific Library -> add libcmtd.lib

C++ LNK2005 'already defined' errors - files referencing themselves

I have inherited a C++ solution with 3 projects, one compiling to a .DLL, the other two to .EXEs . The DLL builds on its own fine, but the other two, when built, produce around 65 LNK2005 errors, the majority of which are referencing the same .obj file, as shown in the log exert below:
Linking...
Function.obj : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:ICF' specification
Function.obj : error LNK2005: _ReadLocalRegister already defined in Function.obj
Function.obj : error LNK2005: _getSource already defined in Function.obj
Function.obj : error LNK2005: _SendLogEvent already defined in Function.obj
Function.obj : error LNK2005: _DebugMsg already defined in Function.obj
Function.obj : error LNK2005: _MyInformationMsg already defined in Function.obj
MyNTService.obj : error LNK2005: "public: __thiscall CMyNTService::CMyNTService(void)" (??0CMyNTService##QAE#XZ) already defined in MyNTService.obj
MyNTService.obj : error LNK2005: "public: virtual void __thiscall CMyNTService::OnStop(void)" (?OnStop#CMyNTService##UAEXXZ) already defined in MyNTService.obj
MyNTService.obj : error LNK2005: "public: void __thiscall CMyNTService::SaveStatus(void)" (?SaveStatus#CMyNTService##QAEXXZ) already defined in MyNTService.obj
....and so it goes on!
I am a C# coder, only basic C++ knowledge, so I am lost with this. The solution is an 15 year old C solution I am attempting to rebuild as a C++ solution in VS2008. I have managed to build it once, nothing has changed, but perhaps some config settings have changed since then.
Does anyone have ideas where I could start to look...?
Many thanks!
It sounds like you're missing inclusion guards on the header file for that object.
Add:
#ifndef SomeUniqueName
#define SomeUniqueName
//Code goes here.
#endif
Wrapping the code in the header file. The compiler will go through that header file many times when processing your code as it's included in many places (most likely). The inclusion guards stop redefinition of things that have already been defined on previous passes.
PS: It also might help to do a "make clean". Makefiles can be finnicky especially if not made 100% right and sometimes when dependencies are off you need to clean before rebuilding.
in msvc110 (2012), I encountered the same error and the only workaround i found was to create a class and a separate DLL for the recurrent functions I used in the different files.
Here's the link to do so.
Cheers

Linker Errors due to being Already Defined

It has been about a year since I wrote any .dll plugins that use LibCurl, but I decided to start on another one tonight. Unfortunately, I have been combating the same linker errors for almost 4 hours now, and I am completely lost.
I am statically building LibCurl, and it appears to be fine for the most part, except I am getting the following linker errors.
1>MSVCRT.lib(MSVCR90.dll) : error LNK2005: _calloc already defined in memoverride.obj
1>MSVCRT.lib(MSVCR90.dll) : error LNK2005: _realloc already defined in memoverride.obj
1>MSVCRT.lib(MSVCR90.dll) : error LNK2005: _free already defined in memoverride.obj
1>MSVCRT.lib(MSVCR90.dll) : error LNK2005: _malloc already defined in memoverride.obj
1>MSVCRT.lib(MSVCR90.dll) : error LNK2005: __strdup already defined in memoverride.obj
1>MSVCRT.lib(MSVCR90.dll) : error LNK2005: __malloc_crt already defined in memoverride.obj
I have tried...
1) Reorganizing my included libs due to MSDN saying LNK2005 was caused by this.
2) Rebuilding the LibCurl lib through MSVC Application, then through the Command-Line tool.
3) Excluding the libs that are causing issues.
and a bunch of other things that I cannot even remember now. Can anyone help me out with some information as to how I can solve these?
Problem was my .dll was /MT while the libcurl was /MD. Also, I had initially blocked "libcmt", so when I was switching libcurl to /MT, it was spewing errors.

Huge Amount of Linker Issues with Release Build Only

Anyone have idea on this? Linker errors are way out of my wheelhouse, especially ones like this.
Is there any more info I should include?
1>Linking...
1>freeglut_static.lib(freeglut_window.obj) : warning LNK4075: ignoring '/EDITANDCONTINUE' due to '/OPT:ICF' specification
1>LIBCMTD.lib(dbgheap.obj) : error LNK2005: __heap_alloc already defined in LIBCMT.lib(malloc.obj)
1>LIBCMTD.lib(dbgheap.obj) : error LNK2005: __recalloc already defined in LIBCMT.lib(recalloc.obj)
1>LIBCMTD.lib(dbgheap.obj) : error LNK2005: __msize already defined in LIBCMT.lib(msize.obj)
1>LIBCMTD.lib(malloc.obj) : error LNK2005: _V6_HeapAlloc already defined in LIBCMT.lib(malloc.obj)
1>LIBCMTD.lib(dbghook.obj) : error LNK2005: __crt_debugger_hook already defined in LIBCMT.lib(dbghook.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_pHeaderDefer already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: __get_sbh_threshold already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: __set_sbh_threshold already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: __set_amblksiz already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: __get_amblksiz already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_heap_init already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_find_block already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_free_block already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_alloc_block already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_alloc_new_region already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_alloc_new_group already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_resize_block already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_heapmin already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(sbheap.obj) : error LNK2005: ___sbh_heap_check already defined in LIBCMT.lib(sbheap.obj)
1>LIBCMTD.lib(isctype.obj) : error LNK2005: __isctype_l already defined in LIBCMT.lib(isctype.obj)
1>LIBCMTD.lib(isctype.obj) : error LNK2005: __isctype already defined in LIBCMT.lib(isctype.obj)
1>LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
You seem to be linking projects built with different CRT library settings, one with Multi-Threaded, another one with Multi-Threaded Debug. Adjust the settings for all the projects to use the very same flavour of the library and the issue should go away!
You wouldn't normally try and pull in LIBCMTD in a release build, it's the debug version of LIBCMT.
It seems that your release build is trying to link to something that was built debug. You probably have a broken dependency in your build, (or you missed rebuilding something to release by hand if your project is normally built in pieces).
It would seem likely that it's the freeglut_static.lib that wasn't rebuilt for retail. If that isn't it then try deleting all of your build products (*.obj, *.lib, *.pch, *.pdb) of course being careful to not delete things that you don't produce - third party libs, etc. Then build just release.
To add to the other remarks: Don't use "Edit and Continue" /EDITANDCONTINUE in release builds. That's a useful feature while debugging, as it can reduce rebuild times. But it does so by packing your executable in a non-optimized form.
You get the warning because the /OPT:ICF option will fold identical function bodies. This means two functions share the same address. Obviously this means you cannot edit & replace only one of them.