I have a project whose output is a library (.lib). The project depends on a third party library (also a .lib). In order to avoid projects built on top of my library having to worry about this third party dependency, I have used the librarian to include it in mine (Project Properties > Librarian > General > Additional Dependencies).
However, when I build a separate executable project which links to my library, I get a bunch of warnings along the lines of:
MyProject.lib(someThirdPartyObjectFile.obj) : warning LNK4099: PDB 'vc110.pdb' was not found with 'MyProject.lib(someThirdPartyObjectFile.obj)' or at '\vc110.pdb'; linking object as if no debug info
This means (I assume) that I will be able to debug any code belonging to my library, but not to the third party library.
How can I instruct Visual Studio to also include the contents of the third party library's PDB in mine?
The static library has probably been moved, so the compiler can't find the symbols from it. You have several options:
change debugging format to /Z7, which embeds the debug info in the code (whereas /Zi and /ZI put it in a separate file).
change the output configuration of the pdb file (for VS2005 it was Settings > C++ > Output Files > Program Database File Name, probably similar in VS2010).
You can find more information here and here.
Go to Property Pages (Alt+F7)
Linker, All options, Generate Debug Info set into No Position
Related
I have some confusion about static and dynamic linked libraries and .lib and .dll files.
I have a project with two libraries, one I built myself and one is from an open source library.
The one I built myself is a separate project in the same solution (Visual Studio 2015, C++), and I don't need to copy over the .lib files or create a DLL for the executable to build and run
For the other open source library, I do need to copy over the .lib file and the DLL into the executable folder. However, I thought it would be possible to statically link a .lib file and not have to copy over the DLL.
Does this mean I need to compile the Open Source library differently? Like change the define __declspec(dllexport) to __declspec(dllimport) ? Or change /mD to /mT in compiler options?
I tried both of these, but it's still saying that it can't start without the .dll
Or can I get away with changing a setting in the executable project to link this library statically? If so, what are these settings?
EDIT: I know this is a standard question that can be looked up on google, but I haven't been able to find an exact answer for a while. Mainly, I'm confused about what settings need to be changed, and which project they need to be changed in. (The library or the executable).
I'm under assumption that static linking means the library is built into the executable, and dynamic linking means the library needs to be in a separate file, if this is incorrect, please let me know. Otherwise, I need to know how to build the library into the executable file.
And I can go ahead and change the build options in the open source library, and I tried this already.
Thanks,
-D
In Windows, dll files (dynamically linked libraries) need to be in the same directory as the application or on the search path. lib files (static libraries) need to be statically linked during linking (the last step of building the application). It's common in Windows so have a library come with both a dll and lib file. In this case, the lib file is an import library containing the information needed to easily link to the dll.
Place the dll file where your application will be built and statically link with the lib file. Go to 'Project->Properties->Link->Input->Additional Dependencies' and 'Project->Properties->Link->General->Additional Library Directories' to specify the static libraries you want to link.
Edit: It seems I misunderstood the question. The question is how to recompile a dynamic library as a static library. You need the source code of the library you are using along with it's Visual Studio Project file. Open the library and in `Project->Properties->General->Configuration Type' change it from Dynamic Library to Static Library.
Beware that Dynamic Library uses the Linker group of properties while the Static Library uses the Librarian group of properties. Changing between these types may cause the project to drop essential linker flags options. Since every library is different, I can't predict what you will have to do work around this. Make sure to backup the project file so you can see the original options and flags.
I had to change the setting for "Static Library" for All Configurations, not just Debug, although it was building in Debug. Not sure what may have caused this. Possibly because the debug and release builds for the library were set to the same folder, it may have been overwriting the debug builds with release builds when building
I am trying to create a C++ project in Visual Studio 2013 that has CGAL and Boost (and a couple of other libraries) as dependencies. I preferably like to link to these libraries dynamically. Also, I'd like to link to the "Release" versions of these libraries for performance reasons (not the "Debug" versions).
Starting from an empty C++ project, I added the path to header files of the aforementioned libraries as shown in the image below:
Inside the linker options, I then added the directories that contain the DLL and lib files of the external libraries. (CGAL directory contains CGAL's compiled DLL files along with lib files).
At this point, I have not added a single "lib" file "Additional Dependencies" dialog:
Now something weird is going on and I cannot explain why. If I try to build the project as-is (under the "Debug" configuration), I get a LNK1104 error about the linker not being able to find CGAL-vc120-mt-gd-4.7.lib. I know that the error means I should add the lib file in "Additional Dependencies" dialog...
But wait... WHAT...?!!
How does Visual Studio know how to automatically link against this lib file?! Worse yet, how does it know it needs the "debug" version of the library? (With the gd suffix). Also, how does it know I compiled CGAL with VS2013!!??
At first, I though the project was inheriting properties from some preset property sheets somewhere in my system. But I am certain that's not the case as this behavior shows even with a project created from scratch.
My main question is, how would you force Visual Studio to link against the "Release" version of this library? (eg. CGAL-vc120-mt-4.7.lib)
Side question but related: Am I even linking against the DLL files? How can I be certain that I am in deed doing dynamic linking and not static linking?
This is probably happening due to the #pragma comment(lib) mechanism - eg see What does "#pragma comment" mean?
This is a way of the compiler emitting instructions for the linker so that it can decide between multiple versions of a library depending on the compiler version. In this case it means that it can automatically pick up the correct version of the library (debug vs release, vs2013 vs vs2015, MT vs MD, etc). When you added the explicit reference to the library in Additional Dependencies then it is now trying to look for two files.
So, to fix the problem, remove it from Additional Dependencies and let VS pick the right library. If you are getting the LNK1104 error then it suggests that either the link library path isn't set up correctly, or you don't have the CGAL library file it's looking for. You can increase the verbosity settings for the linker in the Project Options to get more detail about what's happening.
For learning purposes, i wanted to create a static library, a "package" of the lib files used in opencv to then link it against my app "opencvuser". Doing so, i get tremendous amounts of erros. (LNK2005 and LNK2019)
My Setup:
Project: staticLib
I've created a static library application without precompiled headers.
Under librarian i've put D:\OpenCV248\build\x64\vc10\staticlib as an additional library
directory. And I've specified all available .lib files as additional
dependencies. (opencv_core248d.lib, opencv_imgproc248d.lib, opencv_highgui248d.lib, ...) Source
Project: opencvuser
I've added C:\OpenCV240\build\include as an additional include directory
Then i've listed "staticLib" under "Properties -> References"
What i expect: Now i should get the same functionallity, as i would add the opencv lib files instead of my built staticLib.lib is my expectation correct?
What i've checked so far:
All Projects are x64
Runtime-Library is set in both Projects to "Multi-threaded Debug"
Anyone knows if the Runtime-Library setting on the static libraries are set to "Multi-threaded Debug"?
You are getting those linker errors because the OpenCV libs you are trying to use were statically linked against the CRT. In your project, you are dynamically linking to CRT and these things won't mix. I would recommend that you don't try to create a "package" of all the OpenCV libs and instead just link to the specific libs you need where you need them.
But I am also going to show you how to solve your problem:
You need to recompile OpenCV without statically linking to the CRT.
You can check out the OpenCV documentation for instructions on how to compile OpenCV using CMake and Visual Studio 2010.
When you run CMake, after you pressed the "Configure" button, look for an option called "BUILD_WITH_STATIC_CRT" and disable it. Then you can press "Generate", open the solution with VS2010 and compile OpenCV.
In your VS2010 project, use the following settings:
In the "opencvuser" project configuration, under Librarian, additional library directories you need to add the path to where the .lib files that you built are located. For me, it's in "c:\opencv248\mybuild\lib\Debug\".
Under Additional Dependencies, you need to include all the OpenCV lib files (opencv_core248d.lib, etc). I also needed to include Comctl32.lib and zlibd.lib because if I didn't I would get some linker errors.
Here are the dependencies I put in:
opencv_calib3d248d.lib
opencv_contrib248d.lib
opencv_core248d.lib
opencv_features2d248d.lib
opencv_flann248d.lib
opencv_gpu248d.lib
opencv_haartraining_engined.lib
opencv_highgui248d.lib
opencv_imgproc248d.lib
opencv_legacy248d.lib
opencv_ml248d.lib
opencv_nonfree248d.lib
opencv_objdetect248d.lib
opencv_ocl248d.lib
opencv_photo248d.lib
opencv_stitching248d.lib
opencv_superres248d.lib
opencv_ts248d.lib
opencv_video248d.lib
opencv_videostab248d.lib
Comctl32.lib
zlibd.lib
Also, in the "opencvuser" project you need to add an empty .cpp file. If you don't add this file, the solution will be empty and Visual Studio won't compile it. I just added a file called "dummy.cpp" to the project. That file is completely empty. Don't put a "main()" function in it because it will collide with the main function in the other project and you will get an error.
In the "staticlib" project, under Linker->General, Additional library directories, you need to include the path to the opencvuser.lib file. For me, it's "..\debug". Also, under Linker->Input, Additional Dependencies, you need to add the "opencvuser.lib" file.
Set project dependencies
You also need to make sure that the projects are built in the right order (first opencvuser, then staticlib). To do this, right-click on the solution and choose Properties. In that window, under Common Properties->Project dependencies, make sure that "opencvuser" does not have a dependency on "staticlib", but "staticlib" must have a dependency on "opencvuser".
That's it, now your project should work. Here are the contents of the two files, and the project running.
When building a static library (.LIB) in MS Visual Studio 10 with debug information,
the .PDB is always named vc100.pdb.(as opposed to building a .DLL, where the debug info is [MyProjectName].pdb)
This is a problem for me because I'm trying to copy several different libraries (and their debug symbols) to a directory of "PublishedLibraries", but all the vc100.pdb names obviously collide.
I'm sure I can change the names of each .PDB to match its .LIB, but for me the bigger question is why does Visual Studio think vc100.pdb is a better name than projectA.pdb??How are we intended to work with Debug Info from multiple libraries if all the names conflict?
If you use /Z7 (instead of /ZI or /Zi) [ in the UI C/C++ -> General -> Debug Information Format] then the debug information is embedded in the lib file itself, instead of a separate pdb, which means you don't need to worry about the same name.
When you build your final executable (.exe or .dll) then you'll get a merged pdb from all the little embedded pdbs.
see this question for more info
Its the way I've always managed this issue on my team, as you can't lose the debug information during the build process. It bloats the libs somewhat [but no more in total than having both lib and pdb], but as you probably don't ship libs you shouldn't worry to much about this.
In VS2010 there is an option to generate debug info for exes/dlls under linker but no such option under librarian for libs. Is the debug info embedded in the static library?
There is an option in the C/C++ properties for Program Database File Name for libs, exes, and dlls. By default it goes into my intermediate directory and is named the project name for libs, but is named vc$(PlatformToolsetVersion).pdb for exes/dlls. What's the pdb from this option and how does it differ from the pdb in the linker option?
If I am supplying a library with libs and headers how do I supply debug symbols to a user of my library?
If you use /ZI or /Zi (C/C++ -> General -> Debug Information Format), then the vc$(PlatformToolsetVersion).pdb is created, which contains the debug info for all of the .obj files created. If alternately you use /Z7, the debug info will be embedded into the .obj file, and then embedded into the .lib. This is probably the easiest way to distribute the debug info for a static library.
I wouldn't advise distributing a static library, however, since it's generally tied to a specific version of the compiler.
Expanding upon previous answers, for those who need the full how-to (VS 2013 minimum).
Note that this should address comments ^^above regarding VS2013 issues.
Method 1: The Program Database (.pdb) Way (/Zi or /ZI)
Static Lib Project: Generate a pdb with same name as your static lib:
Open Solution Explorer from the View menu.
Right click your static lib project, select Properties
Edit Configuration Properties->C/C++->General->Debug Information to /Zi or /ZI
Note that /ZI allows "Edit and Continue" editing during debugging
Edit Configuration Properties->C/C++->Output Files->Program Database File Name to $(OutDir)$(TargetName).pdb
Now compile it, and note where YourLib.lib and YourLib.pdb are.
Application Project: Link your executable with the static lib, and new PDB file:
Again, navigate to project properties, but this time, for your Application project
Again, edit Debug Information property as needed.
Edit Configuration Properties->Linker->General->Additional Library Directories, adding your own "libs" directory, or whatever directory you plan to keep/copy your YourLib.lib and YourLib.pdb files.
Edit Configuration Properties->Linker->Input->Additional Dependencies, adding YourLib.lib (no path in front)
Now copy both YourLib.lib and YourLib.pdb to the directory you specified above.
Method 2: The Embedded Symbols (no .pdb) Way (/Z7)
Static Lib Project: Generate a static lib with embedded debug symbols
As in Method 1, navigate to project properties
As in Method 1, modify your Debug Information, but this time to/Z7
As in Method 1, compile and note where YourLib.lib is generated.
Application Project: Link you executable with the static lib
As in Method 1, navigate to project properties
As in Method 1, modify your Debug Information property as needed
As in Method 1, edit Additional Library Directories
As in Method 1, edit Additional Dependencies
Now copy YourLib.lib to the directory specified in Additional Library Directories
Discussion:
Advantages of Z7? It's simpler, and the "Single-file" way of doing it. All the debug info is in the lib file.
Disadvantages of Z7? File size on-disk, link times, incompatible with "Minimal rebuild" (/Gm) feature, does not allow "Edit and Continue", older format (e.g. older paradigm)
Why don't I specify Debug Information Setting for Application Project? This post is concerned with how to get debug working in static lib code. The same "Method 1 vs Method 2" choice applies for the Application project as well.
I notice in VS2013 it is possible to set the program database file name in the C/C++ Output Files tab. Changing it from the default to something like $(OutDir)$(TargetName).pdb resolves the issue
Static libraries are implemented into the programs that use them.
If the program that uses them is using debug symbols, the compiled library code in that program will have symbols too.
PDB info from wikipedia:
When debug symbols are embedded in the binary itself, the file can
then grow significantly larger (sometimes by several megabytes). To
avoid this extra size, modern compilers and early mainframe debugging
systems output the symbolic information into a separate file; for
Microsoft compilers, this file is called a PDB file.
Weird behavior in VS2012. Building from scratch (or with /A option in nmake) will produce a .pdb file. Now delete the .lib and .pdb and rerun nmake (without /A of course, to run only link) and no .pdb file is output.