I think my problem is that the Visual Studio static library linker hardcodes relative paths, and this causes problems later when linking against that static library from a different directory.
Here's what I'm trying to do:
I have a library dll, call it base.dll.
I have an application that links against this dll: application.exe. In order to write unit tests for this application, I compile the application as a static library: application.lib.
I have a testing project that compiles testing.dll that links against application.lib.
In the last step, the linking fails with LNK1104 (cannot open file) because it is using the relative path of application.exe, not of testing.dll. Testing.dll has already linked successfully to base.dll earlier in the process.
Any suggestions?
Try checking "Inherit from parent or project defaults" in the "Library Directories" dialog for each project.
I have had similar issues with my own library projects, and there is not much documentation out there on this.
The trick is to not link against base.dll when I build the static library, and only link against it when I build testing.dll.
Related
I have a project that I would like to unit test in Visual Studio 2013. I have changed the project type to a static library (lib) after getting some linker errors and reading the answer to this question.
I do not understand the underlying mechanisms of compiling and linking in c++. In changing my project to a static library, it seems I have lost the ability to specify additional dependencies, which is a pain because I need three libs for my main project that I would like to test.
What should I do to test this project, is there a way to make my project a static library and still specify additional dependencies?
Static library is a collection of object files. No linker involved. Dependencies are not being resolved. It only requires headers to build.
Now, when you finally create an executable (or a dynamic library), you should link all the necessary dependencies.
However, note that additionally to the "classic" build process described above, Visual Studio IDE provides abstractions (convenient, but sometimes a bit misleading, especially for novices), called "Project references" and "Project dependencies". There are options to make a static library "depend" on other static libraries. Also, executable can depend on that first static library. When "Link dependencies" is enabled, Visual Studio will resolve entire dependency chain recursively and link all the necessary into your executable.
See also:
What does the “Link Library Dependency” linker option actually do in Visual Studio 2010?
MSDN - C/C++ Building Reference
MSDN - Walkthrough: Creating and Using a Static Library (C++)
What is an undefined reference/unresolved external symbol error and how do I fix it?
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.
I thought this should be straightforward but I am running into a bunch of linker errors like so:
Error 1 error LNK1104: cannot open file '...\Debug\Utils.lib' ...\LINK
where Utils is one of the C++ projects I want to keep as DLL.
If I change Configuration Properties->Configuration Type to Static Library(.lib) everything compiles and runs fine, but if I use .dll then its not working.
The whole solution is native C++ with the main project being a win32 console application.
Perhaps your library (Utils.lib) is not assembled as DLL and changes in console application project (that uses library) will not help.
Read carefully MSDN to see features of DLL's creation and usage.
It you try to link a .lib against another .lib, it doesn't really link. Instead, this instructs the final link to use both libraries.
For a DLL, this can't work, as the runtime linker cannot link the original .LIB. That means the link has to happen when the DLL is compiled.
As a result, a DLL project needs to have the .LIB directories set right.
I've created a Static Library (no mfc is used in it) in Visual Studio and want to link with it in statically linked mfc project (com-dll actually).
When linking mfc-lib I get a bunch of messages symbol is already defined. This is because I linked standard C++ library twice (once in static library, and other in mfc project).
How do I fix it?
There is a workaround with /FORCE:MULTIPLE, but I think this is a bad decision.
When linking static libraries to a DLL or EXE project, you need to take care, that all projects have been compiled to use the same runtime library. So please set all projects to the same "Use of MFC" and also to the same "Runtime library". If you do not do so, then one project might have been compiled to take the fopen function from the standard CRT while another project might have been compiled to take the fopen function from the MFC. Mixing these is a problem for the linker because he does not know which runtime (and in the example: which fopen) to use.
When linking your DLL or EXE project against another DLL project, this is not a problem. You can have a DLL without MFC usage and link your MFC EXE against that DLL.
If you have a util library that you use very often in different projects, then you might consider setting up different build settings so you can build your library in DEBUG and RELEASE and with and without MFC. Then in your EXE project you can pick the library binary that matches your project settings.
I am using VS2010 and
I have a C++ project that is referencing and using an external C library (dll) by having various entries in the VC++ Directories and Linker sections of the project properties.
Right now my project is building but when it starts, a message box appears :
The program can't start because ExternalCLibrary.dll is missing from your computer. [...]
I would like to know how to do in Visual Studio 2010 the the equivalent of
adding "-static-libgcc -static-libstdc++" to your compiler flags.
It seems to be the solution according to:
The program can't start because libgcc_s_dw2-1.dll is missing
Load your project in Visual Studio.
Right click your project and
choose Properties.
Locate the "Linker" portion of the tree on the
left.
Choose All Configurations and All Platforms from the drop down
menus at the top of the dialog.
Put your additional static library
dependencies in the Input -> Additional Dependencies field, semicolon delimited.
If the libs are not on your lib search path, make appropriate
entries in the General -> Additional Library Directories field, semicolon
delimited.
Apply, save, compile, run.
You can't use dll as a static library ( that's why they are called Dynamic-link library ). In order to compile a static library, you'll the source code of that library. Once you have the source code, go to Project settings, General->Configuration Type and set it to Static Library(.lib). Then in your program, you'll need to add that library by putting the library name in Linker->Input->Additional Dependencies
The two flags passed to gcc as per your question tell gcc to link the runtime library statically to an executable or shared library/dll. This is unlikely to be the problem with your issue as the part of the error message you quoted suggests that ExternalCLibrary.dll isn't being built properly.
If the DLL exists, use a tool like dependency walker to determine which dependency of your DLL can't be loaded; that's the likely culprit.
If ExternalCLibrary.dll doesn't exist then you need to find out where you are supposed to get it from, but if your project builds and it's listed in the project as a dependency then my guess is that it's an issue with the loader not being able to find a dependency of this DLL at runtime.
This process is simple, however you need to be aware of several things. The first thing, if your lib is written in C, in the header files of every source containing C functions us the following.
#ifdef __cplusplus
extern "C" {
#endif
// C functions
#ifdef __cplusplus
}
#endif
Once you've done that, compile the library into a static library using the ar rcs [YOUR OBJECT FILES]. The final thing to do is us the c++ compiler link the library with the object files from your project. Now flags are required to link the library.