最近發現了一個非常惱人的程式deployment的問題,估計大家有可能也會遇到,特此memo。
問題的出現我覺得主要還是微軟搞的花頭太多, 一個不知所謂的manifest檔案讓本來簡單的程式釋出變得困難重重。 找了找關于manifest的介紹,貌似這個檔案是用來描述程式或者庫的依賴關系, 特别是對程式依賴的版本進行描述, 這樣系統可以通過manifest的内容找到正确的庫版本。 理論上講這個dd确實是不錯, 可以解決版本不相容的問題, 保證程式運作的時候用的是指定版本的庫。 不過實際操作起來麻煩事一籮筐。
筆者對vs/windows程式設計十分之菜,可能了解的有所偏差, 歡迎指正。 大概也是從vs2005以上的版本開始程式編譯時對這個manifest要求更嚴格了? 要麼可以将manifest資訊内嵌到程式裡,要麼就在釋出程式的時候帶上這個manifest檔案才能保證程式找到依賴的外部庫。 Qt相對這種情況也在build system内部做了相應的調整, 目前的狀況是預設把manifest内嵌在binary裡, 包括庫、程式和插件。
按照Qt文檔的說法, 釋出基于vs2005以上版本的Qt程式有兩種方法, 一是把vc的crt目錄Microsoft.VC80.CRT拷貝到程式路徑下與程式一起釋出; 另外一個是在目标機器上安裝vc的redistribution package。 實際上經過筆者的實驗, 第一種方法行不通, 常見的症狀是按照文檔做了程式不能啟動,或者是插件無法載入。 找了個專家咨詢了一下,發現問題就出在内嵌的manifest資訊上。 由于Qt庫内嵌了manifest資訊, 程式運作的時候系統隻會到固定的位置尋找vc的庫,根本就不搜尋本地的路徑。 筆者的試驗結果是即使把vc的庫放在與程式exe相同的目錄下都找不到,真是奇怪哉! vs2005的程式還沒遇到過這樣的情況哦!
專家給出的意見是要麼安裝vc的redistribution package, 這個是肯定能行的。 還有一種方法是在編譯Qt時在pro裡加 CONFIG-=embed_manifest_dll (這一點和文檔上說的似乎是相反的,可見Qt的文檔有謬誤。), 編譯的插件也需要在pro裡加 CONFIG-=embed_manifest_plugin, 包括我們的程式pro裡要加 CONFIG-=embed_manifest_exe, 這樣才圓滿了! 這種做法的原理是程式裡不嵌入庫的版本和路徑資訊, 系統就會按照傳統的方式搜尋比對的庫,也就會搜尋到程式所在的路徑或者是文檔裡提到的Microsoft.VC80.CRT路徑等等。
各位看官誰家有vs2005以上的版本并遇到了類似問題可以試驗一下, 成功與否來冒個泡。 筆者這裡沒有vs2008可測試,不過想想覺得這個方案還是比較靠譜的。
http://www.cnblogs.com/bingcaihuang/archive/2011/03/15/1984836.html