OpenCV c++ application deployment with external libraries - c++

I've tried searching A LOT for this with no luck (possibly because I'm not using the right technical terms). My issue is mainly to do with linking static libs, compiling and deploying. Before I get into details, my executables compile fine on my system; the main issue is how to deploy these as a working solution to others.
I've written a basic c++ image processing exe that uses OpenCV static libraries (I link these in VC++ using the Project>Properties>Linker> add additional dependencies, as standard). I compile by pointing to the right include files by setting the VC++ Options... basically, it all compiles fine. I now want to be able to deploy this on another PC. I understand I'll need the release version of the exe + static libs... is there anything else?
Some of the libs rely on using libjpeg and libpng; I don't think these are included as standard. Also, I've set the linker path to the static libs to be relative (e.g. resources/libs) so it's not system dependent so it knows where to find the libs. The basic OpenCV data strucs are working fine (e.g. CvPoint), but when I try to load an image using CvLoadImage, the application crashes. If I use standard ifstream fopen instead, I can open the file with no problems (but can't seem to get it into the IplImage OpenCV image strut - does anyone know how to do these? Probably to do with IplImage->imageData.).
Any help very much appreciated. Thanks!

Static libraries do not have to (and should not) be distributed with the application. Static libraries are built into the exe file by the linker.
The reason why OpenCV crashes is that it cannot find libpng/libjpeg dlls. OpenCV doesn't link them as static dependencies but uses LoadLibrary/dlopen APIs at runtime instead. If these calls fail, there's probably no nice recovery and the application crashes. Your problems should be fixed if you include the libpng/libjpeg libraries.
Also beware - some .lib files aren't truly static libraries but are just a thin layer that allows the linker to find the appropriate functions in a DLL and generate the dynamic linking code so that the programmer doesn't have to do that by hand. You will usually see that from the .lib file size that is pretty small and that your application cries that it cannot find a DLL entry point at the startup of the exe..

Related

Distribution of C++ application with dependencies in Visual Studio

I'm a junior programmer. I have developed a Visual Studio C++ project with a fair amount of dependencies: Boost, a fingerprint recognition library and Windows Biometrics Frameworks. As for today I know the Windows Biometric Framework can be downloaded from the standard Windows Update and I am not concerned about that, to my knowledge, the application is ready to search and link WBF dependencies on the computer by itself.
My concern is: which is the easiest (not most efficient, I need speed here) way to pack the executable file with all the resources and dependencies this .exe needs (Boost and the fingerprint recognition SDK) so that I can minimize distribution troubles, i.e this dll is missing, please reinstall the application, and things like that, without having to compile everything in the client's computer?
I've been able to see a couple ways here: copy the dlls listed in the project config, change to static linking... but I don't know if that is the simplest way. I have little to no trust in my abilities for this and those methods seem quite manual, wondering if there might be an automatic way for doing these things?
I'm not familiar with the fingerprint library or WBF, but most of Boost resides in headers so its compiled in when you compile your application. Some, like the threading library and system specific calls(e.g. getting CPU core count) are libraries that are statically linked to.
What format of the fingerprint library is provided? Dynamically, there would be at least a .dll with a corresponding import .lib file. Your application links statically to the importer after compiling, and binds to the library during run time. Or the library can be included in one large, single .lib that's linked to your application after its compiled. If you have both options available and you only want to distribute the binary file, use static linking.
Like in any systems, you will need to include every .dll libraries your app links and every external resources(images, config files, ...) your app uses. I usually make my Windows distributions by using http://www.jrsoftware.org/isinfo.php.
Very easy to use.

When u download additional libraries & add their features to ur c++ program, would u be able to run ur software on another PC (w/o the library)?

Quick question here, okay say that I have downloaded additional libraries and added them to my version of visual studios and have their #include and commands in my project source code.
If I was to take the .cpp file and bring it to my school computer which also has visual studios and doesn't have these additional libraries, it would have a bunch of missing errors and can't compile.
but..
What if I publish my project and I have it in a .exe file and I was to try and run it on another computer that doesn't have these libraries? Would the executable file run okay?
When you
#include <stuff>
stuff is used during compilation time. However, the libraries it may refer to (e.g. the include gives the definition of many functions from an external library), can be
static or
dynamic
static libraries are linked statically when the program is built, and are part of the executable. dynamic libraries like DLL are linked during the execution of the program .exe. Thus they (DLL) may not be present on another computer when you run the same exe on it.
It depends on the libraries you are using, but sometimes a package is available for download and installation on the other computer, so that they become available. Sometimes you have to copy a bunch of DLLs along with your exe to the other computer. For instance, some advice from Microsoft in this regard.

How to include all dll's in exe?

