Visual Studio 2010 - Create Convenience Static Library OpenCv - c++

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.

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.

Adding my DLL into a Visual Studio project in C++

I am working on a project that involves making a dynamic link library, so I want to test it in a console app in Visual Studio.
The DLL is also made in Visual Studio, it doesn't have much, just a few functions in it. I'm not sure if I'm just supposed to include the librarys header in the include directories panel in Properties, or do something else
A lot of people say I'm supposed to add its corresponding .lib file in the Library or Reference directory, but I'm not sure that VS generates a .lib file alongside the DLL. I'm using VS 2015.
I don't have VS in front of me this very moment, but these should be the general steps to set it up:
Properties->Linker->Input: your.lib
Properties->Linker->Additional Library Directories: ../your/bin
Properties->General->Compiler->Additional Include Directories: ../your/include
To build your app, the DLL's API headers must be in the include for the compile-time, it's LIB files in the bin for the link-time. Once you have your app EXE, all you need is the DLL to be in the same folder as your EXE when it executes.
You might also want to add the dll project and the app project into a common solution in VS and add (right click) Project Dependency from the app to the dll. This ensures correct order of building, assuming you are going to build the dll at all.
You can also do what I did.
You can create a Libs directory inside of your Solution directory.
You can then place your .DLL files inside of the Libs directory or some sub-directory inside of Libs
In my case, I added the entire SFML-2.3.2 directory in there, which included the source-code, .lib files, and .dll files.
I did link up what I could in the project properties, but I used Visual Studio's macros to fill in the path name to the Solution directory. Just in case I wanted to put this in version control and work on it from multiple machines.
Then I opened up the Project's Property Page.
Within the property page, I went to Build Events -> Post-Build Event -> Command Line
Within the Command Line, you can add a copy command that will copy any needed files into the same directory as the executable that will need them.
In my case I used: copy "$(SolutionDir)Libs\SFML-2.3.2\bin\*" "$(TargetDir)"
I could have written multiple commands to copy just the individual files that I needed, but I had spent a good three hours trying to get SFML to work without actually installing it.

SFML library can't find .dll

I implemented the SFML library nightly build to my Visual Studio 2013, because the original one is not compatibile with this VS version. I done everything what is needed (added directory to include folder in both Debug and Release, added directory to .dll files), but it can't find the files in program. What else should be done to make this library work? Or should i consider changing Visual Studio to 2010?
You haven't given really to much information so I am just really guessing as to what the problem is.
added directory to .dll files
But that sounds like your problem right there. You don't add the directory that the .dll files are in to your project. The only directories you need to add to the project are the include directory and the library directory.
But anyways I am assuming you are using dynamic linking since otherwise you wouldn't be dealing with .dlls. Now different IDE's require that you place the .dlls in different spots but since you are dealing with VS2013 you need to copy whatever .dlls that you are using into the same folder where your program's compiled executable is (The .exe file).
Another option is to link statically instead of dynamically which I generally prefer to do on small projects but it is really up to the developer which he prefers.
When you link statically you don't need to include any .dlls. What you will need to do is recompile SFML's sources and make sure to build the library so it produces the static library files (They should be named something like sfml-graphics-s-d.lib for debug and sfml-graphics-s-d.lib for release).
Add that library directory which contains the static library files to your project and then link to them .lib files in VS's input window (Remember that -d is for the debug build).
Next you will need to add SFML_STATIC to your preprocessor options on both the release and debug build.
After that you are good to go and don't need to include the .dll files with your project. And again whether you choose to link dynamically or statically is really up to you and the project you are working on but for small projects I would suggest linking statically.

compiled *.lib file visual studio

I have several library project. And I have a solution which including these library project and an application project.
My question is, in linker, should I link the *.lib file from the debug folder of those individual projects or from the debug folder of this solution? If I click rebuild, those library project will be compiled to *.lib and new *.lib file will be generated both in their own solution/Debug folder and the current Debug folder.
My problem is that If I set Liker->General->Additional Library Directories to their individual debug folder and Input->Additional Dependencies to the *.lib files, visual studio will give some random linker error 1104 cant open *.lib file, But it is now the same lib file every time, sometimes is Library1 sometimes is Library2.
If I keep the directories and set the dependencies to all those *.obj files. works just fine.
If I delete the directores and set the dependencies to *.lib files in the current solution debug file by "U:\Source\Applications\CURRENTSOLUTION\Debug\Library1.lib" it works just fine.
So, which is the correct way to way my library?
sometimes is Library1 sometimes is Library2
You probably have a build order problem. It is starting to build your EXE project before the libraries are built. The fix for the existing way you have it is to right-click your EXE project and select "Project Dependencies". Tick the library projects.
But the superior solution is to right-click the EXE project, Properties, Common Properties, Framework and References. Click the Add New Reference button and tick the library projects. That not only takes care of the build order, it also automatically tells the linker to link the .libs. Which now also works in the Release build, your existing solution probably didn't do that yet.

How to add lib files and headers to a C++ Project

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.