天天看點

C++可執行檔案的釋出

      在用VS2005或VS2008的VC++開發産品時,經常遇到的一個問題就是最終編譯出的可執行檔案Exe、Dll、Ocx之類會需MSVCR90.dll、MSVCR80.dll等C庫函數運作時Dll的支援,在一些較老的系統,如XP中,經常不具備這些新版本的運作庫,導緻産品釋出推廣成為一個嚴重的問題。方法就是修改一下編譯選項,将/MD選項改為/MT選項,最終的可執行檔案就不會包含對那些VC運作時DLL的引用了,可以很友善的釋出和部署。

/MD

 使應用程式使用運作時庫的多線程并特定于 DLL 的版本。定義 _MT 和 _DLL,并使編譯器将庫名 MSVCRT.lib 放入 .obj 檔案中。

用此選項編譯的應用程式靜态連結到 MSVCRT.lib。該庫提供允許連結器解析外部引用的代碼層。實際工作代碼包含在 MSVCR90.DLL, 中,該庫必須在運作時對于與 MSVCRT.lib 連結的應用程式可用。

當 /MD 與 _STATIC_CPPLIB 預處理器定義 (/D_STATIC_CPPLIB) 一起使用時,您的應用程式将與靜态多線程标準 C++ 庫 (libcpmt.lib) 而非動态版本 (msvcprt.lib) 連結,但仍通過 msvcrt.lib 動态連結到主 CRT。

請注意,不支援 _STATIC_CPPLIB 預處理器定義和 /clr 或 /clr:pure 編譯器選項的組合。有關 /clr 選項的限制的更多資訊,請參見 /clr 限制。

/MDd

 定義 _DEBUG、_MT 和 _DLL,并使應用程式使用運作時庫的調試多線程并特定于 DLL 的版本。它還使編譯器将庫名 MSVCRTD.lib 放入 .obj 檔案中。

/MT

 使應用程式使用運作時庫的多線程靜态版本。定義 _MT 并使編譯器将庫名 LIBCMT.lib 放入 .obj 檔案中,以便連結器使用 LIBCMT.lib 解析外部符号。

/MTd

 定義 _DEBUG 和 _MT。此選項還使編譯器将庫名 LIBCMTD.lib 放入 .obj 檔案中,以便連結器使用 LIBCMTD.lib 解析外部符号。

/LD

 建立 DLL。

将 /DLL 選項傳遞到連結器。連結器查找 DllMain 函數,但并不需要該函數。如果沒有編寫 DllMain 函數,連結器将插入傳回 TRUE 的 DllMain 函數。

連結 DLL 啟動代碼。

如果指令行上未指定導出 (.exp) 檔案,則建立導入庫 (.lib);将導入庫連結到調用您的 DLL 的應用程式。

将 /Fe(命名 EXE 檔案) 解釋為命名 DLL 而不是 .exe 檔案;預設程式名成為基名稱.dll 而不是基名稱.exe。

除非顯式指定 /MD,否則将暗指 /MT。

/LDd

 建立調試 DLL。定義 _MT 和 _DEBUG。

這個開關就是控制這個C運作時庫的引用方式的。

當然到這裡先别忙着去修改你的項目屬性中關于這個開關的選項,因為當你的項目也是一個LIB時,如果使用了/MT或/MTd選項時,最終的靜态LIB中就會出現LIBCMT.lib中的大量符号,導緻在别的項目引用你的這個靜态LIB時出現重複定義符号而無法連結的錯誤,怎麼解決呢?其實繼續看MSDN中的幫助就可以得到答案:

傳遞給連結器的給定調用的所有子產品都必須使用相同的運作時庫編譯器選項(/MD、/MT、/LD)進行編譯。

呵呵,原來如此,所有的子產品保持一緻就完了,但是靜态的LIB貌似還是無法引用,問題依舊怎麼辦呢?

那就是在引用了你自己的使用/MT或/MTd選項編譯生成的靜态LIB的項目中,不但指定對應的/MT或/MTd選項,而且需要忽略LIBCMT.lib庫即可。