3

我已经使用 MinGW 和 CMake 静态编译了 OpenCV 2.4.1 而没有错误。我检查了With_QT

我只是取消选中BUILD_SHARED_LIBS并继续 mingw32-makeand mingw32-make install

它的构建没有错误,最终我在 opencv 的 lib 文件夹中有一堆.a文件。

但是在设置LIBS and INCLUDEPATH.pro 文件的参数并在 Qt 中运行一个简单的应用程序后,我遇到了错误。

我还将以下行添加到.pro文件中:

CONFIG += -static -static-libgcc

我提供了最后一行错误:

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'

更新

我发现错误只是在我调用highgui.hpp方法时。像我使用时出现以下错误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

谁能帮我解决这个问题。

谢谢

4

1 回答 1

2

在我们进行修复过程时有很多问题,所以我将在这里尝试总结所有问题的答案。

未解析的符号


undefined reference to `jas_image_decode'

jas_image_decode符号在libjasper中定义(这是 OpenCV 的第 3 方依赖项)。要解决它,请链接到libjasper.a.

undefined reference to `CreateToolbarEx@52'

CreateToolbarEx符号是 Windows API 的一部分,因此在系统库中定义(在您的情况下,这些库始终与工具链一起提供,MinGW)。通过查看MSDN(向下滚动并查看DLL单元),您始终可以找到应该链接哪个库来解析此类符号。在这种情况下,您可以看到Comctl32.lib,但是 MSDN 当然会以 Microsoft Visual C 工具链定义的格式发布库名称。由于您使用的是 MinGW 工具链,因此您必须(在心理上)将此名称转换为库的 Unix 命名约定,在本例中为libcomctl32.a.

undefined reference to `AVIStreamRelease@4'

与前面的案例类似,我们在这里找到它,并推断我们必须链接反对libvfw32.a

注意:工具链始终自动搜索此类系统库(包含 Windows API)的路径。因此,您不应-L在编译/链接期间提供选项,而应仅提供库本身,即-lcomctl32.

undefined reference to `cv::dft'

好吧,这又是来自 OpenCV 的一些组件(cv命名空间显然暗示了这一点)。稍微搜索一下,发现它是在Core 组件中定义的。因此,要解析该符号,请链接到libopencv_core.a.

该方法


如何找出链接哪个库来解决丢失的符号?

这里没有经验法则或任何直接的配方,而是一些主要来自经验的技巧和有根据的猜测。这里有一些例子:

  1. 例如,在 的情况下CreateToolbarEx,只要我认识函数名的 Windows API 命名约定,我就很容易猜到它属于 Windows API。因此,我接下来要做的是CreateToolbarEx在 Google 中输入,跳转到 MSDN 上的相应页面,向下滚动,查看库名称是什么,(在心理上)转换为库的 Unix 命名约定(见上文),瞧!

  2. OpenCV 的情况比较棘手。OpenCV 是一个第 3 方库,找出定义某个符号的库是否会很痛苦的问题完全取决于所提供文档的质量。虽然,我可以看到 OpenCV 文档非常好,但它仍然缺少每个符号的这些重要提示,这很遗憾。然而,我们(开发人员)必须能够应对这样的问题,无论第三方库的文档有多么糟糕,并完成工作。

    这就是为什么使用文件内容搜索实用程序总是一个好主意,例如(在 Unix OS 系列中很流行,但在MSYSgrep发行版中也可用于 Windows )。这样,例如在 的情况下 ,您可以在 OpenCV 源代码树的根目录中运行,并立即追踪该符号的定义位置。之后,您必须推断文件包含的组件属于哪个组件,但这应该很简单,只需环顾四周,看看文件所在的目录。cv::dftgrep -r "void.*dft(" .cv::dft

结论


我发誓我这辈子从未使用过 OpenCV,但正如您所见,我仍然能够为您找到所有这些缺失的符号。因此,我们可以得出结论,所提出的搜索未解析符号的技术是可靠的。

最后,这些都不是特定于 OpenCV 或 Qt 的。您在这里处理的是基本的程序员工艺技能。如果您想成为能够快速解决此类日常例程的高效软件开发人员,那么grep它只是众多必不可少的实用程序之一,无疑应该成为您工具库的一部分。

于 2013-04-25T00:18:33.773 回答