vc 編譯連線選項

林堯彬發表於2020-04-04

大家可能一直在用VC開發軟體,但是對於這個編譯器卻未必很瞭解。原因是多方面的。大多數情況下,我們只停留在“使用”它,而不會想去“瞭解”它。因為它只是一個工具,我們寧可把更多的精力放在C++語言和軟體設計上。我們習慣於這樣一種“模式”:建立一個專案,然後寫程式碼,然後編譯,反反覆覆除錯。但是,所謂:“公欲善其事,必先利其器”。如果我們精於VC開發環境,我們是不是能夠做得更加遊刃有餘呢?

  閒話少說。我們先來看一下VC的處理流程,大致分為兩步:編譯和連線。原始檔通過編譯生成了.obj檔案;所有.obj檔案和.lib檔案通過連線生成.exe檔案或.dll檔案。下面,我們分別討論這兩個步驟的一些細節。

 

一,編譯引數的設定。

主要通過VC的選單項Project->Settings->C/C++頁來完成。我們可以看到這一頁的最下面Project Options中的內容,一般如下:

/nologo /MDd /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_AFXDLL" /D "_M
BCS" /Fp"Debug/WritingDlgTest.pch" /Yu"stdafx.h" /Fo"Debug/" /Fd"Debug/" /FD /GZ /c

  各個引數代表的意義,可以參考Msdn。比如/nologo表示編譯時不在輸出視窗顯示這些設定(我們可以把這個引數去掉來看看效果)等等。一般我們不會直接修改這些設定,而是通過這一頁最上面的Category中的各項來完成。

  1) General:一些總體設定。Warning level用來控制警告資訊,其中Level 1是最嚴重的級別;Warnings as errors將警告資訊當作錯誤處理;Optimizations是程式碼優化,可以在Category的Optimizations項中進行更細的設定;Generate browse info用以生成.sbr檔案,記錄類、變數等符號資訊,可以在Category的Listing Files項中進行更多的設定。Debug info,生成除錯資訊:None,不產生任何除錯資訊(編譯比較快);Line Numbers Only,僅生成全域性的和外部符號的除錯資訊到.OBJ檔案或.EXE檔案,減小目標檔案的尺寸;C 7.0- Compatible,記錄偵錯程式用到的所有符號資訊到.OBJ檔案和.EXE檔案;Program Database,建立.PDB檔案記錄所有除錯資訊;Program Database for "Edit & Continue",建立.PDB檔案記錄所有除錯資訊,並且支援除錯時編輯。

  2) C++ Language:pointer_to_member representation用來設定類定義/引用的先後關係,一般為Best-Case Always表示在引用類之前該類肯定已經定義了;Enable Exception Handling,進行同步的異常處理;Enable Run-Time Type Information迫使編譯器增加程式碼在執行時進行物件型別檢查;Disable Construction Displacements,設定類構造/解構函式呼叫虛擬函式問題。

  3) Code Generation:Processor表示程式碼指令優化,可以為80386、80486、Pentium、Pentium Pro,或者Blend表示混合以上各種優化。Use run-time library用以指定程式執行時使用的執行時庫(單執行緒或多執行緒,Debug版本或Release版本),有一個原則就是,一個程式不要同時使用幾個版本的執行時庫。Single-Threaded,靜態連線LIBC.LIB庫;Debug Single-Threaded,靜態連線LIBCD.LIB庫;Multithreaded,靜態連線LIBCMT.LIB庫;Debug Multithreaded,靜態連線LIBCMTD.LIB庫;Multithreaded DLL,動態連線MSVCRT.DLL庫;Debug Multithreaded DLL,動態連線MSVCRTD.DLL庫。連線了單執行緒庫就不支援多執行緒呼叫,連線了多執行緒庫就要求建立多執行緒的應用程式。

  Calling convention可以用來設定呼叫約定,有三種:__cdecl、__fastcall和__stdcall。各種呼叫約定的主要區別在於,函式呼叫時,函式的引數是從左到右壓入堆疊還是從右到左壓入堆疊;在函式返回時,由函式的呼叫者來清理壓入堆疊的引數還是由函式本身來清理;以及在編譯時對函式名進行的命名修飾(可以通過Listing Files看到各種命名修飾方式)。Struct member alignment用以指定資料結構中的成員變數在記憶體中是按幾位元組對齊的,根據計算機資料匯流排的位數,不同的對齊方式存取資料的速度不一樣。這個引數對資料包網路傳輸等應用尤為重要,不是存取速度問題,而是資料位的精確定義問題,一般在程式中使用#pragma pack來指定。
  4) Customize:Disable Language Extensions,表示不使用微軟為標準C做的語言擴充套件;Eliminate Duplicate Strings,主要用於字串優化(將字串放到緩充池裡以節省空間),使用這個引數,使得

 

 

