linux環境下的c++程式設計

zyex1108發表於2016-11-29

標籤: linuxc++makefileemacslisp工具
24162人閱讀 評論(2) 收藏 舉報

 就C++開發工具而言,與Windows下微軟(VC, VS2005等)一統天下相比,Linux/Unix下C++開發,可謂五花八門,各式各樣。Emacs, vi, eclipse, anjuta,kdevelop等層出不窮。


Windows下,開發工具多以整合開發環境IDE的形式展現給終端使用者。例如,VS2005整合了編輯器,巨集彙編ml,C /C++編譯器cl,資源編譯器rc,偵錯程式,文件生成工具, nmake。它們以整合方式提供給終端使用者,對於初學者而言十分方便。但是,這種商業模式,直接導致使用者可定製性差,不利於自動化,整合第三方工具的能力弱

例如,無法定製一些巨集來處理一些重複操作;體會不到自動化makefile一步到位快感;無法遠端登入到伺服器上進行開發;無法使用某種粘合劑來把第三方工具(例如,文字工具,字串工具)有效地呼叫起來。可以說,良好的商業支援和傻瓜式開發,是它們主要的優點。


在linux下,開發工具被切割成一個個獨立的小工具。各自處理不同的問題。例如:

編輯器(emacs, vim) 用來進行編輯程式的
偵錯程式(gdb)
用來除錯程式
編譯器(GCC)
用來編譯和連結程式的
效能分析工具(gcov, gprof)
用來優化程式的
文件生成器(doxygen) 用來生成文件的

同時,還有一些系統工具和系統知識,我們是很有必要了解的:程式自動化機制 makefile,系統粘合劑shell,系統查詢工具grep, locate, find。其它的工具(例如ctags, OCI公司的MPC等等),一旦熟練掌握,它們將成為你手中的利器。


本文主要是一些針對LINUX下開發工具使用的經驗之談。由於,工具品種繁多,我們沒有能力也沒有必要一一介紹。對於LINUX下IDE工具,例如 eclipse, anjuta等,它們雖然也很實用,但是使用起來比較簡單,而且目前還算不上主流。所以,它們將不被著重介紹。同時,本文也不打算寫成各個工具的操作手冊,只著眼於介紹各個工具的想要解決的問題、執行機理和主要特性。



編輯器
要進行開發,第一件事情就是選擇一個合適的編輯器。編輯器選擇有幾個要素:
1)減少不必要的編輯動作,減少編輯的時間。
一切能夠無二義性描述出來的編輯任務,都可以而且應該能被自動化。例如,每一個C++程式都會有一個main函式;我們在定義.h檔案時,都希望加入一些預處理指令#define來幫我們解決重複引用同一個標頭檔案而帶來的麻煩。滑鼠操作總是比鍵盤操作要慢的。這方面 EMACS 做得可算是到了極致。所以, EMACS使用者經常會吹噓:他們編輯的速度等同於他們思考的速度。

=============================================================================

連結串列處理語言 (有專貼)

   LISP(全名LISt Processor,即連結串列處理語言),由約翰·麥卡錫在1960年左右創造的一種基於λ演算的函數語言程式設計語言。

  LISP有很多種方言,各個實現中的語言不完全一樣。各種LISP方言的長處在於操作符號性的資料和複雜的資料結構。1980年代Guy L. Steele編寫了Common Lisp試圖進行標準化,這個標準被大多數直譯器編譯器所接受。在Unix/Linux系統中,還有一種和Emacs一起的Emacs Lisp(而Emacs正是用Lisp編寫的)非常流行,並建立了自己的標準。

  LISP的祖先是1950年代Carnegie-Mellon大學的Newell、Shaw、Simon開發的IPL語言。

  LISP語言的主要現代版本包括Common Lisp和Scheme

  lisp擁有理論上最高的運算能力

  lisp在cad繪圖軟體上的應用非常廣泛,普通使用者均可以用lisp編寫出各種定製的繪圖命令。

=============================================================================


2)可擴充套件性高。
程式設計師預期的編輯器應該能提供一些程式設計的幫助,例如,語法高亮,自動補齊,自動排版,語法檢查等等。留心觀察一下gedit, vim, emacs, ultraEdit,就會發現它們提供的遠不是windows 記事本,寫字板提供的那麼簡陋的功能。對於一種新的語言,新的語法,它們應該能很方便地提供支援,而不停留在一種或幾種固定的語言上。


