從零開始,學習windows編程(8)--自己動手,編譯CRT
翻開對應VC中的lib目錄,是可以看到CRT的lib文件的,我電腦上面路徑是“d:Program FilesMicrosoft Visual StudioVC98Lib”,大家可以自己找一下自己的路徑。經過上面的文章,我們對它已經有了一定的了解,使用它當然沒問題了。那作為程序員,是不是還想看看它是怎麼生成的呢?這裡,就是講如何來生成一個CRT庫。
安裝CRT源碼
既然題目是編譯,那就需要源碼。如果你翻開電腦中的路徑,如我電腦中為“d:Program FilesMicrosoft Visual StudioVC98CRT”,發現下面已經有一個SRC目錄,並且裡面有700多個文件和2個子目錄的話,那你就是安裝過CRT的源碼了,可以直接跳過這段,看到下面的“編譯過程”,如果碰巧沒有,那想要繼續,可以參考這裡,來安裝一下CRT的源碼。
首先,你需要一張VC6的安裝盤,或者VC6的安裝文件。不管你是已經安裝過VC,還是新裝VC,安裝過程我就不詳細說了,主要CRT安裝在下面這個畫面中:
中間用紅線框住的就是CRT了。
可以看一下細節,裡面第3項就是CRT的源碼,重點就是將這項勾選上,到時候安裝目錄中就有源碼了,對應的源碼目錄也在截圖中有顯示,為用黃線框住的部分。
當然,為了省事,直接將VC中的組件全部安裝上就可以了。
安裝完之後,就可以進行編譯了,不過安裝盤先不要放到一邊,一會我們還有用。
編譯過程
我們已經知道,CRT庫分為單線程,多線程,動態庫這三種,而這三種又分別有一個debug版本,這樣就一共有6個版本的CRT庫可以進行編譯。微軟分別稱它們為ST model, MT model, DLL model, XST model, XMT model以及XDLL model。我們的目的就是將這些版本都編譯出來。
編譯的准備工作
在編譯之前,還需要做幾件工作。
確保你的nmake是可以工作的。
從VC6安裝文件/CD-ROM相關目錄底下,找到下面3個文件,並拷貝到對應源碼目錄中,對應我這裡目錄為“d:Program FilesMicrosoft Visual StudioVC98CRTSRC”。
MAKEFILE
MAKEFILE.INC
MAKEFILE.SUB
修改MAKEFILE文件。 搜索Winver.h所在的每一行,如果有
$(V6TOOLS)includewinver.h
則刪除該行,一共有6處。(都是DLL編譯時出現的)
當這些工作都做完之後,你就可以開始編譯了,當然,有可能會出現其他問題,比如我就在編譯DLL版本的時候遇到了一點問題,但是微軟提供的需要進行修改的部分就是這麼多了。
下面我們將6個版本分開來編譯,這樣看得更清楚。進入源碼目錄,然後分別輸入下面的命令,並查看輸出
ST
d:Program FilesMicrosoft Visual StudioVC98CRTSRC>nmake st
編譯結果
所有編譯出來的產出都在build目錄底下,編出的一堆obj文件位於st_obj目錄下,這個我們就不去管了。主要是產生的lib文件:
libc.lib
libci.lib
libcp.lib
MT
d:Program FilesMicrosoft Visual StudioVC98CRTSRC>nmake mt
編譯結果
libcmt.lib
libcimt.lib
libcpmt.lib
DLL
d:Program FilesMicrosoft Visual StudioVC98CRTSRC>nmake dll
編譯結果,最後編譯會出現一些warning,但是沒有問題,按照微軟的說法,在編譯CRT的時候出現這些,是正常的。(信息過多,這裡只取部分警告信息)
link -nologo -filealign:4096 @buildinteldll_objlinki.rsp
.sample_i.def : warning LNK4102: export of deleting destructor "public: virtual
void * __thiscall exception::`vector deleting destructor(unsigned int)"; image
may not run correctly
.sample_i.def : warning LNK4102: export of deleting destructor "public: virtual
void * __thiscall filebuf::`vector deleting destructor(unsigned int)"; image m
ay not run correctly
.sample_i.def : warning LNK4102: export of deleting destructor "public: virtual
void * __thiscall fstream::`vector deleting destructor(unsigned int)"; image m
ay not run correctly
結果
LIB文件 DLL文件 MAP文件 RES文件 等價對應文件(LIB)
_sample_.lib _sample_.dll _sample_.map _sample_.res MSVCRT.LIB
sample_i.lib sample_i.dll sample_i.map sample_i.res MSVCIRT.LIB
sample_p.lib sample_p.dll sample_p.map sample_p.res MSVCPRT.LIB
XST
d:Program FilesMicrosoft Visual StudioVC98CRTSRC>nmake xst
編譯結果
LIB文件 PDB文件
libcd.lib libcd.pdb
libcid.lib libcid.pdb
libcpd.lib libcpd.pdb
XMT
d:Program FilesMicrosoft Visual StudioVC98CRTSRC>nmake xmt
編譯結果
LIB文件 PDB文件
libcmtd.lib libcmtd.pdb
libcimtd.lib libcimtd.pdb
libcpmtd.lib libcpmtd.pdb
XDLL
d:Program FilesMicrosoft Visual StudioVC98CRTSRC>nmake xdll
編譯結果
LIB文件 DLL文件 MAP文件 RES文件 PDB文件 等價對應文件(LIB)
_sampld_.lib _sampld_.dll _sampld_.map _sampld_.res _sampld_.pdb MSVCRTD.LIB
sampld_i.lib sampled_i.dll sampled_i.map sampled_i.res sampld_i.pdb MSVCIRTD.LIB
sampld_p.lib sampled_p.dll sampled_p.map sampled_p.res sampld_p.pdb MSVCPRTD.LIB