简体   繁体   中英

OpenCV 2.4.1 static linking with Qt

I have compile OpenCV 2.4.1 statically without error using MinGW and CMake. I checked With_QT

I just unchecked BUILD_SHARED_LIBS and proceed with mingw32-make and mingw32-make install .

It was built without error and eventually I have bunch of .a file in the lib folder of opencv.

But after setting LIBS and INCLUDEPATH parameters of .pro file and running a simple application in Qt I have got errors.

I also add the following line to .pro file:

CONFIG += -static -static-libgcc

I provided last line error:

F:\OpenCV2.4.1\opencv-static\install\lib\libopencv_highgui241.a(grfmt_jpeg2000.cpp.obj):grfmt_jpeg2000.cpp:(.text$_ZN2cv13Jpeg2KDecoder10readHeaderEv+0x4f):
undefined reference to `jas_image_decode'  collect2: ld returned 1
exit status  mingw32-make[1]: ***

[release\test.exe] Error 1 
mingw32-make: *** [release] Error 2  The process "C:/ming44/bin/mingw32-make.exe" exited with code %2. Error while building project test (target: Desktop) When executing build step 'Make'

Update

I figured out that the error is just when I call highgui.hpp methods. like the following error when I use cv::imshow() :

F:\OpenCV2.4.1\opencv-static2\install\lib\libopencv_highgui241.a(window_w32.cpp.obj):window_w32.cpp:(.text$_ZL17icvCreateTrackbarPKcS0_PiiPFviEPFviPvES4_+0x5e1): undefined reference to `CreateToolbarEx@52'  collect2: ld returned 1
exit status  mingw32-make[1]: *** [release\test.exe] Error 1 
mingw32-make: *** [release] Error 2

Can anybody help me solve this problem.

Thanks

There were many questions as we proceeded through the fix process, so I'll try to summarize the answers to all of them here.

Unresolved Symbols


undefined reference to `jas_image_decode'

The jas_image_decode symbol is defined in libjasper (which is a 3rd party dependency of OpenCV). To resolve it, link against libjasper.a .

undefined reference to `CreateToolbarEx@52'

The CreateToolbarEx symbol is part of Windows API, and is therefore defined in system libraries (which are always supplied with a toolchain, MinGW in your case). You can always find against which library you should link to resolve such symbols by looking in MSDN (scroll down and see Library and DLL cells). In this case, you can see Comctl32.lib , however MSDN of course posts names of libraries in the format that Microsoft Visual C toolchain defines them. Since you are using MinGW toolchain, you'd have to convert (mentally) this name into the Unix naming convention of libraries, and in this case that would be libcomctl32.a .

undefined reference to `AVIStreamRelease@4'

Similarly to the previous case we find it here , and infer that we have to link against libvfw32.a .

NOTE: The paths to such system libraries (containing Windows API) are always searched automatically by the toolchain. Therefore, you shouldn't supply -L option during compilation/linkage, but only the library itself, ie -lcomctl32 .

undefined reference to `cv::dft'

Well, that's again some component from OpenCV ( cv namespace obviously suggests that). A bit of searching reveals that it is defined in the Core component . Accordingly, to resolve that symbol, link against libopencv_core.a .

The Approach


How do I find out which library to link against to resolve the missing symbol?

There is no rule of thumb or any direct recipe here, but rather a number of tricks and educated guesses which primarily come from experience. Here are a few examples:

  1. For instance, in case of CreateToolbarEx , it was quite easy for me to guess that it belongs to Windows API as long as I recognize the Windows API naming convention of the function name. Consequently, what I do next is type CreateToolbarEx into Google, jump to the corresponding page on MSDN, scroll down, see what the library name is, convert (mentally) to the Unix naming convention of libraries (see above), and voila!

  2. The case of OpenCV is more tricky. OpenCV is a 3rd party library and the question whether it'll be painful to find out the library where certain symbol is defined solely depends on the quality of the documentation provided. Although, I can see that the OpenCV documentation is pretty good, it is still missing these important hints for every symbol, and that's a pity. However, we (developers) have to be able to cope with problems like that regardless of how crappy the documentation of a 3rd party library is, and get the job done.

    That's why it is always a good idea to use file content searching utility such as grep (popular on Unix OS family, but available for Windows too in MSYS distribution). This way, for example in case of cv::dft , you could run grep -r "void.*dft(" . in the root of OpenCV source tree, and track down where that symbol is defined in no time. After that you'd have to infer to which component the file containing cv::dft belongs, but that should be straightforward, just look around and see in which directory the file resides.

Conclusion


I swear that I've never used OpenCV in my life, but as you can see I was still able to locate all these missing symbols for you. As a result, we can conclude that the proposed techniques of searching for unresolved symbols are sort of reliable.

Finally, nothing of this is specific to OpenCV or Qt. You're dealing with basic programmer craftsmanship skills here. If you want to be productive software developer capable of solving such day-to-day routines rapidly, then grep is just one of many essential utilities which should undoubtedly be the part of your tooling arsenal.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM