Static library debug symbols - c++

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.

Related

Visual Studio Static Linking for Standalone Exe

I've read multiple posts with regards to this topic, but none of them have enabled me to build a statically linked exe.
In my release configuration (x64) I have the following:
Configuration Properties -> General : Use of MFC - Use MFC in a Static Library
Configuration Properties -> C/C++ -> Code Generation : Runtime Library - Multi-threaded (/MT)
Configuration Properties -> Linker -> Command Line : Additional Options - I have all the required Windows libs "kernel32.lib", etc. (as use of MFC removed them from the "All Options" window above)
Configuration Properties -> Manifest Tool -> Input and Output : Embed Manifest - No
Note that in Configuration Properties -> Linker -> Input there are 5 lib files that I'm using in my project, eg glfw3.lib and I'm using Full optimisation (/Ox).
After building the project and running the exe myself I receive errors "The code execution cannot proceed because glfw3.dll was not found..." etc.
Using dependencywalker I can see that it needs the dlls associated with the libs, which it of course cannot find.
Am I misunderstanding how to do this or is there something else that might be wrong?
(I'm using Visual Studio 2017)
Yes, it appears you have a slight misunderstanding.
If something is offered as a DLL, then it is meant to be used as a DLL. There may be some way to incorporate a DLL into an executable, but it would be a hack. That's not how things are supposed to work.
The lib file that you are linking against exists simply in order to provide you with functions that you can link against, and these do nothing but delegate to the corresponding functions in the dynamically loaded DLL. Without it you would have to locate each entrypoint of the DLL yourself, which would be perfectly doable, but a bit cumbersome.
So: you must either find a version of glfw3 which is packaged as a statically linkable library (I have no idea whether one exists) or live with the fact that your .exe will need to be shipped together with glfw3.dll.

Are lib files exclusively statically linked or do they need to be compiled specifically (VS2015)

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

How to set Debug Symbol Path via .props file

After a restructuring of our project, all the 3rd-party libraries ended up in a single system-wide directory. A set of .props files ensures that the include-directories, library-directories, prepocessor definitions, etc. are set correctly upon including such a .props file.
Currently we advise developers to specify the symbol paths by hand using Visual Studio -> Menu Tools -> Options -> Debugging -> Symbols. But when moving the 3rd-party libraries to another folder, or when seting up a second set for testing, we have to change this manually.
Is it possible, and how, to specify the debug symbol path in a .props file? And how?
And of course, is it possible to set the sourcepath (for debugging) in a .props file?
That's not possible. It is a VS setting, not a project setting.
In general it doesn't make sense to have this problem. If these libraries are static link libraries then their .pdb files get merged into the .pdb file for the final executable. If they are DLLs then there needs to be a way for the operating system to find the DLL at runtime. In which case the debugger also won't have any trouble finding the .pdb file for the DLL.
You can diagnose .pdb searching problems for DLLs with Debug + Windows + Modules. Right-click the DLL and select "Symbol Load Information". It shows you where the debugger searched for the .pdb

Including .pdb files with librarian in Visual Studio

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

VSPerf VS2010 and other profiling tools not picking up pdb

trying to profile with VSPerfCmd (VS2010 profiler), and also with Intel VTune Amplifier XE 2013: some results are available, for VsPerfCmd in .vsp file. However, profier is not picking up pdb. no code is available for some parts of the application.
Did this happened to you already, and do you know if some compiler options should be turned on so as to get complete profile?
in which directory does profiler go to find .pdb info ?
thanks
The profilers and debuggers on Windows by default look up the PDB files by the path written in the executable. So the first thing to do is to open the executable in some hex editor and search for ".pdb" string and check whether file mentioned there exists on disk. If that is not the case, check that you specify /Zi or /ZI option to the compiler and /debug option to the linker.
If symbolic names are missing for SOME parts of the application, check whether those parts are separate dynamic or static libraries and whether you generate debug information for those. In case of static libraries it's easy to get the debug information lost along the linking way since by default /Zi flag embeds the debug information into the vc*.pdb file (e.g. vc90.pdb for VS 2008) and that file is usually not exported into SDK by build systems. For static libraries I personally find the most instrumental to use /Z7 option for debug information since that embeds it into the object files themselves and then to the *.lib file and then it propagates to the final *.exe / *.dll binary's PDB file.