In Visual Studio 2012 what is the difference between Librarian and Linker? - c++

I am configuring my Projects to build with x86 and x64 bits, in order to do that I had to change the Target Machine for the different Configurations.
I was trying to find where to set the Target Machine for my Native C++ Libraries and I found this post.
However I don't have a Linker in the Native C++ Library projects, I have the "Configuration Properties -> Linker -> Advanced -> Target Machine" option in the C++/CLI projects only.
In the Native C++ Library projects I have a "Librarian" section. I searched and I found that the Target Machine is in: Configuration Properties -> Librarian -> General -> Target Machine.
The Librarian section seems to have less options than Linker.
Are the Librarian and the Linker section the same? On the documentation I searched on google I only see Linker mentioned.
Maybe I have something configured wrong? Or in this post the answer didn't refer to Native C++?

Are the Librarian and the Linker section the same? On the documentation I searched on google I only see Linker mentioned.
They are almost the same. Option Librarian is enabled when your project is going to be a static lib. Option Linker is for executables and dynamic (link) libraries (dll).
Dynamic libraries will be linked dynamic to the executable you are building, which means the dll have to be around while execution. Static libraries on the other hand will be part of the executable. Static libraries mustn't be linked to some dynamic lib, since the linkage should be done while generating the executable. Otherwise it would cause ambiguity. This is why the Librarian options are reduced. (e.g. there is no Input options).
Maybe I have something configured wrong? Or in this post the answer didn't refer to Native C++?
The project from the linked post generates a dll (dynamic link library), not a static lib. Check your settings in Configuration Properties -> General -> Configuration Type.

You see the Librarian section when you created a static library project. Do beware that such a project is incompatible with code built with the /clr option, managed code is linked at runtime, not build time. Trying to use such the .lib file gives pretty hard to diagnose linker errors when you try to build an assembly. It is okay if you use it for pure native code, the kind built without /clr in effect.
There's very little to a .lib file, it is just a bag of .obj files. Think of it as a .zip archive with a cr*ppy compression rate. The lib.exe utility is there to get .obj and .lib files added and removed from the .lib, think of it as winzip.
So there are indeed very few settings in the General section, there's just not much to lib.exe. Pretty much a one-to-one mapping to the command line options that lib.exe takes. The /MACHINE option (aka Target Machine setting) is not required, it is fixed by the compiler you used. It is documented as:
However, in some circumstances, LIB cannot determine the machine type and issues an error message. If such an error occurs, specify /MACHINE.
So scratch that idea. It is entirely locked in by the Platform selection you used for your project. Standard ones in VS are Win32 to generate 32-bit code and x64 to generate 64-bit code.

Related

ftd2xx static library link error

I'm working on a DLL project in Visual Studio 2017. This library adds some functionality around the ftd2xx library from FTDI. I set up the project as described in this instruction. I'm linking against the static version of the ft2dxx library. The only difference between the instruction and my project is the selection of the Runtime Library. The instruction states (figure 2.16) that the Multi-threaded Debug Runtime library must be used. In my case, I selected the Multi-threaded Debug DLL (/MDd) option, because i'm working on an DLL (see the image below)
When i build the project, I get the following errors:
When i clicked on the first warning, this page opens. I changed the project properties as described on the webpage:
This fixes the first warning, but the link errors still exists:
So, to conclude: I assume there is something wrong with the Runtime Library, used by the ftd2xx library, but I have no idea how to fix this. Any suggestions?
I found the solution here. The solution is to add the 'legacy_stdio_definitions.lib' to the linker input. To do this, go to the project properties -> Linker -> Input and add 'legacy_stdio_definitions.lib' to the additional dependencies.

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.

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.

Visual Studio C++ - Check the reason of link a specific library