3)使用者可定製性高。
如果想長期從事研發, 特別是linux/unix下研發的話,那麼你很有必要學好一個功能足夠的編輯器。有這麼一句話:Linux下程式設計師分為三種,使用emacs的,使用vi的,還有其它。
EMACS是Stallman用lisp語言寫的一個GPL的編輯器。我們這裡所說的emacs指的是GNU emacs,而非Xemacs。由於它的開放性,我們可以把它打造成一個功能強大的IDE。我們在安裝好CGYwin之後,也可以在Windows系統下使用 EMACS。CGYwin和MINGW是第三方寫的一個在Windows系統上模擬POSIX系統的工具。
EMACS與其說的是一個編輯器,倒不如說它是一個作業系統。我們可以用它來寫程式設計,寫wiki,收發郵件等等。EMACS主要是通過兩種方式來進行擴充套件:el指令碼(elisp是lisp的一種方言)和第三方擴充套件包。EMACS的入門成本很高。由於是純鍵盤操作,所以需要記憶大量的快捷鍵;功能強大是通過使用者新增一些擴充套件包,lisp指令碼來實現的。如何正確配置和修改是很需要耐心和技巧的。


編譯器
編譯器首選GCC(GNU COMPILER COLLECTION)。原因有兩個,它是GNU開源的,同時它對標準C++的支援度高達96.15%。而VC++6.0的支援度只有83.43%。 GCC不僅是通常意義上的C或C++的編譯器,它還可以編譯Java等其它語言。gcc是GUN c的編譯器, g++ 是GUN c++的編譯器, 而EGCS(Enhanced GNU Compiler Suite)可以認為是gcc的改進版。
編譯語言從源程式到目的碼會經過如下幾個階段:源程式->彙編程式->編譯成obj程式->連結成最終可執行程式。我們可以通過一條編譯指令來完成所有步驟。也可以分步執行。

gcc有三個重要選項-E(只進行預處理), -S(生成彙編程式碼), -g(生成帶原始碼除錯符號的可執行檔案,如果想用gdb除錯的話,就應該在編譯時開啟這個選項)。
GCC可以看作一個軟體包,除了編譯工具,它還整合了偵錯程式gdb效能分析工具gcov, gprof。只要我們裝好了GCC,這些強大工具就可以直接使用了。
通過gcov,我們可以檢視一個程式,原始碼中每行程式碼的執行次數。我們優化執行次數最多的程式碼,那麼就可以大大優化程式。使用gcov時,需要開啟 GCC的 fprofile-arcs 和 ftest-coverage 兩個選項。gcov中常用的選項有-b分支統計資訊。
通過gprof工具,我們可以檢視函式之間的呼叫順序,及各個函式執行的時間。我們可以將gprof理解為linux/unix自帶工具time的加強版。使用gprof時,需要開啟GCC的pg選項
gcov 和 gprof 的共同點是在編譯程式時,加入自己的一些輔助資訊,由此來進行程式診斷。除了,這些優化手段,我們還可以使用一些記憶體洩漏工具,來減少野指標,未釋放的記憶體空間。


偵錯程式
GDB即GNU的偵錯程式,它是GCC附帶的一個效能優質的偵錯程式。通過GDB和指令碼結合,我們可以很好的實現迴歸測試
GDB可以執行於CLI和GUI兩種模式(命令列和圖形模式) 。預設GDB是CLI模式的,我們可以去下載和安裝GUI模式的GDB,例如xxgdb, ddd等。一個更好的方式是在 EMACS中使用GDB。GDB包括visual studio工具的所有除錯功能,還包括它沒有的功能。它除了支援,我們一般的設定斷點,單步跟蹤,step in, step out, step over等,還有一些強大的功能。在gdb中,我們可以有以下幾種暫停方式:斷點(BreakPoint)、觀察點(WatchPoint)、捕捉點(CatchPoint)、訊號(Signals)、執行緒停止(Thread Stops)。
下面列舉幾個讓我印象深刻的功能。1)通過 watch指令,可以讓程式在某個變數的值發生變化時,暫停下來。2)通過print指令,在程式執行時,設定變數的值,執行一個程式自身支援的一個方法。3)通過until指令,我們可以讓程式在執行到某個程式時暫停下來。4)通過break.. if指令,使得程式在滿足某個bool表示式時,暫停下來。


