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
Related
This question already has answers here:
How do I set the path to a DLL file in Visual Studio?
(7 answers)
Closed 7 years ago.
In Visual Studio 2010, under VC++ Directories > Executable Directories, I have specified the path to glew32d.dll. However, when I run the executable, it still complains.
On the other hand, if I copy the DLL into the local folder and run the executable then, it doesn't complain.
Can someone please tell me how to fix this? Also, why is Visual Studio not recognizing that path?
Update
Scenario: I currently use a template project which I use as a starter code for a lot of my projects. This template depends on glew32d.dll. I usually store all dependent dlls in a common bin folder. I was hoping to reference this folder and Visual studio could read the dlls from there, instead of me having to copy the dlls everytime. What would be a good way to handle this?
Specifying the path to the DLL file in your project's settings does not ensure that your application will find the DLL at run-time. You only told Visual Studio how to find the files it needs. That has nothing to do with how the program finds what it needs, once built.
Placing the DLL file into the same folder as the executable is by far the simplest solution. That's the default search path for dependencies, so you won't need to do anything special if you go that route.
To avoid having to do this manually each time, you can create a Post-Build Event for your project that will automatically copy the DLL into the appropriate directory after a build completes.
Alternatively, you could deploy the DLL to the Windows side-by-side cache, and add a manifest to your application that specifies the location.
I've experienced same problem with same lib, found a solution here on
SO:
Search MSDN for "How to: Set Environment Variables for Projects".
(It's Project>Properties>Configuration Properties>Debugging
"Environment" and "Merge Environment" properties for those who are in
a rush.)
The syntax is NAME=VALUE and macros can be used (for example,
$(OutDir)).
For example, to prepend C:\Windows\Temp to the PATH:
PATH=C:\WINDOWS\Temp;%PATH%
Similarly, to append $(TargetDir)\DLLS to the PATH:
PATH=%PATH%;$(TargetDir)\DLLS
(answered by Multicollinearity here: How do I set a path in visual studio?
try "configuration properties -> debugging -> environment" and set the PATH variable in run-time
To add to Oleg's answer:
I was able to find the DLL at runtime by appending Visual Studio's $(ExecutablePath) to the PATH environment variable in Configuration Properties->Debugging. This macro is exactly what's defined in the Configuration Properties->VC++ Directories->Executable Directories field*, so if you have that setup to point to any DLLs you need, simply adding this to your PATH makes finding the DLLs at runtime easy!
* I actually don't know if the $(ExecutablePath) macro uses the project's Executable Directories setting or the global Property Pages' Executable Directories setting. Since I have all of my libraries that I often use configured through the Property Pages, these directories show up as defaults for any new projects I create.
I have downloaded the Autodesk fbx sdk and trying to build a simple console app. I have added additional directories in Linker / General / Additional Library Directories like follows:
see the screenshot of the directory below. There are several libs that (I suppose) I should add in dependencies, and there's also the .dll file. It's release folder (debug is another available), for x86 architecture and for VS2017 which I am using.
Also, I have add dependencies like below and have included the standard include folder as specified in the Autodesk manual
The project builds fine but shows the following when run:
Cannot run code because libfbxsdk.dll could not be found...
But it is in the folder as you can see in the pic. Could you pls help?
The linker settings have nothing to do with finding DLL files at run-time. If you want this SDK to be available to all programs - which without reason to do otherwise would be my recommendation - hit the start button and search for "environment", choosing "Edit environment variables for your account". Edit the value of the PATH environment variable (adding it if necessary) to include the directories where the DLLs are located.
If you only want it to be available to this particualr program (and you don't have any other custom DLLs that need to be found) you could also change the startup directory in the project properties to the directory where the DLL files can be found (the startup directory is one of the locations in the system search path).
I am working on a project that involves making a dynamic link library, so I want to test it in a console app in Visual Studio.
The DLL is also made in Visual Studio, it doesn't have much, just a few functions in it. I'm not sure if I'm just supposed to include the librarys header in the include directories panel in Properties, or do something else
A lot of people say I'm supposed to add its corresponding .lib file in the Library or Reference directory, but I'm not sure that VS generates a .lib file alongside the DLL. I'm using VS 2015.
I don't have VS in front of me this very moment, but these should be the general steps to set it up:
Properties->Linker->Input: your.lib
Properties->Linker->Additional Library Directories: ../your/bin
Properties->General->Compiler->Additional Include Directories: ../your/include
To build your app, the DLL's API headers must be in the include for the compile-time, it's LIB files in the bin for the link-time. Once you have your app EXE, all you need is the DLL to be in the same folder as your EXE when it executes.
You might also want to add the dll project and the app project into a common solution in VS and add (right click) Project Dependency from the app to the dll. This ensures correct order of building, assuming you are going to build the dll at all.
You can also do what I did.
You can create a Libs directory inside of your Solution directory.
You can then place your .DLL files inside of the Libs directory or some sub-directory inside of Libs
In my case, I added the entire SFML-2.3.2 directory in there, which included the source-code, .lib files, and .dll files.
I did link up what I could in the project properties, but I used Visual Studio's macros to fill in the path name to the Solution directory. Just in case I wanted to put this in version control and work on it from multiple machines.
Then I opened up the Project's Property Page.
Within the property page, I went to Build Events -> Post-Build Event -> Command Line
Within the Command Line, you can add a copy command that will copy any needed files into the same directory as the executable that will need them.
In my case I used: copy "$(SolutionDir)Libs\SFML-2.3.2\bin\*" "$(TargetDir)"
I could have written multiple commands to copy just the individual files that I needed, but I had spent a good three hours trying to get SFML to work without actually installing it.
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.
I understand that I need to use LoadLibrary(). But what other steps do I need to take in order to use a third-party DLL file?
I simply jumped into C++ and this is the only part that I do not get (as a Java programmer). I am just looking into how I can use a Qt Library and tesseract-ocr, yet the process makes no sense to me and is so difficult to google.
How do I tell the compiler of the functions that I am using? Should there be an include file from the third-party vendor?
As everyone else says, LoadLibrary is the hard way to do it, and is hardly ever necessary.
The DLL should have come with a .lib file for linking, and one or more header files to #include into your sources. The header files will define the classes and function prototypes that you can use from the DLL. You will need this even if you use LoadLibrary.
To link with the library, you might have to add the .lib file to the project configuration under Linker/Input/Additional Dependencies.
To incorporate third-party DLLs into my VS 2008 C++ project I did the following (you should be able to translate into 2010, 2012 etc.)...
I put the header files in my solution with my other header files, made changes to my code to call the DLLs' functions (otherwise why would we do all this?). :^) Then I changed the build to link the LIB code into my EXE, to copy the DLLs into place, and to clean them up when I did a 'clean' - I explain these changes below.
Suppose you have 2 third-party DLLs, A.DLL and B.DLL, and you have a stub LIB file for each (A.LIB and B.LIB) and header files (A.H and B.H).
Create a "lib" directory under your solution directory, e.g. using Windows Explorer.
Copy your third-party .LIB and .DLL files into this directory
(You'll have to make the next set of changes once for each source build target that you use (Debug, Release).)
Make your EXE dependent on the LIB files
Go to Configuration Properties -> Linker -> Input -> Additional Dependencies, and list your .LIB files there one at a time, separated by spaces: A.LIB B.LIB
Go to Configuration Properties -> General -> Additional Library Directories, and add your "lib" directory to any you have there already. Entries are separated by semicolons. For example, if you already had $(SolutionDir)fodder there, you change it to $(SolutionDir)fodder;$(SolutionDir)lib to add "lib".
Force the DLLs to get copied to the output directory
Go to Configuration Properties -> Build Events -> Post-Build Event
Put the following in for Command Line (for the switch meanings, see "XCOPY /?" in a DOS window):
XCOPY "$(SolutionDir)"\lib\*.DLL "$(TargetDir)" /D /K /Y
You can put something like this for Description:
Copy DLLs to Target Directory
Excluded From Build should be No.
Click OK.
Tell VS to clean up the DLLs when it cleans up an output folder:
Go to Configuration Properties -> General -> Extensions to Delete on Clean, and click on "..."; add *.dll to the end of the list and click OK.
These are two ways of using a DLL file in Windows:
There is a stub library (.lib) with associated header files. When you link your executable with the lib-file it will automatically load the DLL file when starting the program.
Loading the DLL manually. This is typically what you want to do if you are developing a plugin system where there are many DLL files implementing a common interface. Check out the documentation for LoadLibrary and GetProcAddress for more information on this.
For Qt I would suspect there are headers and a static library available that you can include and link in your project.
In order to use Qt with dynamic linking you have to specify the lib files (usually qtmaind.lib, QtCored4.lib and QtGuid4.lib for the "Debug" configration) in
Properties » Linker » Input » Additional Dependencies.
You also have to specify the path where the libs are, namely in
Properties » Linker » General » Additional Library Directories.
And you need to make the corresponding .dlls are accessible at runtime, by either storing them in the same folder as your .exe or in a folder that is on your path.
You only need to use LoadLibrary if you want to late bind and only resolve the imported functions at runtime. The easiest way to use a third party dll is to link against a .lib.
In reply to your edit:
Yes, the third party API should consist of a dll and/or a lib that contain the implementation and header files that declares the required types. You need to know the type definitions whichever method you use - for LoadLibrary you'll need to define function pointers, so you could just as easily write your own header file instead. Basically, you only need to use LoadLibrary if you want late binding. One valid reason for this would be if you aren't sure if the dll will be available on the target PC.
I'f you're suppsed to be able to use it, then 3rd-party library should have a *.lib file as well as a *.dll file. You simply need to add the *.lib to the list of input file in your project's 'Linker' options.
This *.lib file isn't necessarily a 'static' library (which contains code): instead a *.lib can be just a file that links your executable to the DLL.