char *sBuffer = "This is a character buffer";

char *tBuffer = "This is a character buffer";

 

  sBuffer和tBuffer指向的是同一塊記憶體空間;Enable Function-Level Linking ,告訴編譯器將各個函式按打包格式編譯;Enables minimal rebuild,通過儲存關聯資訊到.IDB檔案,使編譯器只對最新類定義改動過的原始檔進行重編譯,提高編譯速度;Enable Incremental Compilation,同樣通過.IDB檔案儲存的資訊,只重編譯最新改動過的函式;Suppress Startup Banner and Information Messages,用以控制引數是否在output視窗輸出。

  5) Listing Files:Generate browse info的功能上面已經提到過。這裡可以進行更多的設定。Exclude Local Variables from Browse Info表示是否將區域性變數的資訊放到.SBR檔案中。Listing file type可以設定生成的列表資訊檔案的內容:Assembly-Only Listing僅生成彙編程式碼檔案(.ASM副檔名);Assembly With Machine Code生成機器程式碼和彙編程式碼檔案(.COD副檔名);Assembly With Source Code生成原始碼和彙編程式碼檔案(.ASM副檔名);Assembly, Machine Code,and Source生成機器碼、原始碼和彙編程式碼檔案(.COD副檔名)。Listing file name為生成的資訊檔案的路徑,一般為Debug或Release目錄下,生成的檔名自動取原始檔的檔名。

  6) Optimizations:程式碼優化設定。可以選擇Maximize Speed生成最快速的程式碼,或Minimize Size生成最小尺寸的程式,或者Customize定製優化。定製的內容包括:

  Assume No Aliasing,不使用別名(提高速度);

  Assume Aliasing Across Function Calls,僅函式內部不使用別名;

  Global Optimizations,全域性優化,比如經常用到的變數使用暫存器儲存,或者迴圈內的計算優化,如

i = -100;

while( i < 0 ){ i += x + y;}

 

  會被優化為

 

i = -100;
t = x + y;
while( i < 0 ){i += t;}
Generate Intrinsic Functions,使用內部函式替換一些函式呼叫(提高速度);
Improve Float Consistency,浮點運算方面的優化;
Favor Small Code,程式(exe或dll)尺寸優化優先於程式碼速度優化;
Favor Fast Code,程式(exe或dll)程式碼速度優化優先於尺寸優化;
Frame-Pointer Omission,不使用幀指標,以提高函式呼叫速度;
Full Optimization,組合了幾種引數,以生成最快的程式程式碼。

       Inline function expansion,行內函數擴充套件的三種優化(使用內聯可以節省函式呼叫的開銷,加快程式速度):Disable不使用內聯;Only __inline,僅函式定義前有inline或__inline標記使用內聯;Any Suitable,除了inline或__inline標記的函式外,編譯器“覺得”應該使用內聯的函式,都使用內聯。

  7) Precompiled Headers:預編譯標頭檔案的設定。使用預編譯可以提高重複編譯的速度。VC一般將一些公共的、不大變動的標頭檔案(比如afxwin.h等)集中放到stdafx.h中,這一部分程式碼就不必每次都重新編譯(除非是Rebuild All)。

 

  8) Preprocessor:預編譯處理。可以定義/解除定義一些常量。Additional include directories,可以指定額外的包含目錄,一般是相對於本專案的目錄,如..\Include。

 

二,連線引數的設定。

主要通過VC的選單項Project->Settings->Link頁來完成。我們可以看到這一頁的最下面Project Options中的內容,一般如下:

