win10+opencv3.2+eclipse

        打算在64位windows10系统下安装opencv3.2,由于opencv官网下载的是源码(看文件目录,倒是有一个跟source在同一级的build文件夹,应该是编译好的,不过据说不太好用,不方便调试之类的),所以需要自己编译一下。编译器方面选择windows下的gcc编译器MinGW-w64(mingw只支持32位,mingw-w64是后来发展出来的另一个产品,选择posix,seh版的),cmake是用于生成编译所需要的Makefile等文件的,IDE方面选择了熟悉一点eclipse c/c++ 版(即cdt插件)。


        上述opencv、MinGw-w64、CMake和eclipse全部下载安装完毕后即进入编译opencv的步骤(途中碰到各种问题ORZ)。
        首先打开cmake-gui.exe,source code选择opencv安装目录下的source目录,where to build自己指定一个目录,generator开始选择的是Eclipse CDT4 MinGW Makefiles,configure和generate完成之后,import进Eclipseas as Makefile Project,然后build的时候报错,内容是"Resource is not produced by this arg!!!",大概是因为我下的Eclipse不是CDT4的?CDT4好像是几年前的版本了,然而Cmake里面没有更新的可以选择了。所以只好放弃用Eclipse直接build,老老实实用MinGW编译然后再导入Eclipse(注意Cmake一旦选完generator之后不可以更换,要更换需要重新指定where to build)。 
        使用MinGW编译途中在编译到modules/world/CMakeFiles/opencv_world.dir/__/videoio/src/cap_dshow.cpp这个文件的时候会出错,显示 error: 'sprintf_instead_use_StringCbPrintfA_or_StringCchPrintfA' was not declared in this scope。根据stackoverflow上的一个回答(http://answers.opencv.org/question/62580/not-able-to-build-opencv3-rc1-with-debug-build-type) ,在cap_dshow.cpp中加上#define STRSAFE_NO_DEPRECATE即可。应该还是编译器版本的问题导致sprintf识别不了。
        如果在CMake配置里勾选了WITH_IPP的话编译过程中还会报cannot find -lRunTmChk的错,这个根据stackoverflow上的一个回答(http://answers.opencv.org/question/67508/compile-failed-cannot-find-lruntmchk/),如果勾选了ipp就会执行一个runtime check,而这个runtime check的lib是微软visual studio里的lib。
        排除了ipp的错误之后继续,结果进行到60%多的时候又出错,提示编译opencv/sourcesmodulescore/perf/opencl/perf_arithm.cpp的时候出错,错误原因是too many sections,file too big,google到的原因是因为build过程中生成的.obj文件是COFF(Common Object File Format)格式的,而COFF文件的header里有两位是表示number of sections的,不能超过32766,而这里汇编生成的obj的section超过了这个值,所以直接报错提示file too big。如果用msvc编译的话会提示你使用/bigobj参数来解决.obj文件的限制,然而这次用的是MinGW...一种workaround是把perf_arithm.cpp拆分以缩小单个.obj文件,似乎assimp这个项目就是这么干过(https://github.com/assimp/assimp/commit/304556ab168486829d05746c02f5f3bfa31e2788#diff-663e9ee46a1a0eda8178422a576884b3),然而害怕之后别的文件再出这个问题,还是想彻底解决一下。一番折腾之后发现解决方法是修改opencv的sources文件夹里的CMakeLists.txt,其中加上
if( MINGW )
  set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj")
endif()
(https://github.com/include-what-you-use/include-what-you-use/commit/901083ac17ce446122623fa6a9a65f71b2d7825f)或者在之前build的文件夹下面的CMakeVars.txt中在CMAKE_CXX_FLAGS=那一行等号后面添上 -Wa,-mbig-obj,再重新build。
折腾了好久之后总算build好了,也不知道之后使用时还会不会再出状况╮(╯▽╰)╭


PS:
1.Windows平台上的东西还真是很难绕开vs啊,整个安装编译过程中出现的种种问题多多少少都和没有用msvc而是用了MinGW脱不了关系...
2.CUDA目前在windows下只支持vc编译器,不支持MinGW,所以在CMake配置里没有选BUILD_CUDA_STUBS,否则会报错。
3.整个安装过程中最好不要使用代理连接网络,MinGW-w64的在线安装以及CMake过程中需要下载的时候都会因为连接不了网络而报错。




2017年3月3日更新:还真出状况了...在项目的include和library里配好opencv的头文件和库文件后,跑例程的时候编译没问题,执行就是没反应,eclipse连个error code都没有(好坑)...自己在命令行运行才发现是找不到dll文件,把库文件拷到exe所在的目录下就可以执行了。好奇怪,明明在项目里指定好库文件的位置了呀!很久之前配过一次opencv2.4+eclipse cdt,印象中opencv的dll是不需要拷到project里的嘛,只要配置好include和lib就行了。
以为是eclipse出了问题,于是想先自己想办法通过命令行指定执行的时候去哪找库文件,结果搜了一大圈之后发现并不可以...根据这个回答(http://stackoverflow.com/questions/10606304/load-a-dll-from-another-directory-at-program-start),windows有两种方式加载dll,一种是run-time的时候根据代码里的LoadLibrary函数加载,一种是load-time的时候在包括:exe所在目录、当前工作目录、系统path目录等目录下加载。
原来IDE里配置的include跟lib只是编译的时候用的,执行的时候并没有用...找了下之前配的机器印证了一下,果然之前那次配的时候是把编译好的bin加进系统path里的,时间太久忘记了(在各种opencv安装教程中都会提到,真是最低级的错误...)。把编译好的opencv目录下的bin目录添加进path,问题终于解决了。


3月3日夜更新:好像windows还是可以通过配置指定去哪加载dll的,通过manifest的方式,但是这个好像主要是为了解决加载同一个库的不同版本的,不清楚能否用来指定游离在load-time check范围之外的dll。





你可能感兴趣的:(win10+opencv3.2+eclipse)