So I was beating my head against my desk for days trying to figure out why my MFC project kept failing at link phase because it couldn't find mfc40.lib. I checked for #pragma comment, I checked for lib inputs in project settings, i grepped folder after folder, I could find NOTHING.
Just before I was about to lose my mind, I realized that grepWin ignores LIB files for some reason, so I opened up an old lib in my text editor and saw this:
-defaultlib:mfc40.lib -defaultlib:mfcs40.lib -defaultlib:msvcrt.lib -defaultlib:kernel32.lib -defaultlib:user32.lib -defaultlib:gdi32.lib -defaultlib:comdlg32.lib -defaultlib:winspool.lib -defaultlib:advapi32.lib -defaultlib:shell32.lib -defaultlib:comctl32.lib /include:_afxForceEXCLUDE /include:_afxForceUSRDLL /include:__afxForceSTDAFX -defaultlib:LIBC
-defaultlib:OLDNAMES
For some odd reason the above human-readable portion was actually in the LIB file itself, so I can only assume that because I link against this lib directly, it is INDIRECTLY forcing the inclusion of mfc40.lib (and friends).
Is this what is happening? Why is the above inside the LIB file? An explanation of why this happens would be a bonus.
Also the lib in question is from the Exchange SDK. I'm compiling this MFC project in VS2008.
If when you created the project for your library you chose an MFC based library, whichever version of MFC is available gets added as a default library. To remove it, in your project properties go to Linker > Input > Ignore Specific Libraries and enter mfc40.lib.
More info on that property: http://msdn.microsoft.com/en-us/library/3tz4da4a%28v=VS.90%29.aspx
Related
I am trying to use ICU Unicode in my C++ Project.
I have downloaded the libraries from here, and then linked them by:
Adding the lib64 directory to Properties -> Linker -> General -> Additional Library Directories
Adding the names of all the .lib files into the Input tab.
I then #include "ucnv.h", and the build and run.
The program builds fine, but I get this error message saying I need to put the DLL next to the exe.
I do that, and it runs fine. My questions is
How do I statically link ICU to my project?
What I have tried
I have tried downloading the Master from github, and opening the allinone.sln file, and then setting the following:
Release and x64
Changing the output from DLL to Static Lib
Adding U_STATIC_IMPLEMENTATION to all of the project-preprocessors
I then rebuild, and then add each one of the projects release directories to the Additional Library Directories section of my projects properties, and then also adding the names of the libraries to the Input Section.
Now this actually works for UTF-8, however, for another encoding such as Big-5 most of the functions (and basically all essentials) return NULL.
Also, another reason for a static library is because the DLL I downloaded is over 16MB, which is way too big. On ICU docs they even say that they recommend static linking to reduce size (by removing unneeded)
I am trying to use ICU Unicode in my C++ Project.
I have downloaded the libraries from here, and then linked them by:
Adding the lib64 directory to Properties -> Linker -> General -> Additional Library Directories
Adding the names of all the .lib files into the Input tab.
I then #include "ucnv.h", and the build and run.
The program builds fine, but I get this error message saying I need to put the DLL next to the exe.
I do that, and it runs fine. My questions is
How do I statically link ICU to my project?
What I have tried
I have tried downloading the Master from github, and opening the allinone.sln file, and then setting the following:
Release and x64
Changing the output from DLL to Static Lib
Adding U_STATIC_IMPLEMENTATION to all of the project-preprocessors
I then rebuild, and then add each one of the projects release directories to the Additional Library Directories section of my projects properties, and then also adding the names of the libraries to the Input Section.
Now this actually works for UTF-8, however, for another encoding such as Big-5 most of the functions (and basically all essentials) return NULL.
Also, another reason for a static library is because the DLL I downloaded is over 16MB, which is way too big. On ICU docs they even say that they recommend static linking to reduce size (by removing unneeded)
I've been programming in Python for over a year now but am just learning C++ and am unfamiliar with how to go about using external libraries, CMake and github for that matter. I'm trying to use an external library called cpr - https://github.com/whoshuu/cpr. So far I've followed the instructions in the 'Usage' section of that link up to, but not including, the "add_subdirectory(cpr)" bit.
So far I've got the source code for cpr in the Visual Studio project folder of my C++ project. In the project properties I've then added into Include Directories (under VC++ Directories) "$(SolutionDir)site_libs\cpr\include" and I've added the same thing into Additional Include Directories (under C/C++ -> All Options). This means that the following code compiles just fine:
#include <cpr/cpr.h>
int main(int argc, char** argv) {
auto r =
cpr::Get(cpr::Url{"https://api.github.com/repos/whoshuu/cpr/contributors"},
cpr::Authentication{"user", "pass"},
cpr::Parameters{{"anon", "true"}, {"key", "value"}});
r.status_code; // 200
r.header["content-type"]; // application/json; charset=utf-8
r.text; // JSON text string
}
However this code isn't working when it comes to building, due to link errors. I'm pretty sure the thing I'm missing is the actual .lib file for it to find where these functions etc are defined (nothing for cpr is set in the Linker -> Input property). So I'm wondering - how do I create this .lib file / is that even the right thing to do / what is this "add_subdirectory(cpr)" and where/how do I run it... basically what do I do to make this whole thing work..?! I've tried compiling cpr with CMake but it throws a load of errors about 'CMakeLists.txt' not present in certain folders.
Apologies if I've used any incorrect terminology here, only been learning C++ for a couple of days now. Any help massively appreciated!
If the library does not come as a binary distribution (that is with the .lib already built) you are going to need to build it as a separate project from the code you want to use the library, that step will build the .lib file. If a .sln is included with the distribution use that otherwise you may well have to create your own (or add it as a project to an existing solution).
Once you have a .lib add the directory under the VC++ directories of the project settings and add the actual .lib file name under Linker->Input on the Additional Dependencies line.
To build the library if the distribution does not include the needed VS files you will need to create a project at minimum (it can be part of the solution for your program), right click on the solution node in solution explorer and select Add->New Project, from there select Visual C++->Windows Desktop and either Dynamic Link Library or Static Library as you desire.
Go to the Project menu and select Project Dependencies, change your program to depend on the new project, this will set build order so your program project builds after the library.
You may need to disable the use of pre-compiled headers, right click on the new project node select Properties, go to C/C++->precompiled headers and change Precompiled Headers->Precompiled Header to Not using precompiled headers.
Next add the header and source files to the project and attempt building.
If this succeeded you will have a .lib suitable for use in the additional dependencies of your program project as already described.
I know many have asked this question, but following the things suggested hasn't seemed to work for me. So I thought I'd ask for help, as I'm obviously missing something.
I've spent the past couple days writing some code that uses the boost library that allows me to open text files, translate the text into a usable data format, and save the data as a text file when I'm done with it. I built it specifically to be extendable to deal with different datatypes (specifically any object or class I make down the line) so that I could link to it as a library in my project as I do other libraries.
However, even after compiling it into a lib and adding the directory of the lib to the "Additional Include Directories", I get an unresolved external error whenever I try to include one of the header files in the library. I've also tried putting the direct path to it under Additional Dependencies (as well as just the library name with the path to the directory set in Additional Include Directories and Additional Library Directories. I also tried it with only one of those on at a time and it still failed).
Is there something I'm missing? How can I compile this code I'd like to reuse and link to it in new projects without copying the cpp and h files into my solution every time? Would a DLL work better/easier? If so, how would I go about compiling it as a dll and linking to it?
Thanks for reading this wall of text. Any help you could provide would be great.
Ok. While it's not the exact solution I was going for, I managed to figure this out. For anyone running into this problem, there's a wonderful tutorial that explains how to make DLL files and make use of them (at least on windows, don't have any computers using an alternate OS set up yet to test the DLL on). You can find it here.
http://programmingexamples.wikidot.com/blog:1
The gist of the problem is you need to also keep a copy of the .h file handy to include in your project. (what I did is created a directory on my C drive that holds the libraries I'm making, and in that I have a folder for the .lib files and a folder for the .h files.) Either import the .h file directly into your project directory or add it to your project properties (C++ -> General -> Additional Include Directories ). Make sure for that, you're linking to the directory, not the file itself. In the linker, you need to add your .lib file to the Additional Dependencies section (Linker -> Input -> Additional Dependencies). You can put the whole path here, or you can just put the file name, then tell the program where to find the directory it's in (add the path to the directory to Linker -> General -> Additional Library Directories)
Hope this helps anyone else who managed to miss something that everyone else seems to understand instinctually :P
We have a large project using VS2008 and boost 1_42. I'm trying to upgrade to VS2010 and boost 1_44. I installed VS2010 and boost 1_44 and converted the project. Now I am trying to build, and everything compiles, but fails when linking:
LINK : fatal error LNK1104: cannot open file 'libboost_thread-vc90-mt-1_42.lib'
I have changed the include and lib directories to point to the new boost 1_44 files and I have renamed the old boost 1_42 directory.
Why is the linker still looking for a vc90-1_42 file, when it is only using 1_44 headers? Is there a way that I can determine WHY the linker wants this file? The linker obviously thinks it needs the file, but why?
I have cleaned the project and I am re-building to ensure any old build files are erased.
I've run into exactly this problem a couple of times too. It's usually been some old temporary files but like in your case cleaning didn't always do the trick straight away. Does your project include any static libs that might have been built with 1.42?
Something you can try which may or may not be helpful in tracking down your issue:
Rename the old boost directory back to it's original name
Clean the solution
Under C/C++->Command Line->Additional Options add "/showIncludes"
Under Linker->Command Line->Additional Options add "/verbose:lib"
Rebuild all
Then when you build you'll be able to see at which point 1.42 headers are included, etc. in the output window. Somehow doing this helped me in tracking down where the problem was.
Along with changing the lib directory, you need to change the name of the boost library. That's in the Linker | Input section of the project settings.
Your added comment makes it clear that the dependency on the Boost 1.42 library was being created indirectly by another library that hadn't been rebuilt.
For this you basically have two choices: either add that library as a project to your main solution, and make sure it has enough dependency information that it'll be re-built when you upgrade Boost, or use the /Zl compiler switch when you build your library. This tells the compiler you're building a library so you do not want to embed library dependencies like this.
Boost uses
#pragma comment(lib)
command to inform the linker of libraries it needs to link with. It is not an error. If Boost says you need it, it's likely you do.
On How can I find out why the linker wants this file?
There are programs which will go through your app and dlls/libs and report the content of manifests and what the binaries report they depend on. You could then scan the report for the unexpected libraries being included. We used this mainly to find libs including the previous version of the VC runtime.
Have not used the one we had in about 5 years though, now if only I could remember the name of the app!
DependancyWalker (depends.exe) will allow you to see dependancies of dll/exe but not static libs.
You could open each binary as a 'file' in MSVS and look at the manifest content by hand, but I imaging this would be a bit painful. I've not tried this with a static lib.