靜態編譯是什麼? 不懂請先看這篇wiki定義 http://en.wikipedia.org/wiki/Static_library
再看這篇microsoft的: 逐步解說:建立和使用靜態程式庫: http://msdn.microsoft.com/zh-tw/library/ms235627(v=vs.110).aspx
我們什麼時候會需要靜態編譯? 依照我的經驗可能性有三:
本篇說明 windows環境下,基於OpenCV的程式靜態編譯方法。
再看這篇microsoft的: 逐步解說:建立和使用靜態程式庫: http://msdn.microsoft.com/zh-tw/library/ms235627(v=vs.110).aspx
我們什麼時候會需要靜態編譯? 依照我的經驗可能性有三:
- 在外合作案子,需要使用他人提供的環境,不想給人看到我們程式碼以及背後用到的函式庫,或是不希望對方拿到你的libraries丟給印度人破解後,開心地使用起來。
- 雲端環境開發很好用,可以少做很多設定的東西,一樣也有安全性
- 要還沒簽約前,要提供廠商一支exe檔,做簡單測試用。
本篇說明 windows環境下,基於OpenCV的程式靜態編譯方法。
有兩個方法可以得到靜態的OpenCV資料庫
以上抱歉,懶得截圖,有問題可以直接問。
用靜態編譯就不會有dll檔,因此不用管系統環境參數,在你的專案中如果過往連結OpenCV的方式,把header路徑,與libs linker路徑加上去後,還是會碰到問題,如下:
- 下載新版OpenCV,例如 OpenCV 2.5,安裝完之後就直接有編好。
注意你要使用x86, x64哪個版本? 看不懂就選x86..
再注意你自己程式編譯環境是vc2008, vc2010, vc2012, etc.選取對應的目錄,例如我是vc2012,就選下列的位置
C:\SDK\opencv2.4.5\build\x86\vc11\staticlib
(PS1. build之前是我的安裝目錄,你要換成你的目錄,如果你是vc2008以前的版本,建議你更新啦!! 不要再用vc6了..然後vc2008有bug,其實最好也不要用)
(PS2. 用QT編,就選mingw環境,注意mingw的gcc版本搞不好不一樣,還是會不能用) - 自己編,用CMake編譯,注意 BUILD_SHARED_LIBS 的勾要取消,BUILD_WITH_STATIC_CRT打開,前面那一項當然是為了要編static libs,後面這項是為了後續方便,範例程式等都會自動選成MT,而非MD,都選好後Configure,再選Generate產生專案檔(.sln)在你選的build the binaries目錄下,請去打開後,將debug和release都編譯好吧。然後你自己要開發的專案中,把產生的lib位置連結進去就好。
(PS1. MT, MD選像自己選法: Project->Property->C/C++->Code Generation->Runtime Library,不知道這是什麼請看: http://msdn.microsoft.com/zh-tw/library/2kzt1wy3(v=vs.80).aspx )
(PS2. CMake其他勾不要亂勾,溝下去就確定背後的lib也要是靜態編譯的,例如QT, OpenCL等)
以上抱歉,懶得截圖,有問題可以直接問。
用靜態編譯就不會有dll檔,因此不用管系統環境參數,在你的專案中如果過往連結OpenCV的方式,把header路徑,與libs linker路徑加上去後,還是會碰到問題,如下:
Error 1 error LNK2001: unresolved external symbol __imp__CreateToolbarEx@52 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(window_w32.obj) evIntruderDetector
Error 2 error LNK2001: unresolved external symbol _ICOpen@12 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 3 error LNK2001: unresolved external symbol _ICClose@4 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 4 error LNK2001: unresolved external symbol _ICSendMessage@16 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 5 error LNK2001: unresolved external symbol _ICDecompress G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 6 error LNK2001: unresolved external symbol _AVIFileInit@0 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 7 error LNK2001: unresolved external symbol _AVIFileRelease@4 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 8 error LNK2001: unresolved external symbol _AVIFileOpenA@16 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 9 error LNK2001: unresolved external symbol _AVIFileGetStream@16 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 10 error LNK2001: unresolved external symbol _AVIFileCreateStreamA@12 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 11 error LNK2001: unresolved external symbol _AVIStreamRelease@4 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 12 error LNK2001: unresolved external symbol _AVIStreamInfoA@12 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 13 error LNK2001: unresolved external symbol _AVIStreamSetFormat@16 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 14 error LNK2001: unresolved external symbol _AVIStreamWrite@32 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 15 error LNK2001: unresolved external symbol _AVIStreamGetFrameOpen@8 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 16 error LNK2001: unresolved external symbol _AVIStreamGetFrame@8 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 17 error LNK2001: unresolved external symbol _AVIStreamGetFrameClose@4 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 18 error LNK2001: unresolved external symbol _AVIMakeCompressedStream@16 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 19 error LNK2001: unresolved external symbol _AVISaveOptions@20 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 20 error LNK2001: unresolved external symbol _capCreateCaptureWindowA@32 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 21 error LNK2001: unresolved external symbol _capGetDriverDescriptionA@20 G:\work\evIntruderDetector\evIntruderDetector\opencv_highgui245.lib(cap_vfw.obj) evIntruderDetector
Error 22 error LNK1120: 21 unresolved externals G:\work\evIntruderDetector\New Release\evIntruderDetector.exe evIntruderDetector
明顯看到錯誤都是highgui帶來的,這是因為highgui 背後有帶ffmpeg造成。
解決方法:
將環境加入 vfw32.lib(解cap_vfw.obj) 與 comctl32.lib(這個是解window_w32.obj)
我這兩個檔案位置在:
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\Vfw32.Lib
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\comctl32.lib
v6.0A這個目錄可能會不一樣,例如: v7.0等,自己搜索一下換成正確路徑就好。
重編,搞定。
解決方法:
將環境加入 vfw32.lib(解cap_vfw.obj) 與 comctl32.lib(這個是解window_w32.obj)
我這兩個檔案位置在:
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\Vfw32.Lib
C:\Program Files\Microsoft SDKs\Windows\v6.0A\Lib\comctl32.lib
v6.0A這個目錄可能會不一樣,例如: v7.0等,自己搜索一下換成正確路徑就好。
重編,搞定。