While using C++ in Visual Studio 2013, I've come across a really weird warning/bug thing.
I have a static library and a console application.
Static library imports 4 3rd party .lib files, and their headers.
Console application imports the static library and the headers of the original 4 .lib files, so that I can use the code from the original 4 .libs and my .lib.
(I think this is the right setup in this situation, if there is a better way, do tell!)
However, when I build the static library, I get a warning: "LNK4221: This object file does not define any previously undefined public symbols, so it will not be used by any link operation that consumes this library" for each .lib imported.
But where is it getting the code if not from the libraries? If I remove the .libs from being imported, the build fails stating that it needs them! I don't know what to do in a situation like this. I would be happy enough to just leave the .libs being imported as is and ignore the warnings, but when I try to disable them (Under disable specific warning, "4221", in the compiler options), the warnings are not disabled!
Edit: The 4 3rd party .libs are standalone - they do not use each other's code so I do need to import all of them.
I am truly at a loss - any advice would be much appreciated.
I found a way of disabling the warnings using /ignore: on the linker command line, but I'm still confused as to why the linker gave the warnings in the first place, when removing the library as input caused multiple "unresolved external symbol" errors.
Oh well, problem (sorta) solved.
Related
I have a executable project, Game.exe, which is linking against a library Engine.lib. I want to link another internal library, Video.lib, into Engine.lib, so that Game.exe can simply link against Engine.lib and not worry about the symbols provided by Video.lib. This sort of linking setup makes the most sense for my current solution.
In the librarian tab of Engine.lib, I have included the path of Video.lib as well as the file "Video.lib" in the input section. This works perfectly and I have access to the Video.lib symbols.
My issue is when trying to link against Engine.lib from Game.exe. I am not sure if I changed some sort of setting in the Game.exe project, but when I try build Game.exe, I get a linking error that Video.lib cannot be found. How is this possible, when I do not have "Video.lib" under the inputs of Game.exe?
Adding the path of the Video.lib file (simply the path, not the file itself) to the Game.exe project solves this, but obviously the whole point of this setup is that Video.lib should be merged into Engine.lib so that I only have to link Game.exe against Engine.lib.
Is there a setting in Engine.lib I have to set that specifies all Video.lib symbols should be pulled into Engine.lib, instead of making it a dependency for future projects that link against Engine.lib? Or have I set something incorrectly in the Game.exe project?
I do not want to use Visual Studio's "project dependencies" or "references" system.
Thanks!
Edit: This post here (Linking static libraries to other static libraries) does not answer my question, as it is both outdated (doesn't really contain information about the new VS interface) and doesn't answer the issue I am having (why is Game.exe trying to link against Video.lib). Since my question is about this problem and the other question is simply a "how to" I therefore do not believe my question is a duplicate.
Edit 2: I am certain that Video.lib IS being linked into Engine.lib due to the noticeable increase in file size. What I don't understand is why Game.exe still complains about not being able to find Video.lib
The issue turned out to be with the library I was using specifically, which is wxWidgets (I simplified the example above in order to avoid complications).
wxWidgets uses #pragma comments to link specific libraries in. In this case, wxWidgets ("Video.lib") was causing Game.exe to "see" these pragma comments and ultimately attempt to link in the libraries.
Adding all the wxWidgets libraries ("Video.lib") to "Ignore Specific Default Libraries" under Linker -> Input in Game.exe solved the problem to me, as this ultimately overrode the pragma directives.
I'm working with Embarcadero XE8 C++ builder 32 bit.
I was adding a library to my program for solving the Unresolved external error.
When I added the library I got the error as in the title. So I searched the web and found this topic on stackoverflow:
Linker error "contains invalid OMF record"
As it says the COFF2OMF tool, CAN work. Sadly it didn't work for me, I give a 7mb library file, when I convert it with the tool it's only 41kb... so I guess the convertion failed. When I add the converted files to my program it just ignores it and still says the unresolved external error.
So how can I get my library working with my C++ builder?
A little background:
Libraries need to be compiled with the same kind of tool as the application you are trying to make, because every compiler does things a wee bit differently. Most libraries for Windows are compiled with the MVSC (Microsoft Visual Studio Compiler).
You're using the Embarcardero Compiler, which means that the MVSC libraries are incompatible (you may have noticed that ;)).
You have multiple options.
If you can, get the source of the library and compile it with your own compiler. That way the chance to succeed is the highest.
I may be mistaken since it's been a while, however I believe there's a tool called implib which takes the shared library (.dll) and generates an Embarcardero-style .lib from that for use in your project.
Use COFF2OMF to convert the static library. And even if the file size is strange, do at least try it.
Try the LoadLibrary function call. This one requires you to map the functions you need manually, however you get around using the .lib.
Good luck.
I'm currently trying to compile a static 64 bit version of cryptopp (more precisely, the cryptlib VS project) using MS Visual Studio 2013 on a Windows 8.1 machine. Since it is a static release build, I've set the Runtime Library to Multithreaded (/MT).
However the linker throws several of the following errors:
error LNK2038: mismatch detected for 'RuntimeLibrary': value 'MT_StaticRelease' doesn't match value 'MD_DynamicRelease' in adhoc.obj
In most of the similar cases I've found here and on google, this was caused by one library setting /MT and another one setting /MD. The weird thing about this case is that the linker does not include any libraries (except maybe some Visual-Studio-internal magic) and there are no additional include directories. The linker command line assembles as:
/OUT:"build\x64\static_release\cryptlib64.lib" /LTCG /MACHINE:X64 /NOLOGO
In the project file, I couldn't find any other <RuntimeLibrary> settings except for those on project level so I'd assume there is no .cpp file which has a /MD switch.
To sum it up, this means my library defines /MT, but something which is used by crytlib internally seems having /MD defined. Is there a way to find out what object/cpp/define/library/whatever has that switch defined?
This linker diagnostic is a 100% accurate hint that you are in fact linking .obj or .lib files that were built wrong. Almost always .lib files that you don't know about because you didn't have to explicitly list them as Additional Dependencies. MSVC++ makes it pretty easy to specify link dependencies without having to use the setting, like using Add Reference or #pragma comment(lib, "yadayada.lib") in a source code file. Very convenient of course, but not so visible when you are trying to troubleshoot linker errors like this.
It is easily diagnosable however, the linker has an option to show you what it is actually linking. Use Project + Properties, Linker, Command Line and add the /VERBOSE option. The linker now gets very chatty to the Output window, showing you every .lib file it loads and what symbols it uses from the .lib file.
The .lib name should be enough of a hint to know where to start looking, you ought to know the #include from there. Whether you can really build with /MT is still up in the air, if it is an import library of a DLL then the odds dwindle rapidly. Avoid forcing it, having more than one copy of the CRT in a process is fraught with trouble.
Cleaning the solution and then rebuilding might help. It seems the linker is still trying to use the old object files (before you applied /MT).
The weird thing about this case is that the linker does not include any libraries (except maybe some Visual-Studio-internal magic)
There is a good chance that is where its coming from if you are certian its not something in your gear.
If Dynamic C++ Runtime Linking is an option for you, then you might consider using it for Crypto++. To ease the troubles of converting Crypto++ to Visual Studio 2010 (and above) and converting to /MD and /MDd, you can use vs2010-dynamic.zip. Just unpack it over top of the existing Crypto++ sources.
Also see Mismatch Detected for 'RuntimeLibrary' and Crypto++ on Stack Overflow.
I'm developing an application at work using C++, Qt, Mingw32 and Netbeans. I need to use an in house API that has been developed by the software group in the company.
I have the symbol libraries .lib files for the DLLs i need to link against, but i cannot use these libs with Mingw32, it works fine with Microsoft Visual Studio.
Does anyone know if there is a way to export the symbols and create a .a symbol library that works with Mingw32 ? If not i'll have to go over to Visual Studio i guess.
I have tried using the program "pexports" to create a .def file and dlltool, but that didn't work. Still got unreferenced symbol errors, then i added the symbols it complained about to the .def, because they weren't there and it stopped complaining and compiled. But the program crashes. I tried the same code in Visual Studio and it compiles and runs fine.
Have you considered dynamically loading the DLL? LoadLibrary, GetProcAddress, etc. You can probably easily write a class that encapsulates all the DLL's entry points, loading and unloading the library, and does all the #typedefs, etc. It's grunt work but if it's an in-house library there probably aren't too many entry points?
Import libs are overrated. :p
Not sure if it helps, but you may wish to check this guide.
Here's how I did that for the mysql library.
Create a list of exports using dllwrap:
dllwrap --export-all-symbols --output-def libmysql.def libmysql.dll --implib liblibmysql.a
This creates a list of exports in the .def file but the name mangling is incorrect.
Edit the .def file in a text editor and remove the '#' symbols.
The symbol names typically also have a number appended to them as well.
I don't know how to determine the correct name except by experimentation:
Run the following to create a netbeans compatible library:
dlltool --input-def libmySQL.def --dllname libmySQL.dll --output-lib libMySQLclient.a -k
Compile with it and you'll get undefined symbols. The undefined symbols will have the correct decorations.
Edit the .def file again and correct the symbol names. Re-run dlltool to get the correct .a library file.
Have you tried linking the DLL directly, rather than a .a/.lib? MinGW is usually happy to do that for you.
I give up, some people say it is not possible with a dll compiled on microsofts compiler with c++ exports, because of the name mangling
Problem:
I'm trying to use a library named DCMTK which used some other external libraries ( zlib, libtiff, libpng, libxml2, libiconv ). I've downloaded these external libraries (*.LIB & *.h files ) from the same website. Now, when I compile the DCMTK library I'm getting link errors (793 errors) like this:
Error 2 error LNK2005: __encode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 3 error LNK2005: __decode_pointer already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 4 error LNK2005: __CrtSetCheckCount already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 5 error LNK2005: __invoke_watson already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 6 error LNK2005: __errno already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 7 error LNK2005: __configthreadlocale already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Error 8 error LNK2005: _exit already defined in MSVCRTD.lib(MSVCR90D.dll) LIBCMTD.lib dcmmkdir
Documentation:
This seems to be a popular error for this library so, they do have a FAQ entry addressing this issue which ( http://forum.dcmtk.org/viewtopic.php?t=35 ) says:
The problem is that the linker tries to combine different,
incompatible versions of the Visual
C++ runtime library into a single
binary.
This happens when not all parts of your project and the libraries you
link against are generated with the
same code generation options in Visual
C++.
Do not use the /NODEFAULTLIB workaround, because strange software
crashes may follow. Fix the problem!
DCMTK is by default compiled with the "Multithreaded" or "Multithreaded
Debug" code generation option (the
latter for Debug mode).
Either change the project settings of all of your code to use these code
generation options,
or change the code generation for all DCMTK modules and re-compile.
MFC users beware: DCMTK should be compiled with "Multithreaded DLL" or
"Multithreaded DLL Debug" settings if
you want to link the libraries into an
MFC application.
Solution to same problem for others:
Huge Amount of Linker Issues with Release Build Only says:
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).
More technically, you seem to be
linking projects built with different
C Run Time 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
Questions:
Till now I used to think that Name mangling is the only problem that may cause linking failures if its not been standardized. Just now I knew there are other things also which can cause same effect.
Whats up with the "Debug Mode" (Multi-Threaded Debug) and "Release Mode" (Multi-Threaded)? What exactly is happening under the hood? Why exactly this thing is causing linking error?
I wonder if there is something called "Single-Threaded Debug" and "Single-Threaded" which again causes the same thing.
Documentation talks something about "Code Generation Options". What Code Generation Options? WTH are they?
Documentation specifically warns us not to use /NODEFAULTLIB workaround. (example /NODEFAULTLIB :msvcrt ). Why? How would I cause troubles? what exactly is it?
Please explain the last point in the documentation for MFC users. Because I'm going to use MFC later in this project. Explain Why should we do it? What troubles would it cause if I don't.
Anything more you'd like to mention? I mean regarding similar errors. I'm very interested in Linker & its problems. So, if there are any similar things you can mentions them or some keywords atleast.
Whats up with the "Debug Mode"
(Multi-Threaded Debug) and "Release
Mode" (Multi-Threaded)? What exactly
is happening under the hood? Why
exactly this thing is causing linking
error?
The linker drags in libraries for several different reasons. The simplest is that a library is listed on the linker command line, or in the linker answer file on the linker command line. But any object files, whether compiled in your project or packed into a library, can also contain linker options including requesting particular libraries be linked in. In fact, the Visual C++ compiler automatically embeds such linker options matching the project options you use when compiling.
At link time, all the linker options from all object files and objects in static library files get combined. If more than one CRT library filename is requested, the linker reads in all of them and them you get naming conflicts, where the linker doesn't know which one to use.
I wonder if there is something called
"Single-Threaded Debug" and
"Single-Threaded" which again causes
the same thing.
There used to be, but the last few versions of Visual C++ have only shipped multi-thread compatible libraries.
Documentation talks something about
"Code Generation Options". What Code
Generation Options? WTH are they?
Look inside your project options.
Documentation specifically warns us
not to use /NODEFAULTLIB workaround.
(example /NODEFAULTLIB :msvcrt ). Why?
How would I cause troubles? what
exactly is it?
If you use /NODEFAULTLIB, all the linker settings stored within object files and objects in libraries get ignored. You'll end up with no runtime library and maybe missing other libraries. You can add them back in by hand, but it's still a big mess.
Please explain the last point in the
documentation for MFC users. Because
I'm going to use MFC later in this
project. Explain Why should we do it?
What troubles would it cause if I
don't. Anything more you'd like to
mention? I mean regarding similar
errors. I'm very interested in Linker
& its problems. So, if there are any
similar things you can mentions them
or some keywords atleast.
MFC applications and the MFC library have to use the same memory management functions, so that memory allocated by MFC can be freed by the application and vice-versa. FILE handles and other resources are also shared. The MFC DLLs are already compiled to use the CRT in a DLL, and in order to be able to share resources you need to use the same CRT, which means using a DLL too.
You need to configure project properties so that your debug build links with DCMTK's debug build and your release build links with DCMTK's release build.
The above is what you need to do. Below are explanations of some other random things you asked about.
Older versions of Visual Studio used to have single threaded libraries (release and debug versions) besides multithreaded libraries (release and debug versions). For your project you can pretend single threaded libraries never existed.
If you experiment with random ways to trick the linker into shutting up and leaving problems to be found by your customers instead of by yourself, you might find that the /NODEFAULTLIB option will do that. The makers of the DCMTK library are warning you not to do that because some other people did the same dumb thing in the past.
Whats up with the "Debug Mode" (Multi-Threaded Debug) and "Release Mode" (Multi-Threaded)? What exactly is happening under the hood? Why exactly this thing is causing linking error?
They are different versions of the C runtime library. You can statically link to the runtime library in debug and release mode. In the Code Generation Options (mentioned below), those would be "Multi-Threaded Debug" and "Multi-Threaded". The options "Multi-Threaded Debug DLL" and "Multi-Threaded DLL" dynamically link to the C runtime. By dynamically linking to the runtime, you'll also have to ship your installer configured to install the VC redistributable package that contains the proper runtime dlls for your version of Visual C++.
Statically linking to the C runtime is generally frowned upon, even by Microsoft:
In addition to all the methods
described above of distributing the
Visual C++ libraries DLLs, there is
one last option for building your
application which does not require you
to distribute the DLLs. However, this
option only works for native-only code
(it is not supported with /clr) and
leaves your customers seriously
vulnerable to any security holes as
well as adds a significant burden upon
yourself to patch all customer systems
should a vulnerability be found in any
of the libraries. This option is to
statically link in the libraries as
.lib files instead of dynamically
loading them as DLLs. You do this by
using the /MT flag on the cl.exe
command line (vs /MD), or selecting
the appropriate option in your project
properties through Visual Studio. You
may wish to use this option when
testing early debug builds of your
application on test machines before
you start working on setup. [See
footnote 3]
However, I can think of no scenarios
in which this is actually the right
thing to do when shipping your product
to customers. Basically, what this
approach does is pulls in the binary
code needed from .LIB files at compile
time, making it a part of your .exe or
.dll files. It increases the size of
your application, and there is no way
to update the libraries apart from
recompiling your application with new
.LIBs and redistributing your
application all over again. What this
means is that unless you go touch
every single machine which has
installed your application every time
there is a security vulnerability
found in the Visual C++ libraries and
completely reinstall your updated
binaries, you will be leaving your
customers vulnerable to attack. If
instead you use the DLLs, every time
there is a security vulnerability
found in the Visual C++ libraries,
Microsoft will install the update
centrally into the WinSxS folder via
Windows Update and all requests for
the DLLs will be redirected to the
updated version. This removes all
servicing burden on your side and also
allows the user to install one small
update which will touch all their
applications instead of replacing
every installed exe and DLL on their
system. Please, do not distribute an
application built by linking
statically against the Visual C++
libraries unless you have a system in
place for updating every customer
machine and also have a very good
reason to do so. At this time, I can
think of no circumstance under which
this would be the right thing to do
for a shipping application.
I wonder if there is something called
"Single-Threaded Debug" and
"Single-Threaded" which again causes
the same thing.
No such thing, see above.
Documentation talks something about "Code Generation Options". What Code Generation Options? WTH are they?
Right click on your Visual C++ project (from within Visual Studio) and select Properties. Under Configuration Properties->C/C++->Code Generation
Documentation specifically warns us not to use /NODEFAULTLIB workaround. (example /NODEFAULTLIB :msvcrt ). Why? How would I cause troubles? what exactly is it?
Take their advice and don't do it.
Please explain the last point in the documentation for MFC users. Because I'm going to use MFC later in this project. Explain Why should we do it? What troubles would it cause if I don't.
Because MFC is dynamically linked to the C runtime, using libraries that are statically linked to the C runtime will cause the linker errors you listed first in your post.
Anything more you'd like to mention? I mean regarding similar errors. I'm very interested in Linker & its problems. So, if there are any similar things you can mentions them or some keywords atleast.
From my experience, always dynamically link to the C runtime. It generally saves you a lot of headaches like the one you're experiencing right now.