vs report a error such as:
can not find xxx.lib
How do I check out why vs need to link xxx.lib? Is there a trace log? My project have not use boost.regex, but vs report a error says can not find regex.lib. So I want to find out which part of code refer to regex
LNK error: LIBCMT.lib: xxx was already defined in LIBCMTD.lib
How do I check why vs also link yyy.lib even this is a debug build? I have 2 projects, they link to same libs, all libs and project itself was /MTd. But one of them will report above error, I think it shouldn't link LIBCMT.lib because it is a release version lib, and another project is OK so the lib file was build correctly
VS can show the link trace?
1) Let's start with how the linker actually knows what to link with. Basically there are 2 categories:
Libraries specified in the project settings in the linker options as additional inputs
Libraries added in code with precompiler directive #pragma comment (generally the same thing as above but people have different tastes)
Otherwise you just get information about missing symbols but not the actual library they are from. What you can do to help is under visual studio linker options set Show Progress to For Libraries Searched (or just /VERBOSE:LIB linker flag), that will actually show you what dependencies are added after each lib is loaded, this also helps with point 2) to see which library loads which run-time.
2) Already mentioned in 1) that you can make the linker show library load progress, otherwise if a dynamic C run-time is used in the external library you are linking against you could use Dependency Walker to examine the dependencies of the library and find if the C run-time dll that is needed is debug or release by 'd' suffix in the dll name. If the library is already linked with static run-time then I guess only the linker errors will warn you. But I think that most serious libraries are correctly packed and structured so that you will be able to tell which files contain the debug version and which the release. If the library has only release version, well than that's another story. But i mean still, you can reconfigure the Debug configuration of your project to actually link against the release run-time to satisfy the external library, of course this prevents some debugging features, debug heap, etc.
For the missing boost regex library problem, I think the cause is due to boost's default autolink behaviour. If you include one of the headers of some of the boost libraries (not all of them, but regex is one of them), then these will cause Visual Studio to automatically link against the library. It uses a special pragma of the form:
#pragma comment(lib, "regex")
This has the effect of automatically adding a flag to the linker command. However, it's only picked up during compilation and so you won't see it in the project properties. In the case of boost, the solution to this is quite simple - find boost/config/user.hpp and uncomment the line
#define BOOST_ALL_NO_LIB
This will turn off the autolink behaviour for all libraries. Alternatively you can use #define BOOST_REGEX_NO_LIB to change this just for the regex library.
To solve the second problem, you need to find out which library is linking against the release build. Try selecting all projects in the solution and open Properties -> C++ -> Code Generation. You will probably find that the Runtime Library setting will be blank (because the option is different for some of the libraries. Force it to the correct threaded/single-threaded Debug option and rebuild.

How do you pack a visual studio c++ project for release?

I'm wondering how to make a release build that includes all necessary dll files into the .exe so the program can be run on a non-development machine without it having to install the microsoft redistributable on the target machine.
Without doing this you get the error message that the application configuration is not correct and to reinstall.
Choose Project -> Properties
Select Configuration -> General
In the box for how you should link MFC, choose to statically link it.
Choose Linker -> Input. Under Additional Dependencies, add any libraries you need your app to statically link in.
You need to set the run-time library (Under C/C++ -> Code Generation) for ALL projects to static linkage, which correlates to the following default building configurations:
Multithreaded Debug/Release
Singlethreaded Debug/Release
As opposed to the "DLL" versions of those libraries.
Even if you do that, depending on the libraries you're using, you might have to install a Merge Module/framework/etc. It depends on whether static LIB versions of your dependencies are available.
Be aware that Microsoft do not recommend that you static link the runtime into your project, as this prevents it from being serviced by windows update to fix critical security bugs. There are also potential problems if you are passing memory between your main .exe and .dll files as if each of these static links the runtime you can end up with malloc/free mismatch problems.
You can include the DLLs with the executable, without compiling them into the .exe and without running the redist tool - this is what I do and it seems to work fine.
The only fly in the ointment is that you need to include the files twice if you're distributing for a wide range of Windows versions - newer OSs need the files in manifest-defined directories, and older ones want all the files in the program directory.
You'd be looking to static link (as opposed to dynamically link)
I'm not sure how many of the MS redistributables statically link in.
If you are looking to find out which dll's your target machine is missing then use depends.exe which used to come with MSDev, but can also be found here. Testing this on a few target machines should tell you which dll's you need to package with your application.
You should use a static link and add all libraries you need under additional dependencies.