[分享] Windows 下架構 C/C++ 簡易 IDE

看板C_and_CPP作者 (藍影)時間12年前 (2011/09/20 18:48), 編輯推噓19(19024)
留言43則, 19人參與, 最新討論串1/1
零、 前言 可能是學校作業,可能是之前我發過提問文,這星期私信來函不少, 內容從命令列編譯程式碼 到 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
notepad++也很棒喔!
09/20 19:07, 2F

09/20 19:10, , 3F
推薦 程式設計師的自我修養:連結、載入、程式庫
09/20 19:10, 3F
notepad++ 我還沒摸過,寫得不錯之編輯軟體應都有支援這部份, 純粹只因摸過 UltraEdit / PSPad, 兩者相較下我選用 PSPad (免費)

09/20 20:07, , 4F
推MinGW+Vim,不推Dev-C++。
09/20 20:07, 4F

09/20 20:22, , 5F
謝謝推書。另本文其實是想讓 Dev-C++ 使用者跳出來,
09/20 20:22, 5F

09/20 20:23, , 6F
故才以 Dev-C++ 為例,了解流程後其實也不再限於 IDE..
09/20 20:23, 6F

09/20 21:54, , 7F
有種編譯和組譯搞錯的感覺XD
09/20 21:54, 7F

09/20 22:00, , 8F
(跑去翻wikipedia :p)
09/20 22:00, 8F
compiler , assembler , 這個真的是我弄反了,已更正,謝謝指出。 :)

09/20 22:04, , 9F
推推 第二頁有個地方打成TMD-gcc了XD
09/20 22:04, 9F

09/20 22:18, , 10F
我以為TMD-gcc是故意的耶?XD
09/20 22:18, 10F
我也以為那是 TMD-gcc,查證後是 TDM-gcc,感謝 lsc36 指正。

09/20 22:35, , 11F
我傾向用geany做小型IDEXDD
09/20 22:35, 11F

09/20 22:36, , 12F
geany 裝好後在設完環境變數後就可以使用了XDD
09/20 22:36, 12F

09/20 22:41, , 13F
像linker這種事就交給makefile(逃~~
09/20 22:41, 13F

09/20 22:42, , 14F
geany 是 linux 底下的? linker 用 make 無庸致疑, 只
09/20 22:42, 14F

09/20 22:42, , 15F
是現在我大多還是搞 batch, 是該找時間補 makefile.
09/20 22:42, 15F

09/20 22:43, , 16F
geany 也有windows的呀(雖然某些顯示有點怪怪的)
09/20 22:43, 16F

09/20 22:45, , 17F
不用 IDE 話有 Makefile 就夠了,不然就 cmake
09/20 22:45, 17F

09/20 22:52, , 18F
在windows下 還是先把路徑設一設比較方便...
09/20 22:52, 18F

09/20 23:08, , 19F
不用IDE的話,一般還是會希望有high light 之軟體吧..
09/20 23:08, 19F

09/20 23:26, , 20F
恩恩 highlight 是editor裡最偉大的發明(對programer而言)
09/20 23:26, 20F

09/20 23:36, , 21F
有種tex進化到pdflatex的味道XD
09/20 23:36, 21F

09/21 00:19, , 22F
vim + gcc!!
09/21 00:19, 22F

09/21 00:38, , 23F
gvim搞定一切,讚
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
從 IDE 直接衝 CMake 也太硬了吧XD
09/21 08:38, 26F

09/21 12:23, , 27F
拜託別再用 makefile 了
09/21 12:23, 27F

09/21 14:10, , 28F
為什麼不能用makefile QQ
09/21 14:10, 28F

09/21 14:20, , 29F
makefile有什麼不好嗎QQ
09/21 14:20, 29F

09/21 14:45, , 30F
1. makefile內部寫死compile指令,換compiler很麻煩
09/21 14:45, 30F

09/21 14:45, , 31F
2.難以處理不同的build如debug/release/shared/static
09/21 14:45, 31F

09/21 14:47, , 32F
3. 隱藏的dependency很麻煩,makedepend只能處理.h
09/21 14:47, 32F

09/21 14:49, , 33F
去看一下cmake/bjam/scons這些都是很棒的替代方案
09/21 14:49, 33F

09/21 15:03, , 34F
$(CC) $(CXX) 可以換吧 orz
09/21 15:03, 34F

09/21 15:07, , 35F
參數不一樣啊...
09/21 15:07, 35F

09/21 15:07, , 36F
那 ... 全部用變數取代掉好了 XDD
09/21 15:07, 36F

09/21 15:13, , 37F
目前我的Makefile還真的是全用變數 @_@"
09/21 15:13, 37F

09/21 15:14, , 38F
而且分開make debug和make release @_@"
09/21 15:14, 38F

09/21 15:17, , 39F
不過這樣 Makefile 應該會很難讀喔 XD
09/21 15:17, 39F

09/22 11:44, , 40F
好文推~
09/22 11:44, 40F

09/22 19:11, , 41F
請問一下 CMake 能夠使用多 compiler 嗎?
09/22 19:11, 41F

09/22 19:12, , 42F
比方說小弟的專案 .cu 需要 nvcc 而 .c 則要 gcc 這樣@@
09/22 19:12, 42F

09/23 12:52, , 43F
可能要靠 custom command 把 .cu 指給 nvcc
09/23 12:52, 43F
※ 編輯: tropical72 來自: 180.177.78.41 (09/27 00:29)
文章代碼(AID): #1EU6-1Ld (C_and_CPP)