C_and_CPP 板


LINE

零、 前言 可能是學校作業,可能是之前我發過提問文,這星期私信來函不少, 內容從命令列編譯程式碼 到 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
1F:推 diabloevagto:不推別人以為我看不懂! 09/20 19:02
2F:推 diabloevagto:notepad++也很棒喔! 09/20 19:07
3F:→ diabloevagto:推薦 程式設計師的自我修養:連結、載入、程式庫 09/20 19:10
notepad++ 我還沒摸過,寫得不錯之編輯軟體應都有支援這部份, 純粹只因摸過 UltraEdit / PSPad, 兩者相較下我選用 PSPad (免費)
4F:推 ariesd:推MinGW+Vim,不推Dev-C++。 09/20 20:07
5F:→ tropical72:謝謝推書。另本文其實是想讓 Dev-C++ 使用者跳出來, 09/20 20:22
6F:→ tropical72:故才以 Dev-C++ 為例,了解流程後其實也不再限於 IDE.. 09/20 20:23
7F:→ weiyucsie:有種編譯和組譯搞錯的感覺XD 09/20 21:54
8F:→ weiyucsie:(跑去翻wikipedia :p) 09/20 22:00
compiler , assembler , 這個真的是我弄反了,已更正,謝謝指出。 :)
9F:推 lsc36:推推 第二頁有個地方打成TMD-gcc了XD 09/20 22:04
10F:→ james732:我以為TMD-gcc是故意的耶?XD 09/20 22:18
我也以為那是 TMD-gcc,查證後是 TDM-gcc,感謝 lsc36 指正。
11F:→ firejox:我傾向用geany做小型IDEXDD 09/20 22:35
12F:→ firejox:geany 裝好後在設完環境變數後就可以使用了XDD 09/20 22:36
13F:→ firejox:像linker這種事就交給makefile(逃~~ 09/20 22:41
14F:→ tropical72:geany 是 linux 底下的? linker 用 make 無庸致疑, 只 09/20 22:42
15F:→ tropical72:是現在我大多還是搞 batch, 是該找時間補 makefile. 09/20 22:42
16F:→ firejox:geany 也有windows的呀(雖然某些顯示有點怪怪的) 09/20 22:43
17F:推 Bencrie:不用 IDE 話有 Makefile 就夠了,不然就 cmake 09/20 22:45
18F:→ firejox:在windows下 還是先把路徑設一設比較方便... 09/20 22:52
19F:→ tropical72:不用IDE的話,一般還是會希望有high light 之軟體吧.. 09/20 23:08
20F:→ firejox:恩恩 highlight 是editor裡最偉大的發明(對programer而言) 09/20 23:26
21F:推 llewxam:有種tex進化到pdflatex的味道XD 09/20 23:36
22F:推 stonehomelaa:vim + gcc!! 09/21 00:19
23F:→ kasase:gvim搞定一切,讚 09/21 00:38
24F:推 VictorTom:推:) 09/21 01:35
25F:推 xatier:好文給個推! 09/21 07:09
26F:→ uranusjr:從 IDE 直接衝 CMake 也太硬了吧XD 09/21 08:38
27F:推 littleshan:拜託別再用 makefile 了 09/21 12:23
28F:→ shadow0326:為什麼不能用makefile QQ 09/21 14:10
29F:推 lmr3796:makefile有什麼不好嗎QQ 09/21 14:20
30F:推 littleshan:1. makefile內部寫死compile指令,換compiler很麻煩 09/21 14:45
31F:→ littleshan:2.難以處理不同的build如debug/release/shared/static 09/21 14:45
32F:→ littleshan:3. 隱藏的dependency很麻煩,makedepend只能處理.h 09/21 14:47
33F:→ littleshan:去看一下cmake/bjam/scons這些都是很棒的替代方案 09/21 14:49
34F:推 Bencrie:$(CC) $(CXX) 可以換吧 orz 09/21 15:03
35F:推 littleshan:參數不一樣啊... 09/21 15:07
36F:推 Bencrie:那 ... 全部用變數取代掉好了 XDD 09/21 15:07
37F:推 shadow0326:目前我的Makefile還真的是全用變數 @_@" 09/21 15:13
38F:→ shadow0326:而且分開make debug和make release @_@" 09/21 15:14
39F:推 Bencrie:不過這樣 Makefile 應該會很難讀喔 XD 09/21 15:17
40F:→ kingweirong:好文推~ 09/22 11:44
41F:推 bill42362:請問一下 CMake 能夠使用多 compiler 嗎? 09/22 19:11
42F:→ bill42362:比方說小弟的專案 .cu 需要 nvcc 而 .c 則要 gcc 這樣@@ 09/22 19:12
43F:推 Bencrie:可能要靠 custom command 把 .cu 指給 nvcc 09/23 12:52
※ 編輯: tropical72 來自: 180.177.78.41 (09/27 00:29)







like.gif 您可能會有興趣的文章
icon.png[問題/行為] 貓晚上進房間會不會有憋尿問題
icon.pngRe: [閒聊] 選了錯誤的女孩成為魔法少女 XDDDDDDDDDD
icon.png[正妹] 瑞典 一張
icon.png[心得] EMS高領長版毛衣.墨小樓MC1002
icon.png[分享] 丹龍隔熱紙GE55+33+22
icon.png[問題] 清洗洗衣機
icon.png[尋物] 窗台下的空間
icon.png[閒聊] 双極の女神1 木魔爵
icon.png[售車] 新竹 1997 march 1297cc 白色 四門
icon.png[討論] 能從照片感受到攝影者心情嗎
icon.png[狂賀] 賀賀賀賀 賀!島村卯月!總選舉NO.1
icon.png[難過] 羨慕白皮膚的女生
icon.png閱讀文章
icon.png[黑特]
icon.png[問題] SBK S1安裝於安全帽位置
icon.png[分享] 舊woo100絕版開箱!!
icon.pngRe: [無言] 關於小包衛生紙
icon.png[開箱] E5-2683V3 RX480Strix 快睿C1 簡單測試
icon.png[心得] 蒼の海賊龍 地獄 執行者16PT
icon.png[售車] 1999年Virage iO 1.8EXi
icon.png[心得] 挑戰33 LV10 獅子座pt solo
icon.png[閒聊] 手把手教你不被桶之新手主購教學
icon.png[分享] Civic Type R 量產版官方照無預警流出
icon.png[售車] Golf 4 2.0 銀色 自排
icon.png[出售] Graco提籃汽座(有底座)2000元誠可議
icon.png[問題] 請問補牙材質掉了還能再補嗎?(台中半年內
icon.png[問題] 44th 單曲 生寫竟然都給重複的啊啊!
icon.png[心得] 華南紅卡/icash 核卡
icon.png[問題] 拔牙矯正這樣正常嗎
icon.png[贈送] 老莫高業 初業 102年版
icon.png[情報] 三大行動支付 本季掀戰火
icon.png[寶寶] 博客來Amos水蠟筆5/1特價五折
icon.pngRe: [心得] 新鮮人一些面試分享
icon.png[心得] 蒼の海賊龍 地獄 麒麟25PT
icon.pngRe: [閒聊] (君の名は。雷慎入) 君名二創漫畫翻譯
icon.pngRe: [閒聊] OGN中場影片:失蹤人口局 (英文字幕)
icon.png[問題] 台灣大哥大4G訊號差
icon.png[出售] [全國]全新千尋侘草LED燈, 水草

請輸入看板名稱,例如:BabyMother站內搜尋

TOP