這兩年里,斷斷續續的學習和使用c,平時都是在CodeBlocks里寫代碼,編譯程序,點一下按鈕就行了。對整個編譯過程是一點兒都不了解。相比當年學習java,真的是選擇了兩個不同的路,當年學習java的時候,全是在dos下學習,javac, java,javaw之類的命令用的那些相當的熟,幾年后才開始使用eclipse寫代碼。
今天在找如何用CodeBlocks編譯生成的exe文件添加版本信息時,發現一篇文章,里面介紹到在dos下使用gcc,我就按照上面的提示操作了一下,過程中沒有遇到什么問題。
只是感覺gcc命令用到的參數那是相當的多啊。
1.Console命令行版本:
文件名:main.c
代碼:
程序代碼:
#include <stdio.h>
int main()
{
printf("hello world\n");
return 0;
}
在命令行下面輸入:
gcc -Wall -c -g -o main.o main.c 進行文件編譯。
參數解釋:
-Wall 打開所有的編譯警告
-c 只時行編譯,不進行鏈結。
-g 產生調試信息。
-o main.o 生成編譯輸出文件叫main.o
最后進行文件鏈結:
ld -Lc:\mingw\lib -o main.exe main.o c:\mingw\lib\crt2.o -lmingw32 -lkernel32 -lmsvcrt
參數解釋:
-Lc:\mingw\lib 設置鏈結時庫文件路徑,不設置的話,-lmingw32這些參數會找不到的。
-o main.exe 設置輸出最終的可執行文件main.exe。
c:\mingw\lib\crt2.o 這個是Windows系統的控制台程序初始化模塊。
-lmingw32 -lkernel32 -lmsvcrt 這三個是指示鏈結時鏈上libmingw32.a libkernel32.a libmsvcrt.a相關庫。其中后兩個對應的是kernel32.dll和msvcrt.dll,基本的程序代碼printf函數實際上調用的是puts函數,在msvcrt.dll動態庫中。
當正式編譯的時候,可以使用以下命令行以生成最小的EXE:
gcc -s -O2 main.c -mconsole
參數解釋:
-s 編譯生成匯編代碼
-O2 進行目標代碼優化,O1到O3范圍
-mconsole 指定生成控制台程序。
雖然這里正式編譯的示例沒有上面步子那么多,但你依然需要如示例所示,明白一個程序倒底和哪些庫/模塊進行了鏈結。然后我們使用depends.exe查看程序與運行庫依賴,如下圖所示:
2.Windows版本:
文件名:main.c
代碼:
程序代碼:
#include <windows.h>
typedef HINSTANCE _h;
int WINAPI WinMain(_h hinst, _h hprev, LPSTR cmd, int nShow)
{
return MessageBox(NULL, "hello world!", "OK", MB_OK);
}
命令行輸入:
gcc -c main.c
ld -L"C:\Program Files\CodeBlocks\MinGW\lib" main.o "C:\Program Files\CodeBlocks\MinGW\lib\crt2.o" -lmingw32 -lkernel32 -luser32 -lmsvcrt
這里示例的是如果是帶空格的路徑。
當正式編譯的時候,可以使用以下命令行以生成最小的EXE:注意-mwindows表示的是生成windows應用程序
gcc -s -O2 main.c -mwindows
用depends.exe查看程序與運行庫依賴。用spy++查看窗口消息和信息。
2012-09-15