[分享] Windows 下架構 C/C++ 簡易 IDE
零、 前言
可能是學校作業,可能是之前我發過提問文,這星期私信來函不少,
內容從命令列編譯程式碼 到 IDE 環境架構都有,
想說這部份蠻多也曾請求協助於版友,發此文做為回饋,
一次全回答完,也留予往後有需求之人做參考。
我會研究此議題,純粹乃習慣開兩個 IDE 出來,一個是 Project 上之實做;
另一個是 Project 寫到一半時,可能需要什麼小隻的副函式,或其它要驗證東西,
開一個 Visual Studio 就吃很大,所以驗證的 IDE 很少在用 Visual Studio ,
甚至嫌 Dev-C++ 還不夠小,最後以 PSPad 進行驗證上之輔助。
由於我使用之 compiler 並不多,僅限於
Visual C++ (CL.exe )
Dev-C++ / MinGW (gcc.exe / g++.exe)
故本文只以此兩套 compiler 做為說明,前文有點煩雜,後文將以 PSPad 輔助,
進行架構小型 IDE。若只對架構小型 IDE 有興趣,而對整體運作沒興趣(或已知),
直接跳到 肆、 使用 PSPad 架構小型 IDE 即可
若對本文有興趣,欲加以實做,建議可下載並安裝 TDM-gcc
http://tdm-gcc.tdragon.net/download
我安裝的是 tdm-gcc-4.5.2 (exe), 應是沒附 IDE 版的。
在說明上盡量以 Dev-C++ 4.9.9.2 之環境為說明條件。
可能有書有教,但我是看 spec try 出來的,有不錯的書歡迎推薦。
壹、 Dev-C++ 從 hello.c 到 hello.exe
假設原始碼為 hello.c,為方便解說,放到 D:\ , 絕對路徑為 D:\hello.c
基本上,只要看到 ???? 器,它「應該」就要是一個執行檔。
這裡只是小提一下,一般從 source code (.c) 一路到產生可執行之執行檔 (.exe),
大致有四個步驟,以下命令,請先按下 開始->執行(或按 WinKey+R),輸入cmd.exe
跳出黑黑像 dos 視窗的命令提示字元後才進行操作,
下述之 綠體字 部份,即為要在該黑黑的 dos 視窗(它就叫命令提示字元)裡輸入之指令。
a. 預處理器 (pre-prossor,或稱前編譯 < hello.c to hello.i> )
將程式碼 (hello.c) 裡,對於 # 及 註解部份 做處理。
如 #define 展開、#include 插入、(#if、 #ifdef、#endif) 做條件編譯處理。
dev-c++ Z:\> C:\Dev-cpp\bin\cpp.exe "D:\hello.c" "D:\hello.i"
※ 結果在 D:\ 生成 hello.i
b. 編譯器 (compiler <hello.i to hello.s> )
將剛剛預處理完之 .i 吃進來,編譯成低階組合語言。asm code 副檔名非一定,
Dev-C++/gcc 為 .c , vs 為 .asm
dev-c++ Z:\> C:\Dev-Cpp\libexec\gcc\mingw32\3.4.2\cc1.exe
"D:\hello.c" -o "D:\hello.s"
※ 結果在 D:\ 生成 hello.s
注意,上面的 cc1.exe ,最後那個是數字 1 (one),非小寫英文 L。
c. 組譯器 (assembler <hello.s to hello.o> )
將 .s 組合語言組譯成目的檔 .o,目的檔副檔名在 dev-c++/ gcc
為 .o , vs 為 .obj
dev-c++ Z:\> C:\Dev-Cpp\bin\as.exe "D:\hello.s" -o "D:\hello.o"
※ 結果在 D:\ 生成 hello.o
d. 連結器 ( linker < hello.o + *.o to hello.exe > )
這是最後一步驟,將剛剛出來的 .o 再連結成 .exe 執行檔出來, 但這個步驟實在是
太讓人覺得麻煩,我也沒弄得很清楚到底要連哪些 .o 出來,實際上是調用
C:\Dev-Cpp\bin\ld.exe ,此處只好調用 gcc.exe
dev-c++ Z:\> C:\Dev-Cpp\bin\gcc.exe D:\hello.o -o D:\hello.exe
※ 結果在 D:\ 生成 hello.exe
事實上真正將 .o 轉到 .exe 的是 ld.exe 連結器 (linker),並非 gcc.exe,
有興趣的話可以詳閱 ld.exe 參數說明,光是一個 hello.exe 要轉過去,
至少要含五、六個 library 裡面,已組譯好的 .o ,這些 .o 目的檔,
大多在 C:\Dev-Cpp\lib 、 C:\Dev-Cpp\lib\gcc\mingw32\3.4.2 裡面
關於 linker 部份,可參考 james732 版大文章 #1DgrW4a5 (C_and_CPP)
這篇寫得很讚。
貮、 談整合性程式
For Dev-C++ / MinGW
如上所見,光是輸出一個 "Hello, World!!" 就這麼麻煩
(1) 先從 hello.c 到 hello.i, pre-processor, cpp.exe
(2) 再從 hello.i 到 hello.s, compiler, cc1.exe
(3) 接著 hello.s 到 hello.o, assembler, as.exe
(4) hello.o + (*.o) 到 hello.exe, linker, ld.exe
這不論是 Dev-C++ 或是 Visual Studio 、 Broland C,即使 Turbo C 也必須這麼做。
但各家發展這些時,都會有大多再開發一隻屬整合這四個程式之另一支程式出來,
如 gcc.exe 便為如此,使用它,甚至可跳過很多步驟,直接從 .c 產生出 .exe 出來
Z:\> C:\Dev-cpp\bin\gcc.exe -o D:\hello.exe D:\hello.c
如果不只一個 .c ,有其它的 .h 等之類的話
Z:\> C:\Dev-cpp\bin\gcc.exe -o D:\hello.exe D:\hello.c D:\h1.h D:\h2.h
D:\h1.c D:\h2.c
這些可容易產生,甚至要叫 asm code 出來也可
Z:\> C:\Dev-cpp\bin\gcc.exe -S D:\hello.c
其它的功能不少,點到為止。
For Visual C++
Visual C++ 算是我見過較為例外的,整個從 .c 到 .exe,除了有一個 Linker.exe 是做
連結動作,其它全部功能都塞到 CL.exe 裡面去。但若要用 CL.exe 之前,在命令提示字
元下必須先呼叫 vsvars32.bat 進行環境變數設定
Z:\> call "%VS100COMNTOOLS%vsvars32.bat" For Visual C++ 2010
Z:\> call "VS90COMNTOOLS%vsvars32.bat" For Visual C++ 2008
接下來才可進行 CL.exe 上之使用
產生 hello.exe, hello.obj
Z:\> CL.exe Fe"D:\hello.exe" D:\hello.c
產生 hello.exe, hello.obj, hello.asm
Z:\> CL.exe Fe"D:\hello.exe" D:\hello.c /FAs
也可進行多個 .c/.h 進行編譯。
參、 MinGW 與 Dev-C++
MinGW 我認為環境架構上一直不是那麼友善,於是如版友之建議,下載了 tdm-gcc-4.5.2
這套下來用 (網址在最一開始地方有附),它和上面說的 Dev-C++ 所使用編譯方式、使用
之 exe、語法,並無顯著差異,唯只有路徑上不一樣,如我手邊安裝完後, gcc.exe 是
位於 C:\MinGW32\bin 底下,故上述所有之 C:\Dev-cpp\bin 全都改成 C:\MinGW32\bin
即可,甚至可以設置 path 之環境變數,這樣下來也不用每次都以絕對位置方式做呼叫。
肆、 使用 PSPad 架構小型 IDE
這方法是有缺點的,要改善的話看 陸、 PSPad 多檔編譯
類似的軟體不只 PSPad,之前還碰過 UltraEdit、NotePad++,
選用 PSPad 之原因在於它免費,同時還類似有 函式導覽、專案管理 等功能,
有興趣的話可再摸摸其他類似之軟體。
PSPad 要下載對版本才好用,確保開始後,設定->語法高亮設定 是看得到的。
若要用 PSPad 去當編輯器,以 Dev-C++ 之 gcc.exe 為 compiler,設定如下
(1) 點擊 設定-> 語法高亮設定
(2) 程式語言選到 C/C++,右半窗格選擇「編譯器」
(3) 「編譯器」輸入 C:\Dev-cpp\bin\gcc.exe
「參數 」設 -o "%Dir%%Name%.exe" "%File%"
「編譯後執行」設 cmd /c "%Dir%%Name%.exe" &pause
下面再勾選
編譯前儲存所有檔案、擷取程式輸出結果。
「編譯器」那裡,若已安裝了 MinGW,建議不要再設 Dev-cpp 裡之 gcc
版本差太多,一個是 3.4.2,一個是 4.5.2
路徑設 C:\MinGW32\bin\gcc.exe
若 MinGW 已有註冊環境變數的話,可直接輸入 gcc.exe 即可,
用不到 Dev-cpp 的話,也可把它移除。
若是慣用 C++ 寫的話,該設的是 g++.exe,非 gcc.exe。
好了之後每次用 PSPad 寫好碼,直接輸入 Ctrl+F9,
編譯器給的所有錯誤與警告訊息,會出現在下面之 Log 視窗,
若無誤時將會執行所生成之檔案。
這方法有缺點,一次只能編譯生成一個檔案出來,下面再說一點點 batch。
伍、 完全不使用 IDE, 只想看 source code 產生之結果
通常我收到「一陀檔案」,說他的程式沒錯,第一個動作是先看執行結果時,
我並不會直接開任何 IDE 出來,這樣要把所有檔案都拉到 IDE 裡面去,
我用的是 batch 方式產生。 在桌面上建立一個 Toilet.bat,內容如下
@echo off
setlocal enabledelayedexpansion
SET "instr="c:\Dev-Cpp\bin\gcc.exe" -o "%~dp1dev_c_multi.exe""
FOR %%I IN (%*) DO (
SET instr=!instr! "%%~I"
)
SET instr=!instr! -O2
!instr!
"%~dp1dev_c_multi.exe"
endlocal
echo. &pause
上面的 "c:\Dev-Cpp\bin\gcc.exe" 這一樣可以改,
我預設輸出檔名是 dev_c_multi.exe,使用方式不用在命令提示字元底下一一輸入,
而且 直接把 "所有" 用到的 .c .h 全都拖到 Toilet 裡面去。
就像是要刪除檔案,把檔案拖到資源回收桶裡面一樣,
只是這次是把所有檔案拖到廁所(Toilet.bat)裡面去。
編譯失敗會顯示錯誤訊息,編譯成功時,會在檔案的地方產生出 dev_c_multi.exe,
並會執行它。
visual c++ 我也寫了一份,
@echo off
call "%VS100COMNTOOLS%vsvars32.bat"
%~d1
cd %~d1
cd "%~dp1"
setlocal enabledelayedexpansion
SET "instr=CL.exe /Fe"%~dp1v10_noOpt.exe" "
FOR %%I IN (%*) DO (
CL.exe /Fo"%%~dpnI.obj" %%I
SET instr=!instr! "%%~dpnI.obj"
)
!instr!
endlocal
echo. &echo compile finish, execute now...
pause & cls
"%~dp1v10_noOpt.exe"
del "%~dp1*.obj"
pause
上述以 visual c++ 2010 為例,要換成是 2008 的話改
"%VS90COMNTOOLS%vsvars32.bat" ,預設檔名為 vc10_noOpt.exe。
使用方式一樣是拖進來即可。
上面這些用 batch 完成,是「無腦」方式, compile 過程中勢必會有些警告出來,
但若單純在寫 console 程式,應還算勘用。
陸、 PSPad 多檔編譯
新增 PSPad 專用之 batch file
基於 第肆點 所產生之缺點,加上第五點,其實我們已可在
PSPad 下連結起所有相關之 .h / .c / .cpp,這裡再新增一個 DevC.bat,
內容如下
@echo off
SET "MyPath=%~dpf1"
SET "MyPath="%MyPath%\*.h" "%MyPath%\*.c" /b"
SET "Output="%~dpf1Main.exe""
SET /P UserInput=Input the execute filename(Default:%Output%):
IF NOT "%UserInput%"=="" SET "Output="%~dpf1%UserInput%.exe""
SET "Instr=C:\Dev-Cpp\bin\gcc.exe -o %Output% "
SETLOCAL EnableDelayedExpansion
FOR /F "tokens=* delims=" %%A in ('dir !MyPath! /b') DO (
:: echo %%A
SET Instr=!Instr! "%~dpf1%%A"
)
%Instr%
ENDLOCAL
echo. &echo compile finished, it will execute now..
pause & cls
%Output%
pause
完成之後,存在 C:\ 底下,絕對路徑為 C:\DevC.bat
與上述一樣,若有安裝 MinGW ,建議Instr=C:\Dev-Cpp\bin\gcc.exe
改為 Instr=C:\MinGW32\bin\gcc.exe ,C++ 的話除了將 gcc 改 g++ 外
"%MyPath%\*.c" 改成 "%MyPath%\*.cpp"。
PSPad 下之設定
在 PSPad 那裡之設定如下所述
(1) 點擊 「設定」、「語法高亮設定」
(2) 點擊 「C/C++」、「編譯器」
(3) 「編譯器」設 「C:\DevC.bat」
「參數 」設 「"%Dir%"」, 其他清空,而 Log 之 CheckBox
只勾 「編譯前儲存檔案」,
其它的「擷取程式的輸出結果」、「隱藏輸出視窗」千千萬萬不要勾。
實際上這改善方案仍有限,它是指定當下 Active File 之路徑,
去找該資料夾底下之所有 .c/.cpp 與 .h,同時把它們全都抓進來編譯,
意思是如果找到該資料夾底下,檔案內容有兩個 main ,那就失敗了。
其實最好之方式,應是去分析該 PSPad 之 project file - .ppr,
但問題已愈來愈複雜,此處僅以概述,不再深入進去。
實際操作流程
實際上,在 PSPad 裡按下 Ctrl+F9 時,程式會提示,請輸入一輸出檔名,
這裡預設是 (資料夾路徑\Main.exe),如果直接按 Enter 的話,就以預設輸出;
如果輸入 a 的話,輸出會放在 (資料夾路徑\a.exe),自動加上 .exe,
若不想每次自己手動輸入,想直接生成的話,在上面之 DevC.bat 裡面,
SET /P UserInput=Input the execute filename(Default:%Output%):
IF NOT "%UserInput%"=="" SET "Output="%~dpf1%UserInput%.exe""
這兩行直接刪除它。完成之後,若順利 compile 出執行檔,程式也會自動執行。
柒、 其他未盡與注意事項
本文其實有點用硬爆法把要的結果爆出來, (好的方法其實不想再花時間去橋),
過程中用到不算淺的 batch command,若要再自己做客制化之環境,有幾個建議
可再供參考
1. 弄熟 make.exe / cmake.exe / nmake.exe(for vs)
2. 弄熟 batch command
3. 弄熟 gcc.exe / g++.exe / CL.exe
4. 弄熟 pspad/ultraedit 之環境變數
用 UltraEdit , PSPad , Notepad++ 這類型軟體當輔助 IDE,只能開發一些簡單之
程式,若程式本身架構複雜,並不適合用這類型小軟體協助,缺點為在 linker ,
compiler 那裡浪費不少不必要時間,且其並無 IDE 開發環境下之 debugger 來得簡便。
若認為此文敘述有所不妥,或敘述上有所誤失、觀念不正確,
或有其他建議者,請不吝指出、補充、指教,小弟當感激不盡。
--
YouLoveMe() ? LetItBe() : LetMeFree();
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 180.177.78.41
推
09/20 19:02, , 1F
09/20 19:02, 1F
推
09/20 19:07, , 2F
09/20 19:07, 2F
→
09/20 19:10, , 3F
09/20 19:10, 3F
notepad++ 我還沒摸過,寫得不錯之編輯軟體應都有支援這部份,
純粹只因摸過 UltraEdit / PSPad, 兩者相較下我選用 PSPad (免費)
推
09/20 20:07, , 4F
09/20 20:07, 4F
→
09/20 20:22, , 5F
09/20 20:22, 5F
→
09/20 20:23, , 6F
09/20 20:23, 6F
→
09/20 21:54, , 7F
09/20 21:54, 7F
→
09/20 22:00, , 8F
09/20 22:00, 8F
compiler , assembler , 這個真的是我弄反了,已更正,謝謝指出。 :)
推
09/20 22:04, , 9F
09/20 22:04, 9F
→
09/20 22:18, , 10F
09/20 22:18, 10F
我也以為那是 TMD-gcc,查證後是 TDM-gcc,感謝 lsc36 指正。
→
09/20 22:35, , 11F
09/20 22:35, 11F
→
09/20 22:36, , 12F
09/20 22:36, 12F
→
09/20 22:41, , 13F
09/20 22:41, 13F
→
09/20 22:42, , 14F
09/20 22:42, 14F
→
09/20 22:42, , 15F
09/20 22:42, 15F
→
09/20 22:43, , 16F
09/20 22:43, 16F
推
09/20 22:45, , 17F
09/20 22:45, 17F
→
09/20 22:52, , 18F
09/20 22:52, 18F
→
09/20 23:08, , 19F
09/20 23:08, 19F
→
09/20 23:26, , 20F
09/20 23:26, 20F
推
09/20 23:36, , 21F
09/20 23:36, 21F
推
09/21 00:19, , 22F
09/21 00:19, 22F
→
09/21 00:38, , 23F
09/21 00:38, 23F
推
09/21 01:35, , 24F
09/21 01:35, 24F
推
09/21 07:09, , 25F
09/21 07:09, 25F
→
09/21 08:38, , 26F
09/21 08:38, 26F
推
09/21 12:23, , 27F
09/21 12:23, 27F
→
09/21 14:10, , 28F
09/21 14:10, 28F
推
09/21 14:20, , 29F
09/21 14:20, 29F
推
09/21 14:45, , 30F
09/21 14:45, 30F
→
09/21 14:45, , 31F
09/21 14:45, 31F
→
09/21 14:47, , 32F
09/21 14:47, 32F
→
09/21 14:49, , 33F
09/21 14:49, 33F
推
09/21 15:03, , 34F
09/21 15:03, 34F
推
09/21 15:07, , 35F
09/21 15:07, 35F
推
09/21 15:07, , 36F
09/21 15:07, 36F
推
09/21 15:13, , 37F
09/21 15:13, 37F
→
09/21 15:14, , 38F
09/21 15:14, 38F
推
09/21 15:17, , 39F
09/21 15:17, 39F
→
09/22 11:44, , 40F
09/22 11:44, 40F
推
09/22 19:11, , 41F
09/22 19:11, 41F
→
09/22 19:12, , 42F
09/22 19:12, 42F
推
09/23 12:52, , 43F
09/23 12:52, 43F
※ 編輯: tropical72 來自: 180.177.78.41 (09/27 00:29)