粘合劑
我想通過粘合劑這個詞來表達將多個工具粘合起來的膠水。例如,通過shell指令碼,我們可以把OS命令,sed指令,awk指令,其它指令碼檔案等串聯起來,發揮它們的合力。在linux C++程式設計中,我們不可避免地會使用makefile檔案。通過它我們可以把編譯指令,生成文件操作,清除操作等等串聯起來。從某種意義上來看,它也相當於一個粘合劑。
makefile的出發點是,維護好一個專案中眾多檔案的依賴關係,由此得到一個源程式的拓撲圖。當我們只修改圖中某個結點時,重新編譯時就只需要將拓撲圖中關聯的鏈路進行編譯就好了。由此,大大縮短了編譯的時間。make有兩大概念:dependencies和rules。規則rule即針對每一個依賴關係 dependency定義一個操作規則。這個細粒度的分離,就可以使我們可以定製軟體構建的行為。例如,修改使用的編譯器,修改includepath, 修改libpath, 修改編譯選項等等。我們常見的VC中的nmake,功能和make是類似的。
make使用的重點和難點是編寫Makefile檔案。Makefile的語法相對其它語言來說是很不一樣的,我們要特別注意TAB鍵和空格鍵的區別。
有很多工具可以用來幫助我們生成Makefile。最出名的就是GNU的autoconf了。一個GNU程式的編寫,需要autoscan, aclocal, autoconf, automake這四個工具。
我們知道GNU軟體安裝的三步曲是:./configure, make, make install。其中./configure就是根據autoconf, alocal等工具生成一個makefile檔案。make指令就是呼叫make指令來根據makefile檔案的規則來編譯源程式。而make install就是執行makefile中的install規則指出的操作(一般是copy操作)。而make clean就是執行makefile中的clean規則指出的操作(一般是rm操作)。我們用Eclispe+CDT開發Managed C++ Project時,它就是通過objects.mk,subdir.mk,sources.mk三個檔案來生成Makefile。我們注意觀察編譯時的輸出資訊,就可以看到顯示的Makefile檔案的內容。
可以說,如果想編譯出跨平臺的C++程式,那麼makefile是一種最方便的機制。
OCI公司為Douglas C.Schmidt的ACE,TAO開源社群編寫了一段偉大的perl指令碼--MPC。它由平臺資訊,一個規則檔案,原始碼,生成使用者想要的工程檔案,例如Make, Nmake, Visual C++ 6, Visual C++ 7等等。Google Web Tookit, Celtix做的事情與之類似,不過它們是針對JAVA的,而MPC是針對C++的。


結束語
國內資料太多的低層次的重複,經常是一個網頁被多次轉載,而且回答問題時深度不夠。個人找資料的順序是:

檢視quick start或how to文件->自帶的幫助(如果看起來不太吃力話)->百度查一下中文網頁,來理清一下基本概念->google查一下->幾個大的,相關的網站查下資料->看自帶幫助。再者,面對面的交流是十分重要的,大家可以相互理一下概念,交流一下心得。可惜,我身邊這種氛圍還是不夠。 // 這種氣氛現在想來是無比的難得
Linux下開發還可以更友好一些。個人感覺, linux開發要在國內普通程式設計師中大規模普及,還有一段很長的路要走。ubuntu火爆的主要原因,就是它幫使用者搭好一些預設配置。使用者如果想新加一些服務,它們提供了良好,有效地支援。所以,我想我們可以在IDE和現在linux這種一個個小部件的這兩種狀態之間,取一個折衷。也就是針對幾種主要需求的使用者,釋出一些配置好的環境。尤其是emacs的各種el指令碼(例如介面主題的color-theme, C/C++語言編輯策略,程式碼樣式設定指令碼,各種emacs系統設定), 第三方擴充套件包(模板template, 程式設計支援包cedet等)。每一個使用者浪費時間來進行這些配置是十分沒有意義的!工具始終只是工具,我們不能淪為工具的奴隸,不能把一大部分精力浪費在配置工具上。
值得注意的是現在方興未艾的eclipse有向這方面邁進的趨勢。但是,現在emacs已經做得很好了,ecilpse能否超越它,我們還有待觀察。我們可以通過在eclipse上安裝SDT外掛來進行C++開發。但是,它目前還不支援除錯功能,而且不太穩定,功能不夠強。例如,有時會無故死掉;如果想通過eclipse來轉向函式原型的話,那麼迎接你的將是一個漫長、焦急的等待。
由於本人缺少在linux下進行實際大規模程式的開發經驗,對很多工具和機制的理解還比較膚淺。對它們的熟悉程度離真正實用,還有一段很長的路要走。

 

 

 

本文轉載地址:http://apps.hi.baidu.com/share/detail/21368004

相關文章