/nologo /subsystem:windows /incremental:yes /pdb:"Debug/WritingDlgTest.pdb" /debug /machi
ne:I386 /out:"Debug/WritingDlgTest.exe" /pdbtype:sept

  下面我們分別來看一下Category中的各項設定。

  1) General:一些總體設定。可以設定生成的檔案路徑、檔名;連線的庫檔案;Generate debug info,生成Debug資訊到.PDB檔案(具體格式可以在Category->Debug中設定);Ignore All Default Libraries,放棄所有預設的庫連線;Link Incrementally,通過生成. ILK檔案實現遞增式連線以提高後續連線速度,但一般這種方式下生成的檔案(EXE或DLL)較大;Generate Mapfile,生成.MAP檔案記錄模組相關資訊;Enable Profiling,這個引數通常與Generate Mapfile引數同時使用,而且如果產生Debug資訊的話,不能用.PDB檔案,而且必須用Microsoft Format。

  2) Customize:這裡可以進行使用程式資料庫檔案的設定。Force File Output ,強制產生輸出檔案(EXE或DLL);Print Progress Messages,可以將連線過程中的進度資訊輸出到Output視窗。

  3) Debug:設定是否生成除錯資訊,以及除錯資訊的格式。格式可以有Microsoft Format、COFF Format(Common Object File Format)和Both Formats三種選擇;Separate Types,表示將Debug格式資訊以獨立的.PDB檔案存放,還是直接放在各個原始檔的.PDB檔案中。選中的話,表示採用後者的方式,這種方式除錯啟動比較快。

  4) Input:這裡可以指定要連線的庫檔案,放棄連線的庫檔案。還可以增加額外的庫檔案目錄,一般是相對於本專案的目錄,如..\Lib。Force Symbol References,可以指定連線特定符號定義的庫。

  5) Output:Base Address可以改變程式預設的基地址(EXE檔案預設為0x400000,DLL預設為x10000000),作業系統裝載一個程式時總是試著先從這個基地址開始。Entry-Point Symbol可以指定程式的入口地址,一般為一個函式名(且必須採用__stdcall呼叫約定)。一般Win32的程式,EXE的入口為WinMain,DLL的入口為DllEntryPoint;最好讓聯結器自動設定程式的入口點。預設情況下,通過一個C的執行時庫函式來實現:控制檯程式採用mainCRTStartup (或wmainCRTStartup)去呼叫程式的main (或wmain)函式;Windows程式採用WinMainCRTStartup (或 wWinMainCRTStartup)呼叫程式的WinMain (或 wWinMain,必須採用__stdcall呼叫約定);DLL採用_DllMainCRTStartup呼叫DllMain函式(必須採用__stdcall呼叫約定)。Stack allocations,用以設定程式使用的堆疊大小(請使用十進位制),預設為1兆位元組。Version Information告訴聯結器在EXE或DLL檔案的開始部分放上版本號。

 

  值得注意的是,上面各個引數是大小寫敏感的;在引數後加上“-”表示該引數無效;各個引數值選項
有“*”的表示為該引數的預設值;可以使用頁右上角的“Reset”按鈕來恢復該頁的所有預設設定。

 

三,其它一些引數設定

  1) Project->Settings->General,可以設定連線MFC庫的方式(靜態或動態)。如果是動態連
接,在你的軟體釋出時不要忘了帶上MFC的DLL。

  2) Project->Settings->Debug,可以設定除錯時執行的可執行檔案,以及命令列引數等。

  3) Project->Settings->Custom Build,可以設定編譯/連線成功後自動執行一些操作。比較有
用的是,寫COM時希望VC對編譯通過的COM檔案自動註冊,可以如下設定:

   Description: Register COM

   Commands: regsvr32 /s /c $(TargetPath)

   echo regsvr32 exe.time > $(TargetDir)\$(TargetName).trg

   Outputs: $(TargetDir)\$(TargetName).trg

  4) Tools->Options->Directories,設定系統的Include、Library路徑。

 

