3

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:

Include directories

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).

enter image description here

At this point, I have not added a single "lib" file "Additional Dependencies" dialog:

enter image description here

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...

enter image description here

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?

Maghoumi
  • 3,295
  • 3
  • 33
  • 49
  • 1
    There is a `#pragma (comment:lib)` https://support.microsoft.com/en-us/kb/153901 that can be used to automatically specify what library to link to. Don't know if this is how your scenario is doing things, but that is one way to not have to specify the library using the project settings. – PaulMcKenzie Nov 11 '15 at 23:07
  • 1
    Library authors in general attempt to defeat these kind of "how do I crash the library code in impossible to diagnose ways" shenanigans. Clearly the CGAL authors picked up the technique that Boost uses, it is pretty solid. The kind of wisdom inspired by having to deal with thousands of mailing list questions. Feature, not a volkswagen, use the /NODEFAULTLIB linker option at your peril. – Hans Passant Nov 11 '15 at 23:21
  • @HansPassant Thanks for the tip. How would the CGAL authors then know what the lib file should be in advance?! I would get `CGAL-vc120-mt-gd-4.7.lib` only if I compiled with VS2013 and MT enabled! What mechanism would they use to force the specific library version? – Maghoumi Nov 11 '15 at 23:37
  • 1
    They use predefined macros, the kind that the compiler sets based on compile options. Like _DLL, defined when you compiled with /MD. "mt" means multi-threaded, nothing to do with the /MT compile option. They drive a different volkswagen. – Hans Passant Nov 11 '15 at 23:43
  • @HansPassant Cool thanks! That's what I kind of thought... Anyway to override these without fiddling with /NODEFAULTLIB? I thought about using /NOFEFAULTLIB and then manually add the libraries it needs but that's not probably such a good idea... The reason I would want this is that I still need to be able to debug the code that calls CGAL's stuff. But CGAL's "Debug" dll is waaaaay too slow. – Maghoumi Nov 11 '15 at 23:47
  • 1
    Well, of course, but then you have to pick compile settings you don't like. You can only ever hope that release build libraries work with the release build of your code. Debugging such code is, erm, character building. – Hans Passant Nov 11 '15 at 23:54
  • @HansPassant Then how would one go about (say) creating a wrapper for some CGAL functions, when the wrapper clearly needs debugging enabled (to track and fix bugs in development) and the debug version of CGAL is excruciatingly slow? What is the standard way? – Maghoumi Nov 12 '15 at 00:04
  • You fix your debugging and testing techniques Using a dataset of 10000 items instead of 1000 does not make it 10 times more likely you will find a bug. The increments get very small after you fix the basic ones. – Hans Passant Nov 12 '15 at 00:25
  • @HansPassant I agree but since I'm still learning a lot of things, I debug unknown behaviors using trial/error: run, breakpoint, inspect, run again (don't kill me please!). On a side note, I used /NODEFAULT:library to un-force linking against debug libs. After that I used "Additional Libraries" to force linking against release libs. Seems it is working :) I know it is probably a very bad approach so by all means feel free to suggest alternatives or point me in the right direction. I can and do read :) Thanks for the tips as well. – Maghoumi Nov 12 '15 at 00:29
  • OK! I found this (http://stackoverflow.com/questions/11658915/mixing-debug-and-release-library-binary-bad-practice) and now I'm starting to understand what you meant :) – Maghoumi Nov 12 '15 at 01:03

1 Answers1

5

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.

Community
  • 1
  • 1
the_mandrill
  • 29,792
  • 6
  • 64
  • 93
  • So does that mean there is a `#pragma comment` somewhere in the files that's forcing VS to use that particular lib file? How do I find the file that's causing it (I tried the /VERBOSE switch, but there isn't much going on). Also, remove what exactly from "Additional Dependencies"? In the question I said my "Additional Dependencies" is empty. – Maghoumi Nov 11 '15 at 23:32
  • I searched all the header files that I'm using (mine, CGAL's and Boost's) using `grep` and did not find any `#pragma comment` related to libs anywhere! – Maghoumi Nov 12 '15 at 01:12
  • 1
    In boost it's defined in `config/auto_link.hpp`: `# pragma comment(lib, BOOST_LIB_PREFIX BOOST_STRINGIZE(BOOST_LIB_NAME) BOOST_LIB_THREAD_OPT BOOST_LIB_RT_OPT ".lib")` – the_mandrill Nov 12 '15 at 16:45