zoukankan      html  css  js  c++  java
  • OpenCV:Debug和Release模式 && 静态和动态编译

    OpenCV:Debug和Release模式 && 静态和动态编译

    目录
    1.Release和Debug的区别
    2.Opencv在Release和Debug下配置的区别
    3. 直接运行利用debug和release生成的exe
    4. 静态编译和动态编译
    5.  OpenCV && VS静态编译和动态编译
    6. 补充: .dll文件和lib文件
    7. 如何在其他电脑上(无VS、Opencv)上运行exe
    7.1 第一种方法:release方式,动态编译
    7.2 第二种方法:release方式,静态编译
    8.参考链接

    1.Release和Debug的区别
      Release版称为发行版,Debug版称为调试版。
      Debug中可以单步执行、跟踪等功能,但生成的可执行文件比较大,代码运行速度较慢。Release版运行速度较快,可执行文件较小,但在其编译条件下无法执行调试功能。
      Release的exe文件链接的是标准的MFC DLL(Use MFC in a shared or static dll)。这些DLL在安装Windows的时候已经配置,所以这些程序能够在没有安装Visual C++的机器上运行。而Debug版本的exe链接了调试版本的MFC DLL文件,在没有安装Visual C++的机器上不能运行,因为缺相应的DLL,除非选择use static dll when link。

             Debug 和 Release 并没有本质的区别,他们只是VC预定义提供的两组编译选项的集合,编译器只是按照预定的选项行动。如果我们愿意,我们完全可以把Debug和Release的行为完全颠倒过来。当然也可以提供其他的模式,例如自己定义一组编译选项,然后命名为MY_ABC等。习惯上,我们仍然更愿意使用VC已经定义好的名称。
       Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M)。至于是否需要DLL支持,主要看你采用的编译选项。如果是基于ATL的,则Debug和Release版本对DLL的要求差不多。如果采用的编译选项为使用MFC动态库,则需要MFC42D.DLL等库支持,而Release版本需要MFC42.DLL支持。Release不对源代码进行调试,不考虑MFC的诊断宏,使用的是MFC Release库,编译时对应用程序的速度进行优化,而Debug则正好相反,它允许对源代码进行调试,可以定义和使用MFC的 诊断宏,采用MFC Debug库,对速度没有优化。
       既然Debug和Release仅仅是编译选项的不同,那么为什么要区分Debug和Release版本呢?
       Debug和Release,在我看来主要是针对其面向的目标不同的而进行区分的。Debug通常称为调试版本,通过一系列编译选项的配合,编译的结果通常包含调试信息,而且不做任何优化,以为开发人员提供强大的应用程序调试能力。而Release通常称为发布版本,是为用户使用的,一般客户不允许在发布版本上进行调试。所以不保存调试信息,同时,它往往进行了各种优化,以期达到代码最小和速度最优。为用户的使用提供便利。


    2.Opencv在Release和Debug下配置的区别
      上文已经说明Release和Debug的区别,所以Opencv在Debug和Release不同环境下都需要进行对应的配置的。
      另外我们需要注意,Opencv并不是Windows下标准库,所以它的DLL文件在安装Windows的时候并不会随之配置。也就是说Release和Debug环境下,Opencv库都有对应的Lib和DLL文件,我们在对应模式下都需要配置。并且在发行程序exe之后,随之的DLL文件也需要放置在同一文件夹中,否则程序会报错找不到对应的DLL文件。


    3. 直接运行利用debug和release生成的exe
          按照下面链接配置好opencv两种版本以后,建立新的项目,在 项目》属性》C/C++》代码生成中将运行库改为MT,然后利用release调试,release文件夹下生成的exe文件则可以直接双击运行。同理如果想直接双击运行debug文件夹下的exe文件,则将下图中的配置选为debug,然后将运行库选择为MTd即可。可以看到运行库不止这MT和MTd两个选项,这两个选项叫做静态编译。而剩下的连个选项MD和MDd叫做动态编译。

        关于运行库的选项:
        静态编译:debug状态下:MTd    release状态下:MT
        动态编译:debug状态下:MDd    release状态下:MD
     即区别debug或release的标志则是有无小写字母 d ,有则为debug,无则为release那么静态编译和动态编译的又是什么呢?下面介绍。

     

    4. 静态编译和动态编译
           动态编译的生成的可执行文件的exe小,但是运行需要系统环境具有相关的dll和lib文件,就是动态调用系统相关的文件才能运行;静态编译生成的可执行文件exe大,但是运行的时候不依赖于系统环境所依赖的dll和lib等环境问题,在编译的时候已经这些dll相关文件编译进了exe文件,所以exe文件较大。所以需要自己创建的工程需要在别的电脑上运行,考虑到稳定性,同时对执行文件的大小没有要求的话还是尽量选择静态编译。

        静态编译将导出声明和实现都放在lib中。编译后所有代码都嵌入到宿主程序。

        静态编译的优点是编写出来的程序不需要调用DLL和载入函数,直接可以当成程序的一部分来使用。
        静态编译的缺点也是显而易见的,使用静态编译的程序体积会比动态编译大,原因是函数的实现被嵌入为程序代码的一部分。

          动态LIB文件相当于一个C语言中的h文件,是函数导出部分的声明,而不将实现过程嵌入到程序本身中,编译后只是将函数地址存在宿主程序中,运行到调用函数是调用DLL并载入函数来实现函数的具体操作。动态编译的可执行文件需要附带一个的动态链接库,在执行时,需要调用其对应动态链接库中的命令。

           优缺点:所以动态编译的优点一方面是缩小了执行文件本身的体积,另一方面是加快了编译速度,节省了系统资源。缺点一是哪怕是很简单的程序,只用到了链接库中的一两条命令,也需要附带一个相对庞大的链接库;二是如果其他计算机上没有安装对应的运行库,则用动态编译的可执行文件就不能运行。静态编译就是编译器在编译可执行文件的时候,将可执行文件需要调用的对应动态链接库(.so)中的部分提取出来,链接到可执行文件中去,使可执行文件在运行的时候不依赖于动态链接库。所以其优缺点与动态编译的可执行文件正好互补。


    5.  OpenCV && VS静态编译和动态编译
             MinGW编译器目前仅能编译OpenCV2.x.x版本,OpenCV3.x.x并不支持MinGW编译器。最重要的是,OpenCV使用的Intel的IPP库是没有MinGW版本的,最直观的差别就是,使用OpenCV开发的实时图像处理程序在处理速度上,VC版本要比MinGW版本快至少一倍。所以在windos平台上使用OpenCV,最好还用微软自家的编译器。

             OpenCV官方默认使用动态链接库的形式发布,平时写OpenCV程序用于学习和研究就算了,当程序需要发布时,尤其是程序需要拷到没有OpenCV环境的机器上运行时,一堆的动态链接库弄得好烦,而且OpenCV3.1官方发布版本默认不包含vc10(也就是vs2010的编译器)的库,只好重新尝试编译。关于opencv支持那哪个vs的编译器,可以打开自己的opencv包:

    可以看到opencv2.4.13版本支持的编译器有vc11和vc12,分别对应的VS版本为 visual Studio 2012 和  visual Studio 2013.

    vc10, vc11, vc12 分别表示VS2010, VS2012, VS2013的Visual Studio使用的编译器版本,根据自己的VS版本来填写正确的编译器版本号。

    编译前,需要提前下载并安装好Cmake和VS2010,并下载好OpenCV3.1的源代码。  

    想在没有opencv和vs的电脑上运行 VS编译好的exe文件,则需要利用release模式(考虑到其他电脑没有VS)下静态编译(考虑到其他电脑不存在opencv的动态依赖库,依赖性小方便,就是生成的exe大些,可选)或动态编译(将对应需要的dll拷贝到exe的执行目录下,这种虽然文件多,但是易操作,也可选)。选哪种都行具体看自己的项目。

    具体过程可参考:1)OpenCV3.1 VS2010静态编译和动态编译——https://blog.csdn.net/Kena_M/article/details/53978150

    2) [opencv]OpenCV项目的动态编译和静态编译——https://blog.csdn.net/kingcooper/article/details/50765320

     

    6. 补充: .dll文件和lib文件
    1)Dll(Dynamic Link Library
           DLL(Dynamic Link Library)文件:动态链接库文件
           在Windows中,许多应用程序并不是一个完整的可执行文件,它们被分割成一些相对独立的动态链接库,即DLL文件,放置于系统中。当我们执行某一个程序时,相应的DLL文件就会被调用。一个应用程序可使用多个DLL文件,一个DLL文件也可能被不同的应用程序使用,这样的DLL文件被称为共享DLL文件。
    特点:
    (1)使用较少的资源(当多个程序使用同一个函数库时,DLL 可以减少在磁盘和物理内存中加载的代码的重复量)
    (2)推广模块式体系结构
    (3)简化部署和安装(当 DLL 中的函数需要更新或修复时,部署和安装 DLL 不要求重新建立程序与该 DLL 的链接。此外,如果多个程序使用同一个 DLL,那么多个程序都将从该更新或修复中获益。当您使用定期更新或修复的第三方 DLL 时,此问题可能会更频繁地出现)
     
    2)Lib文件
           LIB有两种,一种是静态库,比如C-Runtime库,这种LIB中有函数的实现代码,一般用在静态连编上,它是将LIB中的代码加入目标模块(EXE或者DLL)文件中,所以链接好了之后,LIB文件就没有用了。一种LIB是和DLL配合使用的,里面没有代码,代码在DLL中,这种LIB是用在静态调用DLL上的,所以起的作用也是链接作用,链接完成了,LIB也没用了。至于动态调用DLL的话,根本用不上LIB文件。 目标模块(EXE或者DLL)文件生成之后,就用不着LIB文件了。
     
     
    总结:
    编译模式有静态与动态编译,编译选项有debug和release。
    对于同一种编译模式下,debug生成的exe比release生成的exe要大,原因:Debug版本包括调试信息,所以要比Release版本大很多(可能大数百K至数M)。
    对于同一种编译选项下,静态编译比动态编译生成的exe要大,原因:静态编译将相应的dll也编译进exe中,而动态编译的可执行文件exe小,不过另外附带一个动态链接库。
    即生成的exe大小:静态>动态, debug>release
     
     
    7. 如何在其他电脑上(无VS、Opencv)上运行exe
    7.1 第一种方法:release方式,动态编译:
    我的环境windows10 + Visual Studio 2013 + opencv2.4.13

    步骤:
    1.打开项目配置页->c/c++->代码生成->运行库,设置成多线程调试DLL(/MD)(release版的动态编译程序选择MD,这一步是为了添加程序运行需要的运行库)
    2.利用VS编译生成exe,然后把对应的dll库拷贝到exe的文件夹下面。将此文件夹作为一个整体发送到其他电脑。(具体需要拷贝哪些dll库可以使用visual studio的dependents查看,方法如下)

    使用dependents查看exe所需要的dll库:
        开始->所有程序->Microsoft Visual Studio 2010 ->Visual Studio Tools->VS2013 x86本机工具命令提示
        跳转到exe所在根目录下,输入dumpbin /dependents main.exe。

    我们需要添加三个opencvdll库,除此还需额外添加opencv_ffmpeg247.dll,不然总提示读取视频失败。下面的几个DLL文件在上面步骤一修改运行库时就已经添加了。
     
    7.2 第二种方法:release方式,静态编译:
           首先再解释一次为啥不用debug模式:vs2013编译项目有两个版本:Debug和Release,在Debug模式下生成的exe需要vs2013的一些Debug库文件支持,就是说在没有vs2013的电脑上是无法正常运行的,所以要在Release模式下面编译项目。

    步骤:
    1、把工程调成Release模式。
    2、右键项目->属性打开项目属性页面,首先在配置属性->常规页面,如果是MFC程序,则在“MFC的使用”选择“在静态库中使用MFC”。然后在配置属性->C/C++ ->代码生成页面,“运行库”里面选“多线程(/MT)”。
    3、然后生成重新解决方案,生成了之后会在项目的Release文件夹下面看到一个exe文件和一个pdb文件(注意:这不是用静态库生成的)。
    4、打开opencv2-4-13的安装目录,在“安装路径opencvuildx86vc12in目录下将所有的Release版本(不带字母d的dll)的动态库文件拷贝到Release文件夹里面,跟exe文件放在一起。这样生成的exe程序就可以在其他电脑上面运行了。

     
    8.参考链接

    参看:OpenCV:Debug和Release模式 && 静态和动态编译——https://www.cnblogs.com/king-lps/p/7758050.html
    1)Release和Debug模式的区别以及Opencv在Release和Debug不同模式下的配置——http://blog.csdn.net/FX677588/article/details/72622011
    2)知乎上的关于opencv debug和release版本的永久配置——https://www.zhihu.com/question/24400428
    3)CSDNS上的opencv debug和release版本的永久配置——http://blog.csdn.net/leo2007608/article/details/38963947
    4)关于opencv转换debug和release版本出现的问题。——http://www.cnblogs.com/xujianqing/p/5356559.html
    5)如何生成能在没有安装opencv库及vs2010环境的电脑上运行的exe文件——https://www.cnblogs.com/bestwangjie/p/5632465.html

  • 相关阅读:
    nginx入门与实战
    python开发之virtualenv与virtualenvwrapper讲解
    Linux下的python3,virtualenv,Mysql、nginx、redis安装配置
    Linux系统基础优化及常用命令
    vim与程序员
    Shell基本命令
    Linux之文档与目录结构
    远程连接Linux
    oracle 根据时间戳查询date类型sql
    oracle 锁用户
  • 原文地址:https://www.cnblogs.com/Alliswell-WP/p/OpenCVDebugOrReleaseIssue.html
Copyright © 2011-2022 走看看