一些小竅門

  1) 有時候,你可能在編譯的時候,計算機突然非法關機了(可能某人不小心碰了電源或你的記憶體不穩定等原因)。當你重啟機器後開啟剛才的專案,重新進行編譯,發現VC會崩掉。你或許以為你的VC編譯器壞了,其實不然(你試試編譯其它專案,還是好的!),你只要將專案的.ncb、.opt、.aps、.clw檔案以及Debug、Release目錄下的所有檔案都刪掉,然後重新編譯就行
了。

  2) 如果你想與別人共享你的原始碼專案,但是把整個專案做拷貝又太大。你完全可以刪掉以下檔案:.dsw、.ncb、.opt、.aps、.clw、. plg檔案以及Debug、Release目錄下的所有檔案。

 

  3) 當你的Workspace中包含多個Project的時候,你可能不能直觀地、一眼看出來哪個是當前專案。可以如下設定:Tools->Options->Format,然後在Category中選擇Workspace window,改變其預設的字型(比如設成Fixedsys)就行了。

 

  4) 如何給已有的Project改名字?將該Project關掉。然後以文字格式開啟.dsp檔案,替換原來的Project名字即可。

 

  5) VC6對類成員的智慧提示功能很有用,但有時候會失靈。你可以先關掉專案,將.clw和.ncb刪掉,然後重新開啟專案,點選選單項View->ClassWizard,在彈出的對話方塊中按一下“Add All”按鈕;重新Rebuild All。應該可以解決問題。

 

                                                       VC編譯選項

-優化-  
/O1 最小化空間 minimize space
/Op[-] 改善浮點數一致性 improve floating-pt consistency
/O2 最大化速度 maximize speed
/Os       優選程式碼空間       favor code space
/Oa 假設沒有別名 assume no aliasing
/Ot 優選程式碼速度 favor code speed
/Ob 內聯展開(預設 n=0) inline expansion (default n=0)
/Ow       假設交叉函式別名       assume cross-function aliasing
/Od       禁用優化(預設值)       disable optimizations (default)
/Ox       最大化選項。(/Ogityb2 /Gs) maximum opts. (/Ogityb1 /Gs)
/Og       啟用全域性優化       enable global optimization  
/Oy[-]       啟用框架指標省略       enable frame pointer omission
/Oi       啟用內建函式       enable intrinsic functions


-程式碼生成-  
/G3       為 80386 進行優化       optimize for 80386
/G4       為 80486 進行優化       optimize for 80486
/GR[-]       啟用 C++ RTTI       enable C++ RTTI
/G5       為 Pentium 進行優化       optimize for Pentium
/G6 為 Pentium Pro 進行優化       optimize for Pentium Pro
/GX[-]       啟用 C++ 異常處理(與 /EHsc 相同)       enable C++ EH (same as /EHsc)
/EHs       啟用同步 C++ 異常處理       enable synchronous C++ EH
/GD 為 Windows DLL 進行優化 optimize for Windows DLL
/GB       為混合模型進行優化(預設)       optimize for blended model (default)
/EHa       啟用非同步 C++ 異常處理       enable asynchronous C++ EH
/Gd       __cdecl 呼叫約定       __cdecl calling convention  
/EHc       extern“C”預設為 nothrow       extern "C" defaults to nothrow
/Gr       __fastcall 呼叫約定       __fastcall calling convention
/Gi[-] 啟用增量編譯 enable incremental compilation
/Gz       __stdcall 呼叫約定       __stdcall calling convention  
/Gm[-]       啟用最小重新生成       enable minimal rebuild
/GA       為 Windows 應用程式進行優化 optimize for Windows Application
/Gf       啟用字串池       enable string pooling  
/QIfdiv[-]       啟用 Pentium FDIV 修復       enable Pentium FDIV fix  
/GF       啟用只讀字串池       enable read-only string pooling  
/QI0f[-]       啟用 Pentium 0x0f 修復       enable Pentium 0x0f fix
/Gy       分隔連結器函式       separate functions for linker
/GZ       啟用執行時除錯檢查 enable runtime debug checks
/Gh 啟用鉤子函式呼叫 enable hook function call
/Ge       對所有函式強制堆疊檢查       force stack checking for all funcs
/Gs[num]       禁用堆疊檢查呼叫       disable stack checking calls


