OpenCV:Debug和Release模式 && 靜態和動態編譯


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預定義提供的兩組編譯選項的集合,編譯器只是按照預定的選項行動。如果我們願意,我們完全可以把DebugRelease的行為完全顛倒過來。當然也可以提供其他的模式,例如自己定義一組編譯選項,然后命名為MY_ABC等。習慣上,我們仍然更願意使用VC已經定義好的名稱。
   Debug版本包括調試信息,所以要比Release版本大很多(可能大數百K至數M)。至於是否需要DLL支持,主要看你采用的編譯選項。如果是基於ATL的,則DebugRelease版本對DLL的要求差不多。如果采用的編譯選項為使用MFC動態庫,則需要MFC42D.DLL等庫支持,而Release版本需要MFC42.DLL支持。Release不對源代碼進行調試,不考慮MFC的診斷宏,使用的是MFC Release庫,編譯時對應用程序的速度進行優化,而Debug則正好相反,它允許對源代碼進行調試,可以定義和使用MFC的 診斷宏,采用MFC Debug庫,對速度沒有優化。
         既然DebugRelease僅僅是編譯選項的不同,那么為什么要區分DebugRelease版本呢?
   DebugRelease,在我看來主要是針對其面向的目標不同的而進行區分的。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的執行目錄下,這種雖然文件多,但是易操作,也可選)。選哪種都行具體看自己的項目。

具體過程可參考;OpenCV3.1 VS2010靜態編譯和動態編譯   和   [opencv]OpenCV項目的動態編譯和靜態編譯

 

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的安裝目錄,在“安裝路徑opencv\build\x86\vc12\bin目錄下將所有的Release版本(不帶字母d的dll)的動態庫文件拷貝到Release文件夾里面,跟exe文件放在一起。這樣生成的exe程序就可以在其他電腦上面運行了。

 

參考於:

http://blog.csdn.net/FX677588/article/details/72622011

https://www.zhihu.com/question/24400428    知乎上的關於opencv debug和release版本的永久配置

http://blog.csdn.net/leo2007608/article/details/38963947    CSDNS上的opencv debug和release版本的永久配置

http://www.cnblogs.com/xujianqing/p/5356559.html    關於opencv轉換debug和release版本出現的問題。

如何生成能在沒有安裝opencv庫及vs2010環境的電腦上運行的exe文件

 

關於debug和release的問題,個人覺得還是分別建兩個新項目屬性OpencvDebug和OpencvRelease比較方便。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM