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.
Related
I have been successfully testing an image processing library (https://github.com/libvips/libvips) in a C++ project in VS2017. I am new to C/C++ and I have been following the documentation here which describes the C way of using the library. There are features I would like to try in the C++ API, but the C++ API needs to be built with the same compiler as my project. According to the author:
It's slightly awkward to set up under Windows. The problem is that C++
does not have a ABI, so you must use exactly the same C++ compiler for
your whole project. This means the libvips C++ win binary (built with
g++) won't work with MSVC C++.
You need to copy the libvips C++ API source code into your own project
and build it with your own code. It's just a few files and pretty
simple to incorporate:
https://github.com/libvips/libvips/tree/master/cplusplus
I have made several attempts to build the minimal set of files but I have not had any success.
My steps so far:
Create a C++ console app in VS2017, set to Debug and x64
Extract the 'vips-dev-8.10' folder from vips-dev-w64-all-8.10.6.zip to where the project file is (this contains all the built .dll files, .lib files, .h files etc.)
Extract 'cplusplus' folder from 'libvips-master.zip' to where the project file is (this has all the project source files including the cplusplus folder which is the part I have to build per the above explanation)
Add the following folders to Project > Properties > C/C++->General > Additional Include Directories
C:\Projects\ConsoleApplicationVIPS3\ConsoleApplicationVIPS3\cplusplus\include\vips
C:\Projects\ConsoleApplicationVIPS3\ConsoleApplicationVIPS3\vips-dev-8.10\include
C:\Projects\ConsoleApplicationVIPS\ConsoleApplicationVIPS\vips-dev-8.10\lib\glib-2.0\include
C:\Projects\ConsoleApplicationVIPS\ConsoleApplicationVIPS\vips-dev-8.10\include\glib-2.0
Add the 5 .cpp files from the cplusplus folder into the project Source Files folder and Add them in the project tree.
Build the project.
As a result I get the following errors:
I haven't written any code yet. I thought I should just be able to point to the .h include files and compile the required C++ files. It's not clear to me what else I might need to add, but it definitely seems like I don't understand the correct procedure to build the project. I watched some videos on C++ compilation like this one but I cant see where I went wrong.
Any thoughts would be much appreciated.
EDITS 3-Jun-21
I have made some changes. I have instead extracted the exact version of the library according to the suggestion by #Frank, and I also discovered the usefulness of the compiler output window, thanks #Alan Birtles.
I am still getting errors, but I am not clear why. The first error is:
E0020 identifier "VImage" is undefined
Which is odd because I have added the folders to Project > Properties > C/C++->General > Additional Include Directories, and one of them is ..\cplusplus\include\vips which contains VImage8.h
And the Output window shows
Any further advice would be appreciated!
For learning purposes, i wanted to create a static library, a "package" of the lib files used in opencv to then link it against my app "opencvuser". Doing so, i get tremendous amounts of erros. (LNK2005 and LNK2019)
My Setup:
Project: staticLib
I've created a static library application without precompiled headers.
Under librarian i've put D:\OpenCV248\build\x64\vc10\staticlib as an additional library
directory. And I've specified all available .lib files as additional
dependencies. (opencv_core248d.lib, opencv_imgproc248d.lib, opencv_highgui248d.lib, ...) Source
Project: opencvuser
I've added C:\OpenCV240\build\include as an additional include directory
Then i've listed "staticLib" under "Properties -> References"
What i expect: Now i should get the same functionallity, as i would add the opencv lib files instead of my built staticLib.lib is my expectation correct?
What i've checked so far:
All Projects are x64
Runtime-Library is set in both Projects to "Multi-threaded Debug"
Anyone knows if the Runtime-Library setting on the static libraries are set to "Multi-threaded Debug"?
You are getting those linker errors because the OpenCV libs you are trying to use were statically linked against the CRT. In your project, you are dynamically linking to CRT and these things won't mix. I would recommend that you don't try to create a "package" of all the OpenCV libs and instead just link to the specific libs you need where you need them.
But I am also going to show you how to solve your problem:
You need to recompile OpenCV without statically linking to the CRT.
You can check out the OpenCV documentation for instructions on how to compile OpenCV using CMake and Visual Studio 2010.
When you run CMake, after you pressed the "Configure" button, look for an option called "BUILD_WITH_STATIC_CRT" and disable it. Then you can press "Generate", open the solution with VS2010 and compile OpenCV.
In your VS2010 project, use the following settings:
In the "opencvuser" project configuration, under Librarian, additional library directories you need to add the path to where the .lib files that you built are located. For me, it's in "c:\opencv248\mybuild\lib\Debug\".
Under Additional Dependencies, you need to include all the OpenCV lib files (opencv_core248d.lib, etc). I also needed to include Comctl32.lib and zlibd.lib because if I didn't I would get some linker errors.
Here are the dependencies I put in:
opencv_calib3d248d.lib
opencv_contrib248d.lib
opencv_core248d.lib
opencv_features2d248d.lib
opencv_flann248d.lib
opencv_gpu248d.lib
opencv_haartraining_engined.lib
opencv_highgui248d.lib
opencv_imgproc248d.lib
opencv_legacy248d.lib
opencv_ml248d.lib
opencv_nonfree248d.lib
opencv_objdetect248d.lib
opencv_ocl248d.lib
opencv_photo248d.lib
opencv_stitching248d.lib
opencv_superres248d.lib
opencv_ts248d.lib
opencv_video248d.lib
opencv_videostab248d.lib
Comctl32.lib
zlibd.lib
Also, in the "opencvuser" project you need to add an empty .cpp file. If you don't add this file, the solution will be empty and Visual Studio won't compile it. I just added a file called "dummy.cpp" to the project. That file is completely empty. Don't put a "main()" function in it because it will collide with the main function in the other project and you will get an error.
In the "staticlib" project, under Linker->General, Additional library directories, you need to include the path to the opencvuser.lib file. For me, it's "..\debug". Also, under Linker->Input, Additional Dependencies, you need to add the "opencvuser.lib" file.
Set project dependencies
You also need to make sure that the projects are built in the right order (first opencvuser, then staticlib). To do this, right-click on the solution and choose Properties. In that window, under Common Properties->Project dependencies, make sure that "opencvuser" does not have a dependency on "staticlib", but "staticlib" must have a dependency on "opencvuser".
That's it, now your project should work. Here are the contents of the two files, and the project running.
I am having issues compiling a basic openGL program on VS 2012. I get a build error upon compiltation giving me:
1>LINK : fatal error LNK1104: cannot open file 'glew32.lib'
I followed the instructions given to me by the documentation for GLEW.
In your OpenGL project open Project -> Properties -> Configuration Properties -> Linker -> Input -> Additional Dependencies -> add glew32.lib.
Also you must include #include in your sources; For that add path to your glew folder: Project -> Properties -> Configuration Properies -> General -> VC++ Directories -> Include Directories and Library Directories;
C/C++ Tab -> General -> Additional Include Directories - Add lib folder there
I have also added the glew32.dll onto my Debug folder within my project folder along with the executable. So far I keep getting this error.
If you need any more further clarification of the steps I have done please don't hesitate to ask
In all honesty, there is no real benefit to using the DLL version of glew (short of reduced executable size, but this hardly matters on modern Windows PCs).
It is not like you can simply drop a new version of the DLL into your application and use extensions that you never used before. Likewise, bug fixes are so infrequent/unnecessary with a library that basically just parses the extension spec. files that using the DLL as a means of fixing extension loading bugs in shipped software is also not practical. Statically linking to glew (this means glew32s.lib) makes much more sense in the long run.
The static linking library is also more portable on Windows, it will work with MSVC and MinGW (whereas the DLL library only works with MSVC). Link against glew32s and put that in whatever directory you decided to use for additional library dependencies.
Here is a sample solution configuration for a project I wrote that uses glew. I have established a convention for this particular software where compile-time dependencies are stored under platform/<Subsystem>. Thus, I have glew32s.lib (32-bit) and glew64s.lib (64-bit) in ./Epsilon/platform/OpenGL/glew{32|64}s.lib
Steps to Use Classes form another project (Add header and solver linker errors)
To be able to add the header from another project, first go to "Properties > c++ > General > Additional Include Directories" and add the directory that contains the header. Now you will be able to add the header of the class from the other project, but running the project will still cause Linker Errors.
Add __declspec(dllexport) before the class you are using for the other project. This can be added in the header file of that class. This should be added right before the function or variable or class name. Now you will get a lib file. (if placed in wrong place, you can get this warning: https://msdn.microsoft.com/en-us/library/eehkcz60.aspx)
"Properties > Linker > Additional Library Directories". Specify the location of the lib file that is generated.
"Properties > Linker > Input > Additional Dependencies”: Add the name of the lib file.
This sounds like the library has been specified as a dependency, but the linker/additional search path(s) has not been set to include the directory where the library is located.
This may help.
It happened to me under this situation, I clean the solution and build it again, then many errors like LNK1104 occur.
After trying to restart IIS, I build solution successfully without LNK1104 errors. I do not know why, but restarting IIS takes much more time than normal, so I guess something is used by other IIS worker process.
Just give a shot to see if this magic happens on you.
This question is old and marked solved, but I had a similar problem symptoms with a completely different solution. So just in case anyone else stumbles in here:
It appeared that because I had 2 projects under one solution (a dll and an exe), the building order was mixed (from the output window):
1> Rebuilding project1..
2> Rebuilding project1..
1> file1.cpp
2> file1.cpp
and so on. By the message you copied, it appears you too have more than one project under one solution. One project was looking for the *.lib file that the other build hadn't created yet.
Solution:
Right click on "main" project -> Build Dependencies -> Project Dependencies.. -> Mark which project the main one depends on.
I have been using libcurl in a C++ project.
I have added the libcurl Include and Library directory's to the VC++ Directories and added the .lib file to the Linkers Input Additional Dependencies.
Everything works fine but when I check in my code (TFS) and somebody gets it on another machine they cannot build etc due to not having libcurl installed on their machine or installed in different paths etc.
How do I add all the necessary files to my C++ Solution so that anyone getting the project from source control can build and link without error.
Thanks
The solution I went with was too add the library file to a folder within my solution, then add
$(SolutionDir)libs\curllib.lib
To the Additional Dependencies within Linker->Input
You can not add the library to the solution. you should distribute the library along the source code. Place it in a subdirectory of the project so that it goes along the whole project source. Then configure the path in Additional Library Dependencies. That way the people should be able to link appropriately when building from source.
I have had C++ experience but not MSVC.
What I am trying to do is incorporate a .dll from an open source project into my project. The code is available and I have built it. I have the .dll as well as the .lib which as I understand it is required for C++ projects.
Now unfortunately there is no simple "Add Reference", drop my .dll into an include directory and add that to my solution. I have edited the project property pages, the C/C++ Additional Include Directories option as well as adding the .lib as an additional linker dependency. I have created an include directory for the dll and lib inside my solution tree.
My problem is when I try to include the header files from the documentation, VS output spits out error messages. Now I realize that I am using the dll/lib combo and that the .h files are not present in my solution so how do I add the proper includes? I am using QT toolkit also which is working but how I add the other header / dll from the open source library eludes me.
Can someone please point me in the right direction.
You need to do a couple of things to use the library:
Make sure that you have both the *.lib and the *.dll from the library you want to use. If you don't have the *.lib, skip #2
Put a reference to the *.lib in the project. Right click the project name in the Solution Explorer and then select Configuration Properties->Linker->Input and put the name of the lib in the Additional Dependencies property.
You have to make sure that VS can find the lib you just added so you have to go to the Tools menu and select Options... Then under Projects and Solutions select VC++ Directories,edit Library Directory option. From within here you can set the directory that contains your new lib by selecting the 'Library Files' in the 'Show Directories For:' drop down box. Just add the path to your lib file in the list of directories. If you dont have a lib you can omit this, but while your here you will also need to set the directory which contains your header files as well under the 'Include Files'. Do it the same way you added the lib.
After doing this you should be good to go and can use your library. If you dont have a lib file you can still use the dll by importing it yourself. During your applications startup you can explicitly load the dll by calling LoadLibrary (see: http://msdn.microsoft.com/en-us/library/ms684175(VS.85).aspx for more info)
Cheers!
EDIT
Remember to use #include < Foo.h > as opposed to #include "foo.h". The former searches the include path. The latter uses the local project files.
The additional include directories are relative to the project dir. This is normally the dir where your project file, *.vcproj, is located. I guess that in your case you have to add just "include" to your include and library directories.
If you want to be sure what your project dir is, you can check the value of the $(ProjectDir) macro. To do that go to "C/C++ -> Additional Include Directories", press the "..." button and in the pop-up dialog press "Macros>>".
You mention adding the additional include directory (C/C++|General) and additional lib dependency (Linker|Input), but have you also added the additional library directory (Linker|General)?
Including a sample error message might also help people answer the question since it's not even clear if the error is during compilation or linking.