Dependency from .lib to another .lib - c++

I'm trying to build OpenCV v2.3.1 using Intel TBB and IPP. I used CMake to generate Visual Studio 2010 solution. Build is successful and I have opencv_core231d.lib among output.
Now I'm trying to link opencv_core231d.lib with my project. However, after specifying it in Linker -> Additional dependencies, I receive error LNK1104: cannot open file 'tbb_debug.lib'.
That's not the error about unresolved externals. Linker wants specific .lib file from me! How can that be?
I've done dumpbin /all of opencv_core231d.lib and for several sections it tells me:
Linker Directives
-----------------
...
/DEFAULTLIB:"tbb_debug.lib"
...
I tried to add tbb_debug.lib to /NODEFAULTLIB linker option of my project and it solved the problem. However, I just want TBB to be linked in opencv_core231d.lib.
The strange thing is I cannot find any reason why tbb_debug.lib is added to /DEFAULTLIB option of opencv_core231d.lib. I've searched all files in solution directory mentioning tbb_debug.lib as a substring, but the only matches was in generated .obj and .lib files - not in any source or project files. Where is the magic?
This question is not only related to OpenCV, but to whole process of working with .lib-files.
Update
There was a #pragma comment(lib, "tbb_debug.lib") directive in TBB include file _tbb_windef.h, so now I can understand from where did it go.
What I still don't understand is why it is not statically linked in opencv_core231d.lib? I've set Librarian -> Link Library Dependencies option to Yes. And there are no #pragma comment(lib, "tbb_debug.lib") directives in my project - I've checked preprocessor output.
Thanks.

There's probably a #pragma comment(lib, "tbb_debug") somewhere in one of the header files you are including.
This is to do with using the thread building blocks by Intel. See this blog post for more information: http://software.intel.com/en-us/blogs/2008/07/07/get-tbb-going-by-a-single-click/

Related

Visual Studio (C++) is automatically linking against an unwanted version of lib file

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.

Add obj file to linker input with cmake

I have a cmake project that needs to link to a library that contains some .lib files and a .obj file. I've found some clues to how to link to a .obj file, but most solutions seem very complex.
All I really want to do is tell cmake to add the .obj file to the linker input in my Visual Studio project.
I tried linking it as I am doing with normal lib files:
target_link_libraries(Foo C:/a.lib C:/b.lib C:/c.obj)
However when I check the linker input in the generated VS project, cmake has removed the full-path and appended .lib to the obj file:
C:/a.lib
C:/b.lib
c.obj.lib
What's the simplest way of getting this result:
C:/a.lib
C:/b.lib
C:/c.obj
Note that this only needs to work with Windows and Visual Studio.
I was facing facing the same issue when I found your question. It is solved by the following line:
SET_TARGET_PROPERTIES(my_project PROPERTIES LINK_FLAGS "/link setargv.obj")
The link is appended to Additional Options in the Command Line Section from project's linker settings.

Importing a library in MS Visual Studio from the same solution

So I have my solution file here, which contains 4 projects.
Project A is a library which gets compiled into a .lib.
Project B is a program which becomes an .exe.
I have set up Project A as dependency for Project B, and I included
#pragma comment(lib,"terrain.lib")
into the file in Project B which uses the library.
In spite of both projects being compiled into the same Debug / Release folder, MSVCC tells me
1>LINK : fatal error LNK1104: File "terrain.lib" could not be opened.
// <freely translated from German, could mean "not found">
This:
#pragma comment(lib,"../Debug/terrain.lib")
works, but then I have to change it for release.
Is the only valid way for this using #ifdef ?
You need to specify library path in project settings ("additional library directories" in linker settings - at least in vc2008), for both debug and release configuration. You can use macros like ${ConfigurationName} and ${SolutionDir}, so specifying paths within project should be easy enough.
Also it might be a better idea to include libraries using linker settings instead of #pragma comment.

Linker Trouble: How to determine where a "/DEFAULTLIB" is coming from

I am trying to find a good way to determine what module at link time is causing a certain library to get processed as a "/DEFAULTLIB" as seen in the verbose linker output from Visual Studio.
Here is my situation, I have several static library pre-requisites and each has a release and a debug version (BlahD.lib and Blah.lib). For some reason at link time all of the *D.lib's are processed as default libraries even though I am building a release with the non-debug libs specified as "Additional Dependencies". If I never build the debug versions of the static libraries those *D files wouldn't exist and there would be a linker error (can't open file).
I can get my project to build successfully by specifying /NODEFAULTLIB for all of these offending .lib files. All the release libraries link up and everyone is happy. But I want to understand what is going on here. What is causing these *D.lib files to be processed by the linker? Is my only hope to write some kind of script that dumpbins everything in this massive project and its dependant projects (microsoft support)? Even then I don't understand what to look for in the dumpbin output, does this apply to the .lib files as well the .obj files?
I had a similar problem. I was only able to solve it by analyzing the *.obj files as you suggested. To do it, I ran the following command via the Visual Studio command prompt (in the temp folder of the project, where *.obj files are generated):
for /R %1 in (*.obj) do #dumpbin /directives /section:.drectve "%1" > "%1".directives.txt
Then I used Notepad++ to search for the name of the offending library in all of these *.directives.txt files. This revealed which project was referencing the wrong lib.
Note: you may want to modify this to include any 3rd-party *.lib files your project may use, and not just *.obj files. "/DEFAULTLIB" directives may also come from them.
Note: you may need to use *.o instead of *.obj
Look for #pragma comment(lib) in the source. See if it perhaps is dependent on a #define - This is a common way for a SDK to ensure that the right libs are linked, and you may need to define THESDK_DEBUG or THESDK_RELEASE for the logic to work out.
Additional information:
I discovered in Visual Studio 2008 that even commenting out the statement from the *.idl file does not work, as in:
//cpp_quote("#pragma comment( lib, \"MYLIB.lib\")")
The compiler still adds MYLIB.lib as a DEFAULTLIB, and it winds up in the *.obj file. Make sure you remove the line completely from the code!
Link with the /verbose option and search the output for the name of the library in question. This will tell you which object file dragged the library into the link.

glew32.lib linker error

I am writing a basic toon shader in OpenGL. I am using MSVC 2008. I have included the GLEW libraries. I have also set the additional dependencies in linker. But I am getting the following error:
LINK : fatal error LNK1104: cannot open file 'glew32.lib'
You need to set your linker to look in the correct place for the library. Either you don't have the lib, or your linker can't find it. Open your project properties dialog, go to linker, specify the lib as a dependency and provide the path to the correct lib folder.
you can also drag and drop the glew32.lib (or any other lib file of course) into your visual studio project and i think it will be automagically linked in and the linker will find it (which i think is your problem).
anyhow, i prefer setting my search directories by hand.
add this:
#pragma comment(linker, "/NODEFAULTLIB:libc.lib")
It will definitely solve your problem.