Ask Your Question
1

Build Application with Static Libraries

asked 2017-05-27 13:50:41 -0600

cagdas001 gravatar image

updated 2017-05-28 04:04:59 -0600

Hi all,

I'm trying to statically link my C++ (CMake) application to run on another computer which does not have OpenCV installed.

So far,

  1. I built OpenCV from source by setting BUILD_SHARED_LIBS to OFF, so I can see library files under lib directory. (with .a extension)

  2. I edited the environment variable for the new build of OpenCV, my IDE does see include directories and files, so this step also seems ok.

  3. Added "-static" parameter to target_link_libraries command in CMake:

target_link_libraries(HoGPeopleDetector ${OpenCV_LIBS} "-static")

Then rebuilt the application, EXE size increased to 1.6 MB from 200 KB. So I guess linking process was successful.

The application works well when I run it within my IDE. However, when I try to run it from the EXE file, it still expects DLL files. (libopencv_core310.dll and maybe more)

IDE: CLion 2017.1.2 OpenCV: 3.1

Program Code:

#include <iostream>
#include <opencv2/objdetect.hpp>
#include <opencv2/highgui.hpp>
#include <opencv2/video.hpp>

using namespace cv;
using namespace std;

static void detectAndDraw(const HOGDescriptor &hog, Mat &img)
{
vector<Rect> found, found_filtered;

hog.detectMultiScale(img, found, 0, Size(8,8), Size(32,32), 1.05, 2);

for(size_t i = 0; i < found.size(); i++ )
{
    Rect r = found[i];

    size_t j;

    for ( j = 0; j < found.size(); j++ )
        if ( j != i && (r & found[j]) == r )
            break;

    if ( j == found.size() )
        found_filtered.push_back(r);
}

for (size_t i = 0; i < found_filtered.size(); i++)
{
    Rect r = found_filtered[i];

    r.x += cvRound(r.width*0.1);
    r.width = cvRound(r.width*0.8);
    r.y += cvRound(r.height*0.07);
    r.height = cvRound(r.height*0.8);
    rectangle(img, r.tl(), r.br(), cv::Scalar(0,255,0), 3);
}
}

int main(int argc, char** argv)
{

cout << "Cikis icin Q ya da ESC ye basin\n";

HOGDescriptor hog;
hog.setSVMDetector(HOGDescriptor::getDefaultPeopleDetector());
namedWindow("people detector", 1);

string pattern_glob = "";
string video_filename = "C:\\OpenCV\\video.mp4";

VideoCapture vc;
Mat frame;


vc.open(video_filename.c_str());
if (!vc.isOpened())
    throw runtime_error(string("Dosya acilamadi: " + video_filename));


for (;;)
{
    vc >> frame;

    if (frame.empty())
        break;

    detectAndDraw(hog, frame);

    imshow("people detector", frame);
    int c = waitKey( vc.isOpened() ? 10 : 0 ) & 255;
    if ( c == 'q' || c == 'Q' || c == 27)
        break;
}

return 0;
}

CMake:

cmake_minimum_required(VERSION 3.7)
project(HoGPeopleDetector)

set(CMAKE_CXX_STANDARD 11)

find_package(OpenCV REQUIRED)

set(SOURCE_FILES main.cpp)
add_executable(HoGPeopleDetector ${SOURCE_FILES})

target_link_libraries(HoGPeopleDetector ${OpenCV_LIBS} "-static")
edit retag flag offensive close merge delete

Comments

ABout target_link_libraries(HoGPeopleDetector ${OpenCV_LIBS} "-static") in static I don't use specific cmake command for visual studio

and "EXE size increased to 1.6 MB from 200 KB" I think it is 200MB

LBerger gravatar imageLBerger ( 2017-05-28 01:48:51 -0600 )edit

I don't need all libraries, my application is just a simple application. AFAIK, Visual Studio does not use CMake, so it's a little bit different. I edited the post with app code and CMake, you can look again

cagdas001 gravatar imagecagdas001 ( 2017-05-28 04:01:09 -0600 )edit

"Visual Studio does not use CMake," wrong

LBerger gravatar imageLBerger ( 2017-05-28 04:25:57 -0600 )edit

${OpenCV_LIBS} might still point to your old dynamic libs ? (when in doubt, remove them, maybe)

berak gravatar imageberak ( 2017-05-28 04:27:28 -0600 )edit

There is a Linker option for Static linking in Visual Studio, so you don't need to make any change on CMake. My IDE is using MinGW and CMake, I need to solve this with MinGW or CMake parameters

cagdas001 gravatar imagecagdas001 ( 2017-05-28 04:29:25 -0600 )edit

@berak I have changed the environment variable, %OpenCV_DIR% is pointing to correct directory. How can I check OpenCV_LIBS ?

cagdas001 gravatar imagecagdas001 ( 2017-05-28 04:32:49 -0600 )edit

message( ${OpenCV_LIBS} ) in the cmakelists.txt

berak gravatar imageberak ( 2017-05-28 04:43:10 -0600 )edit

@berak I reset the CMake cache and reloaded the project after adding the new message command, after a long waiting, IDE has indexed the files and libraries again. EXE size increased to 9.5MB now. Tried it on my virtual machine which does not have OpenCV installed, EXE is working but I'm having another problem. Even though I put the video.mp4 file to correct directory (C:\OpenCV\video.mp4), EXE can't find the file

cagdas001 gravatar imagecagdas001 ( 2017-05-28 05:11:59 -0600 )edit

" EXE size increased to 9.5MB now. " -- that's what i get with mingw, too.

" EXE can't find the file" -- even if you succeeded linking statically, there'S always an exception ;)

this time, it's opencv_ffmpeg320XXX.dll, you will need that either on t, he path or next to your app.

(this dll is still linked dynamically, to obercome a license problem, long story, youcan't avoid it)

berak gravatar imageberak ( 2017-05-28 05:19:45 -0600 )edit

Ok solved, related to the codec. Put the opencv_ffmpeg310.dll with the same directory with your EXE on the new machine. I'm writing the solution as the answer.

cagdas001 gravatar imagecagdas001 ( 2017-05-28 05:19:57 -0600 )edit

1 answer

Sort by ยป oldest newest most voted
1

answered 2017-05-28 05:40:39 -0600

cagdas001 gravatar image

updated 2017-05-28 05:41:02 -0600

Problem solved after a few steps. Thank you all

  1. step, to statically link your application

First, read the steps that I wrote in my question post. They're actually completely correct, just reset the CMake cache and reload the project in case of you're facing any issue. I had already done that before but the problem had not solved. The trick is, try it out again and again.

After rebuilding the application with statically linked libraries, if you're working with a video file like me, you'll probably face a new issue. Your application can't open the video file on another computer.

  1. step, to solve this

In your OpenCV build directory, there is a file named as opencv_ffmpegXXX.dll (310 in my case), put it in the same directory with your EXE.

edit flag offensive delete link more

Question Tools

1 follower

Stats

Asked: 2017-05-27 13:50:41 -0600

Seen: 18,698 times

Last updated: May 28 '17