-輸出檔案-  
/Fa[file]       命名程式集列表檔案       name assembly listing file
/Fo       命名物件檔案       name object file
/FA[sc]       配置程式集列表       configure assembly listing  
/Fp       命名預編譯標頭檔案       name precompiled header file
/Fd[file]       命名 .PDB 檔案       name .PDB file  
/Fr[file]       命名源瀏覽器檔案       name source browser file
/Fe       命名可執行檔案       name executable file
/FR[file]       命名擴充套件 .SBR 檔案       name extended .SBR file
/Fm[file]       命名對映檔案       name map file


-前處理器-  
/FI       命名強制包含檔案       name forced include file
/C       不吸取註釋       don't strip comments  
/U       移除預定義巨集       remove predefined macro
/D{=|#}       定義巨集       define macro
/u       移除所有預定義巨集       remove all predefined macros
/E       將預處理定向到標準輸出 preprocess to stdout
/I 新增到包含檔案的搜尋路徑       add to include search path
/EP       將預處理定向到標準輸出,不要帶行號       preprocess to stdout, no #line
/X       忽略“標準位置”       ignore "standard places"
/P       預處理到檔案       preprocess to file


-語言-  
/Zi       啟用除錯資訊       enable debugging information
/Zl       忽略 .OBJ 中的預設庫名       omit default library name in .OBJ
/ZI       啟用除錯資訊的“編輯並繼續”功能 enable Edit and Continue debug info
/Zg       生成函式原型       generate function prototypes
/Z7       啟用舊式除錯資訊       enable old-style debug info
/Zs       只進行語法檢查       syntax check only
/Zd       僅要行號除錯資訊       line number debugging info only
/vd{0|1}       禁用/啟用 vtordisp       disable/enable vtordisp
/Zp[n]       在 n 位元組邊界上包裝結構       pack structs on n-byte boundary
/vm       指向成員的指標型別       type of pointers to members
/Za       禁用擴充套件(暗指 /Op)       disable extensions (implies /Op)
/noBool       禁用“bool”關鍵字       disable "bool" keyword
/Ze       啟用擴充套件(預設)       enable extensions (default)


- 雜項 -  
/?, /help       列印此幫助訊息       print this help message
/c       只編譯,不連結       compile only, no link
/W       設定警告等級(預設 n=1)       set warning level (default n=1)
/H       最大化外部名稱長度       max external name length
/J       預設 char 型別是 unsigned       default char type is unsigned
/nologo       取消顯示版權訊息       suppress copyright message
/WX       將警告視為錯誤       treat warnings as errors
/Tc       將檔案編譯為 .c       compile file as .c  
/Yc[file]       建立 .PCH 檔案       create .PCH file
/Tp       將檔案編譯為 .cpp       compile file as .cpp  
/Yd       將除錯資訊放在每個 .OBJ 中       put debug info in every .OBJ
/TC       將所有檔案編譯為 .c       compile all files as .c  
/TP       將所有檔案編譯為 .cpp       compile all files as .cpp  
/Yu[file]       使用 .PCH 檔案       use .PCH file
/V       設定版本字串       set version string
/YX[file]       自動的 .PCH 檔案 automatic .PCH
/w       禁用所有警告       disable all warnings
/Zm       最大記憶體分配(預設為 %)       max memory alloc (% of default)


-連結-  
/MD       與 MSVCRT.LIB 連結       link with MSVCRT.LIB
/MDd       與 MSVCRTD.LIB 除錯庫連結       link with MSVCRTD.LIB debug lib
/ML       與 LIBC.LIB 連結       link with LIBC.LIB
/MLd       與 LIBCD.LIB 除錯庫連結       link with LIBCD.LIB debug lib
/MT       與 LIBCMT.LIB 連結       link with LIBCMT.LIB  
/MTd       與 LIBCMTD.LIB 除錯庫連結       link with LIBCMTD.LIB debug lib
/LD       建立 .DLL       Create .DLL  
/F       設定堆疊大小       set stack size
/LDd       建立 .DLL 除錯庫       Create .DLL debug libary
/link       [連結器選項和庫]       [linker options and libraries]

轉載於:https://www.cnblogs.com/gamesky/archive/2013/01/17/2864640.html

相關文章