I have a Visual Studio 12 project; source code written in C++; it's an OpenCV project. I want to give my compiled program to someone else, but, on other PC, I getting an error message about missing some dlls. My program using many OpenCV (maybe, not only) dll's. How can I resolve that problem? Maybe in VS 12 available an option to include all dll's in .exe?
It's a pretty similar question without proper answer:
include dlls in visual studio c++ 2008
DLLs themself can not be "statically linked" into an executable; that completely defies their purpose (well, actually you can use some really weird voodoo tricks to actually do it, but this is neither recommendable nor should you try it if you have to ask this question).
The simple solution would be to identify all the DLLs your program requires (just starting the program in the Debugger will generate a log file listing them all) and copy those DLLs into the same directory as the EXE resides in; as it happens the directory with the EXE file in is also the first directory where the system looks for DLLs before advancing to the standard system directories in default configuration. Package it up and distribute it that way.
the more complicated solution would be, to build static opencv libraries from src, then link your program against those, resulting in 1 large binary exe-chunk, that does not use any dlls (apart from ffmpeg, not sure about that one).
to build static libs, you'd need to run cmake with : BUILD_SHARED_LIBS=OFF
but take a deep breath, before doing that. linking your program will be sigificantly more difficult, because now you have to link all the zlib,libpng, whatever dependecies manually ( which before got conveniently linked into your dlls )
again, the most simple solution is to deploy all the opencv dlls with your program.
You can use the Windows Dependency Walker to determine which DLLs your program needs to run.
Actually, this only tells you which DLLs your program needs to launch successfully. If you load DLLs dynamically (via LoadLibrary) then you are on your own.
If you opt for the accepted solution (package the DLLs with the EXE file), and you don't want to go into the trouble of finding which DLLs to use, then you can copy all the OpenCV DLLs. They're not so big (65 MB on OpenCV 2.43). They are located at ...\opencvXXX\build\x64\vc10\bin\
where XXX is the OpenCV version. You can use x64 or x86 depending on your platform (32 or 64-bit). And the version of vc can be different on your system (vc9, vc10, etc...)

How to use FFTW DLL import library .lib as a static .lib in my project?

I've knowledge of C++ and compiling small plug-ins (always based on a similar and laid out workflow). Though currently I need to compile the latest version of FFTW into a static library (or get it from the compiled version which should supposedly be a lot easier) and it's giving me an insanely hard time. Probably because I don't know the ins and outs of compiling. As a note I'm working on Windows with Visual Studio.
Since I really want to know how this should work I'm asking the question here.
Basically I need a static .lib of fftw3f library on Windows that I can include in another Visual Studio project.
The first I did was download the 64 bit dll's of FFTW from the website (hoping I could use this).
http://www.fftw.org/install/windows.html
Then I've done the accompanying step they stated, that is:
Run the following in lib.exe.
lib /def:libfftw3-3.def
lib /def:libfftw3f-3.def
lib /def:libfftw3l-3.def
I've done this as well and got a .lib file that I could use in my project correctly. I've been able to compile my project, yet the output build apparently dynamically linked to the library instead of including it as a static library.
I'm compiling my project to .dll but require the fftw3f library to be statically included in my output.
Using lib.exe /list libfftw3f-3.lib I was able to find out that the lib file was referencing the libfftw3f-3.dll.
According to my google results this would mean the .lib file that I created is a DLL import library instead of static library.
It's hard to figure out how to phrase my question because I'm not sure what the terminology is and what's going on behind the scenes. I guess:
How can I use the libfftw3f-3.lib file created from lib.exe as a static library in my own project. So that it is included in my output .dll instead of dynamically linked?
Based on what I learn from comments/answers I'll be happy to update/edit/rephrase my question to make more sense for most other users as I'm likely way of with the terminology
You cannot expect to convert a DLL into a static library.
In order to create a static library you need to re-compile the library from its source code, with an output target that is a static library. If you cannot obtain the source code, then your goal cannot be achieved.

MSVC - boost::python static linking to .dll (.pyd)

I got a VS10 project. I want to build some C++ code so I can use it in python. I followed the boost tutorial and got it working. However VS keeps to link boost-python-vc100-mt-gd-1_44.lib but it's just a wrapper which calls boost-python-vc100-mt-gd-1_44.dll. That's why I need to copy the .dll with my .dll(.pyd) file. So I want to link boost:python statically to that .dll(.pyd) file. But I just can't find any configuration option in VS or in the compiler and linker manual. The weirdest thing is I've got one older project using boost::filesystem with the very same config but that project links against libboost-filesystem-*.lib which is static lib so it's ok. I've been googling for couple of hours without any success and it drivers me crazy.
Thanks for any help or suggestion.
You probably don't want to do that. Statically linked Boost python has a number of problems and quirks when there are more then one boost python based library imported. "But I only have one" you say. Can you guarantee that your users won't have another? That you might want to use another in the future? Stick with the DLL. Distributing another DLL is really not that big a deal. Just put it side-by-side in the same directory.
What libraries are linked depends on the settings of your project. There are two possibilities: You can build against
statically
dynamically
linked versions of the c-runtime libs. Depending on which option is selected, the boost sends a proper #pragma to the linker. These options need to be set consistently in all projects which constitute your program. So go to "properties -> c++ -> code generation" (or similar, I am just guessing, don't have VS up and running right now) and be sure that the right option is set (consistently). Of course, you must have compiled boost libraries in required format before...