http://xinghao.me/2015/07/14/2015-07-14-opencv-static-compile/
静态编译vs.动态编译
程序中需要用到第三方库时,要使得程序在别的电脑上也能正常运行,通常有两种方式:
- 动态编译。即在程序运行时动态加载第三方库,这时候就需要把涉及到的第三方库的dll和exe文件放在同一目录下。优点是exe文件比较精简,而且如果第三方库有更新,替换掉相应dll文件即可,可维护性和升级性强。缺点是exe运行时需要附带很多dll文件,比较麻烦,而且有潜在的由于dll版本不一样带来的兼容性问题。
- 静态编译。即在程序编译生成时,把第三方库的代码嵌入到要生成的exe文件中,这样单个exe文件就能在其他电脑上运行。优点是单个exe文件即可执行,直观简洁。缺点是exe文件较大,而且第三方库更新时需要重新编译。
vs2013静态编译设置
要想在visual studio中静态编译程序,需要有两处地方进行设置。
- 项目->属性->配置属性->C/C++->代码生成->运行库
运行库下面有四个下拉选项,选项及含义见下表:
选项 | 含义 |
---|---|
多线程(/MT) | Release下的静态编译 |
多线程调试(/MTd) | Debug下的静态编译 |
多线程DLL(/MD) | Release下的动态编译 |
多线程调试(/MDd) | Debug下的动态编译 |
以Release模式为例,把运行库选项改成多线程(/MT)即可
- 项目->属性->配置属性->常规->项目默认值->MFC的使用
其默认值为使用标准Windows库,将其改成在静态库中使用MFC即可
OpenCV静态编译
设置静态库目录
接下来是设置OpenCV的静态编译了。现在的OpenCV直接带有静态编译的链接库版本,无需自己重新编译,在%opencv_dir%/build/x86/vc10/staticlib目录下。
项目->属性->配置属性->VC++目录->库目录
把上面的静态库目录添加进去即可。
设置附加依赖项
项目->属性->配置属性->连接器->输入->附加依赖项,进行设置即可。
OpenCV相关依赖项
在OpenCV中staticlib目录中的lib文件和lib目录中的文件命名方式是一样的,把程序中用到的库文件添加进去,比如:
1
| opencv_calib3d2413d.lib
opencv_contrib2413d.lib
opencv_core2413d.lib
opencv_features2d2413d.lib
opencv_flann2413d.lib
opencv_gpu2413d.lib
opencv_highgui2413d.lib
opencv_imgproc2413d.lib
opencv_legacy2413d.lib
opencv_ml2413d.lib
opencv_nonfree2413d.lib
opencv_objdetect2413d.lib
opencv_photo2413d.lib
opencv_stitching2413d.lib
opencv_ts2413d.lib
opencv_video2413d.lib
opencv_videostab2413d.lib
|
从staticlib目录可以看到,除了跟动态库一样的以opencv_开头的库之外,还有以下几个,也需要一并添加进去:
1
| IlmImfd.lib
libjasperd.lib
libjpegd.lib
libpngd.lib
libtiffd.lib
zlibd.lib |
系统相关
设置好OpenCV相关的依赖项之后,如果此时编译,则会出现很多类似于下一句的错误:
1
| 1>opencv_highgui247d.lib(window_w32.obj) : error LNK2019: 无法解析的外部符号 __imp__GetSystemMetrics@4,该符号在函数 _xGetSystemMetrics@4 中被引用
|
这是因为缺少了一些系统所需要的库。
如果注意观察的话,可以发现,在动态编译时,附加依赖项设置页面下方有“继承的值”一项(从父级或项目默认设置继承)。而改成
静态编译之后,这些默认值没有了,所以需要手动添加。
1
| kernel32.lib
user32.lib
gdi32.lib
winspool.lib
comdlg32.lib
advapi32.lib
shell32.lib
ole32.lib
oleaut32.lib
uuid.lib
odbc32.lib
odbccp32.lib
|
设置好上面这些依赖项之后,直接编译还是会出现以下错误:
1
| 1>opencv_highgui2413d.lib(window_w32.obj) : error LNK2019: 无法解析的外部符号 __imp__CreateToolbarEx@52,该符号在函数 "int __cdecl icvCreateTrackbar(char const *,char const *,int *,int,void (__cdecl*)(int),void (__cdecl*)(int,void *),void *)" (?icvCreateTrackbar@@YAHPBD0PAHHP6AXH@ZP6AXHPAX@Z3@Z) 中被引用
|
这时候添加下面这个lib文件即可
1
| comctl32.lib
|
至此,vs2013+OpenCV的静态编译设置就完成了,此时编译生成的程序,就可以放在其他电脑直接运行了,而无需拷贝一堆dll文件。