-- 會員 / 註冊 --  
 帳號:
 密碼:
  | 註冊 | 忘記密碼
3/26 新書到! 3/19 新書到! 3/14 新書到! 12/12 新書到!
購書流程Q & A站務留言版客服信箱
3ds MaxMayaRhinoAfter EffectsSketchUpZBrushPainterUnity
PhotoShopAutoCadMasterCamSolidWorksCreoUGRevitNuke
C#CC++Java遊戲程式Linux嵌入式PLCFPGAMatlab
駭客資料庫搜索引擎影像處理FluentVR+ARANSYS深度學習
單晶片AVROpenGLArduinoRaspberry Pi電路設計CadenceProtel
HadoopPythonStm32CortexLabview手機程式AndroidiPhone
可查書名,作者,ISBN,3dwoo書號
詳細書籍分類

深入理解軟件構造系統:原理與最佳實踐

( 簡體 字)
作者:(加)Peter Smith類別:1. -> 程式設計 -> 綜合
譯者:
出版社:機械工業出版社深入理解軟件構造系統:原理與最佳實踐 3dWoo書號: 32872
詢問書籍請說出此書號!

缺書
不接受訂購

出版日:6/1/2012
頁數:404
光碟數:0
站長推薦:
印刷:黑白印刷語系: ( 簡體 版 )
不接受訂購
ISBN:9787111382263
作者序 | 譯者序 | 前言 | 內容簡介 | 目錄 | 
(簡體書上所述之下載連結耗時費功, 恕不適用在台灣, 若讀者需要請自行嘗試, 恕不保證)
作者序:

譯者序:

前言:

你是軟件開發人員嗎?你想知道構造系統的工作原理嗎?如果你正在閱讀這本書,你會對上述兩個問題作出肯定的回答。不過,許多軟件開發人員卻對自己編寫的程序是如何編譯出來的興趣寥寥,大多數人只想簡單地點擊按鈕,把源代碼轉變成可執行程序即可。如果他們需要修復缺陷,只會修改源代碼,然后再次點擊相同的按鈕。他們的樂趣在于看到自己的程序實現所有預期的功能,對他們來說,構造系統只是隱身幕后的一件必要工具而已。

當源文件的規模稍微大一些,就需要某種形式的自動化構造系統。這種系統可以是個shell腳本,供你在每次源代碼修改之后運行;也可以是個makefile,它了解源文件和目標文件之間的關系;或是個更復雜的構造框架,它可以擴展到成千上萬個源文件的處理規模。

如果你曾在UNIX或Windows命令行環境中寫過程序代碼,那么以下代碼看起來就很眼熟:

本例對5個C語言文件進行編譯和鏈接,創建一個名為sorter的獨立可執行程序。對于使用集成開發環境(Integrated Development Environment,IDE)的人來說,以上內容可能比較陌生,但它就是等同于在IDE環境中創建一個含有5個源文件的項目,然后在工具欄點擊【build】按鈕。

在進行過幾次手工編譯程序之后,你可能想把這些命令保存到一個shell腳本中,然后在每次修改代碼后重新運行這個腳本。另外,你也可以從命令行歷史中檢索命令,然后在每次修改代碼后再次執行相同的命令。

如果你基本了解Make工具,就可以創建自己的makefile,并在每次需要重新構造時輸入make命令。使用Make的好處是它僅當源文件在上次編譯之后發生變化時,才對程序進行重新構造。以下是用來編譯sorter程序的簡單makefile示例:

如果你熟悉Make,就會立即看出這不是個編寫makefile的好方法。第一個錯誤是把源文件列出了兩次:第一次是用于指定依賴關系,第二次是用在編譯命令中。第二個錯誤是每次重新構造程序時,會把所有源文件都編譯一次,即使它們未做任何修改。另外,這里只字未提C文件可能具有頭文件依賴關系。

更好的解決辦法是分解編譯步驟,使每個源文件的編譯和重新編譯都與其他文件無關。另外應當建立依賴文件(以.d為擴展名)來跟蹤頭文件的使用情況。改進建議還有很多,我們與其陷入所有技術細節,不如直接來看滿足全部要求的makefile最終版本:



這就是全部,用最少量的makefile代碼,最大限度地減少重復勞動。很簡單,是不是?

不過,如果你是一名開發人員而非構造專家,你真的理解上面的例子嗎?經驗豐富的Make專家當然理解這些語法,而且會提出更高效的建議來實現相同的效果。但對我們這些只想有個【build】按鈕的大多數人來說,第一次總要浪費大量時間才能讓makefile正常奏效。

實現和維護構造系統常常是復雜的。設計得糟糕的構造系統可能會浪費大量時間,如果某個文件應當卻未被重新編譯的話。當規模上升到成千上萬個源文件,開發人員可能會浪費半天時間來跟蹤排查問題,最后發現從零開始構造(刪除所有目標文件)是唯一的解決辦法。看來【build】按鈕涉及的工作真不少!

構造系統逐漸復雜的原因

構造系統會十分復雜并難以維護,這可能會讓你感到驚訝。如今圖形化用戶界面是如此普及,你當然期望構造工具也會同樣簡單易用。遺憾的是,許多人把創建構造系統看成是一種黑色藝術。只有少數知識淵博的大師,才知道構造工具的完整語法,或依賴關系體系的具體細節。盡管基于IDE的構造工具已解決了部分問題,但它們仍無法承載大規模構造系統的復雜度。

在大多數情況下,一般軟件產品的起始版本都來源于少量的源文件,這些文件被編譯和鏈接形成程序。在這種情況下,一個簡單的makefile就足以滿足需要,而且這個makefile只需從用戶手冊的makefile模板中復制一些內容,花幾個小時修改一下就可以輕松出爐。在幾個月內,除了向其中增加新的源文件和庫文件,沒有人需要修改這個構造系統。

再過一段時間,人們開始發現這個構造過程中的問題。例如,當文件需要重新編譯時卻沒有編譯;當文件本身或其依賴的數據都沒有變化時,文件卻被錯誤地重新編譯了;文件可能在一次構造過程中被編譯了幾遍,導致構造速度很慢。很快,“永遠采用‘clean 構造’(即首先刪除所有目標文件)”或“修改相關文件迫使其重新編譯”等做法,就變成了人們的共識。

當簡單的構造系統變得難以使用,makefile專家就需要反思構造系統的設計,這可能需要創建一個框架來解決所有的構造問題,并把實現細節與最終用戶隔離開。例如,軟件開發人員想看到的是源文件、庫文件、文件中所用編譯標志參數等的清單,但對依賴關系是如何管理的卻毫無興趣。例如:



我們的最終目標是得到一個正確而易用的構造系統,并將所有的復雜性隱藏在framework.mk文件中。對于只想有個【build】按鈕的軟件開發人員來說,這是個理想的解決方案。

這種框架式方法在一段時間內很有效果,效率也頗高,但在未來的某個時間就會開始問題頻發,對于那些在幾年內不斷增長的成功軟件產品來說尤其如此。這種適用于中小規模產品的構造系統,當產品規模增長時將不再適用。

考慮一下,如果要對購自第三方供應商的新代碼模塊進行集成,你會怎么做?新代碼已有自己的構造系統,與你原來產品的構造框架并不相同。當開發人員修改代碼時,就在新增代碼和現有代碼庫之間建立了相互依賴關系,這就要求構造系統能理解更復雜的文件間關系。最終結果是單方或雙方的構造框架需要進行重大修改,甚至可能是推翻重做。

隨著時間的推移,框架也在不斷增長,從而使框架的維護工作變得困難重重。在某些情況下,框架的原作者已經離開,無法進行修改,只有讓不熟悉的生手做這項工作。缺乏足夠構造經驗的開發人員常常采用走捷徑留后患的方法來構造軟件,如后文所述,這些方法包括:寫得很糟糕的shell腳本、大量使用符號鏈接,最糟糕的是源文件重復拷貝。構造過程變得機關重重,沒人能夠輕而易舉地進行維護。

悲哀的是,許多組織并不覺得需要完善自己的構造系統。如果組織的管理者是其他領域(例如電腦游戲、通信、商業應用等)的專家,他們會將熱情全部投注在創造產品上,增加產品的新功能,力圖以之打動最終用戶。在他們看來,構造系統只是產品生命周期中必要的一環,但完善構造系統并不是自己的責任。這一工作當然也從不出現在公司的企業目標或季度開發計劃中。

如你所見,本書通篇討論了在設計構造系統時必須考慮的大量問題。這不僅僅是擁有一個隨叫隨到的makfile大師之類的事,還應當讓開發環境保持一種可維護的狀態。把錢和時間花在清理構造系統上是值得的,這可以讓軟件開發團隊的生產率提升很多倍。

構造系統的真正成本

如果你還未相信一套可靠的構造系統的重要性,那就想想真正的成本。也就是說,如果你沒有一套良好的構造系統,將會付出多大代價?這種代價并不反映在財務報表上,而是隱藏在軟件開發人員日常生產率之中。

一項行業調查表明(參見參考文獻[1]),開發人員因為構造問題導致平均生產率降低12%,而有些被調查對象聲稱20%∼30%也并非罕見。值得注意的是,這項調查關注的是少于20人的小型開發團隊,他們一般不會碰到大型軟件所遭遇的規模度問題。

我們先假定在你的團隊中,所有軟件開發人員在遇到構造系統問題時會損失10%的工時。你對此產生何種反應取決于你以前軟件項目的經驗。對有些人來說,10%可能是了不得的大問題,而對許多組織來說,10%只是入門級程度。

這10%的生產率損失在哪里?回想一下你的團隊以前幾乎肯定碰到過的一些典型問題:

錯誤的依賴關系導致編譯失敗:構造系統獲取的依賴關系信息有誤,從而導致部分源代碼無法正確地重新編譯。當發生這種情況時,開發人員會投入所有時間,力圖完成一次成功的構造。而構造錯誤信息不僅晦澀難解,而且與開發人員剛剛修改的代碼范圍完全無關。如果不解決此類構造問題,他們就無法繼續有效開展工作。

錯誤的依賴關系導致無效的軟件實體:和上面的情況類似,錯誤的依賴關系導致部分代碼編譯失常。然而,構造系統并沒有給出編譯錯誤,但程序卻生成無效的輸出結果。這樣一來,開發人員和測試人員看到的是代碼中問題重重,而他們常常以為是自己的原因,而不是懷疑構造系統。開發人員要浪費一兩天的時間來排查測試錯誤,最后才發現問題并非是自己修改代碼造成的。而采用全新的構造樹來開始編譯,這些問題就會銷聲匿跡。

編譯速度太慢:大型軟件系統更經常遇到這一問題,而小型軟件可以在幾分鐘之內構造完成。如果你的軟件代碼庫需要很多小時的編譯時間,那么當開發人員在等待編譯完成時,他們的時間就被完全浪費了。這個問題對于增量式構造來說尤其嚴重,只修改一個源文件,就可能導致5∼10分鐘的延遲,然后才能重新運行程序。

你可能會想,在等待編譯完成時,開發人員可以做其他工作,這樣就更有效率。但情況并不總是這樣。開發人員有許多種“等待”活動,例如閱讀最新頭條新聞、更新社交網站內容、再喝一杯咖啡,或者起身與朋友聊天。但即使開發人員可以在構造過程中進行此類多任務,也會由于在不同任務環境之間切換而帶來生產率損耗。開發人員的注意力可能被分散,而完全想不起來他們剛剛在做的事情。

花時間更新構造描述文件:如果軟件構造框架艱深難懂,開發人員就可能需要咨詢專家才能進行修改。例如,如果想把新的源文件類型或新的編譯工具加入進來,他們必須先與構造專家咨詢討論。有時要等上幾天,構造專家才有空提供幫助;然后,構造專家可能要花一兩個星期研究才能完成這項工作。

如果你現在相信了10%的生產率損耗是個實際的數字,那么由此帶來的財務成本是多少?對此進行評估的最好辦法,是計算出你的公司工資總額支出的10%是多少。如果你是義務編寫軟件(這在開源世界中很普遍),那么這種評估方法就無效了,但其成本數額同樣是所有人關注的主題。

假定你有10名軟件工程師,每人每年的工資總額是7.5萬美元。這個額度是偏高還是偏低因城市而異,因此最好根據你自己的實際情況進行評估。會計對此估算結果可能會提出質疑,因為還要考慮額外成本,例如員工醫療福利、電費、房租、停車費,以及開發人員享受的其他專項福利。因此,我們暫且假定每年花在每個開發人員身上的成本是15萬美元。

由此得到開發人員解決構造問題的總成本是:

10% × 每年15萬美元 × 10名開發人員 = 每年15萬美元

這相當于一名全職開發人員一年不干活的成本!假定每年的工作日是250天,那么你的公司僅僅由于構造問題,每天就要付出600美元的代價!

如果你是一位軟件經理,你會想什么辦法來提高收益?是繼續為團隊因為構造問題所浪費的時間每天支出600美元,還是付出一兩個月的600美元/天的代價來雇傭一名構造專家,徹底解決此類問題?你自己的組織要選擇何種方式,絕對值得認真考慮。請別忘了,公司的利潤來自兩個方面:要么通過加大產品銷售而增加收入,要么通過在起始環節削減產品的生產成本。

本書的重點

你花時間閱讀本書的原因有二:

為了理解構造系統背后的基本原理:本書對構造系統的特性和應用場景進行了全面徹底的研究,讓你可以理解構造工具的工作方式。

為了獲得構造系統的更多經驗:本書融匯了作者運用多種不同工具在創建和維護構造系統方面的多年經驗,通過閱讀本書,你就可以避免以前構造系統開發人員所犯的初級錯誤。

有了以上知識,你就可以做出明智的選擇,采用何種構造工具,如何建設可靠的構造系統,以及如何預見可能影響生產率的陷阱和錯誤。從此,軟件的構造過程將變得更快、更容易和更可靠。

還要提醒一下,本書不包括以下內容:

本書不是操作手冊:本書不提供任何特定構造工具或技術的操作手冊內容,僅介紹少量示例片斷(例如第2章)。流行的構造工具都有各自專門的網站和書籍,為你講解每項語法和語義的細節。請參閱這些書籍,了解每種構造工具的更詳細信息。

本書不展示構造系統的全套功能:盡管本書包含許多示例,展示如何使用每種構造工具及很多支持工具,但并不從頭至尾演示如何創建一個全功能的構造系統。同上,你應當參閱每種構造工具的文檔,來查閱完整的創建示例。

當然,首先應該閱讀本書,這樣你就能理解每種構造工具的優缺點,從而可以判斷出你自己的構造系統應該使用哪些特性。

本書并未限定于某種開發環境或編程語言,而是從多種不同角度來提供示例并介紹概念:

C/C++語言構造:這可能是最經典的構造類型了,其構造風格起源于20世紀70年代,到現在一直變化不大。近年來它面臨的挑戰是文件數量的增長,以及如何處理已用于典型軟件產品的第三方程序庫。

Java語言構造:Java語言在20世紀90年代后期逐漸流行,對構造系統的設計產生了相當深遠的影響。舉個例子,Java的源文件所保存的目錄層次結構必須要與軟件包的結構相匹配。

C#語言構造:C語言、C++和Java都是平臺無關的編程語言,因此可以用于任何操作系統(例如Linux、Solaris、Mac OS X和Windows),而C#語言的構造環境則更傾向于微軟公司的做事方式。

除了覆蓋多種編程語言,本書還討論了開發大型軟件產品的兩種不同方式:

單體構造:此種方式是在一次構造過程中,整個代碼庫是從源代碼編譯成一個可執行程序。這是小型程序的常用構造方式,但它的可伸縮性不好,因為采用此種方式來構造大型軟件,會產生巨大的源樹,消耗極長的編譯時間。

組件構造:與單體構造相反,本方式把源代碼劃分為多個層級,分別單獨編譯,最后把各個預構造的組件合并成最終的可執行程序。

最后提醒一下,本書講述的內容并不遵循“Make是C/C++開發所選擇的主要工具”、“所有Java和C#軟件應當在IDE中進行構造”等常規假定。

預期讀者

本書主要面向軟件相關開發人員,包含以下幾類讀者:

開發人員:如果你是一名有多年源代碼開發經驗但只有少量構造系統經驗的開發人員,可以通過本書學習如何建設和維護構造系統,還可以學習各種用來描述構造過程的工具。

項目經理:通過本書,你可以學會較高層次的概念和技巧,而無須深入了解太多復雜細節。運用這些知識,你就可以評估團隊所做的工作,并向他們提出恰當的“指引方向式”問題。

構造專家:即使你有建設構造系統的多年經驗,也可以從本書學到一些新東西。本書不僅展示了你可能從未用過的現代構造工具,而且關于大型構造系統可伸縮性和性能方面的討論,會讓你在以后編寫構造框架時三思而后行。

本書的組織結構

本書主要分為四個部分,每個部分討論構造系統的角度略有差異。根據自身經驗和所關心的細節層次的不同,你可以選擇重點閱讀本書的某幾部分。新手開發人員應當重點閱讀第一部分和第二部分,有經驗的讀者可以跳過第一部分,重點閱讀第二、三、四部分。

第一部分:基礎知識

第一部分面向沒有太多構造經驗的軟件開發人員,對構造系統進行簡要介紹。即使有經驗的讀者也應快速瀏覽這些章節,以確保對基本概念有個完整的了解。例如, C/C++開發人員可以學到關于C#語言的新知識。

第1章介紹了構造系統的高層次概念,例如源樹和目標樹、構造工具、編譯工具等。第2章為從未接觸過Make的讀者提供了如何編寫makefile的快速指南。第3章描述了程序在計算機中運行的結構,以便講解構造系統要生成哪些東西。 第4章對構造過程使用的各種輸入輸出文件類型進行了詳細講解,并用C/C++、Java和C#語言進行舉例。第5章描述了構造變量背后的基本思想,而構造變量本身則在后續章節有更詳細的介紹。

閱讀完第一部分,你會對構造系統設計的相關基本概念有充分理解。

第二部分:構造工具

本書第二部分對5種構造工具進行了研究比較。在現有各種工具中篩選這5種工具時,既要考慮到它們的流行程度,也要考慮到它們各自體現了軟件構造的特定方法。每個章節首先介紹構造工具的語法,然后描述該工具的主要應用場景。為了提供有意義的比較結果,所有章節都使用了同一套標準示例。

第6章討論了GNU Make工具,它是C/C++開發的最常用工具。第7章研究了Ant工具,它是Java編譯的事實標準。第8章研究了新近出現的SCons工具,它采用Python語言來描述構造過程。第9章展示了CMake工具,它根據構造過程的高層次描述,生成一套原生構造系統(例如基于Make的系統)。第10章描述了Eclipse IDE中與構造相關的特性。

閱讀完第二部分,你會了解構造工具的當前狀況,并理解每種工具的優缺點。

第三部分:高級主題

第三部分討論更高級的構造系統概念,例如依賴關系分析、軟件打包與安裝、版本管理,以及構造機器和編譯工具的管理。這些章節假定你有較復雜軟件項目的工作經驗,可以理解這里討論的內容。

第11章詳細探討了各種依賴關系檢查技術,用于判斷哪些文件是否必須重新編譯。第12章展示了構造系統如何生成元數據來幫助進行調試、性能分析和源代碼文檔編寫。第13章提供了相關示例,展示如何進行軟件打包,使之達到可安裝到目標機器的狀態。第14章研究了與構造系統有關的版本控制方面的問題。第15章提供了關于構造機器管理的最佳經驗做法(構造機器是指軟件在其上進行編譯的機器)。第16章對編譯工具進行了類似討論。

閱讀完第三部分,你會理解關于建設構造系統的許多高級主題,并了解部分最佳經驗做法。

第四部分:提升規模

本書的最后一部分討論了在構造系統設計時如何適應大型軟件產品。隨著軟件產品的規模不斷增長,它會面臨可伸縮性問題,例如復雜度增長、磁盤空間占用急劇增多、構造時間也變長了。所有這些問題都會降低軟件開發的生產率。

第17章提出了降低最終用戶能感覺到的構造系統復雜度的幾種方法。第18章描述了怎樣把大型軟件產品劃分為多個組件,讓開發更有效率。最后,第19章討論了對軟件構造時間進行度量和改進的技術方法。

閱讀完第四部分,關于如何設計能夠適應規模增長的小型構造系統,你就會有更好的認識。

小結

建設高質量構造系統不是件容易的事,但如果做不到的話,將導致軟件團隊產生重大問題。如果源代碼應當重新編譯卻沒有進行,你的團隊成員將會面臨更長的構造時間或無規律的構造失敗,他們還可能把時間浪費在對無效軟件實體進行調試排錯上。因此,投入一定時間來確保構造系統正常工作是非常值得的。

使用質量低劣的構造系統的真正成本,可以用金錢來衡量。對于一般的軟件組織,他們會發現開發人員把10%的時間浪費在解決構造問題上,這也能推算出每年浪費多少錢。

本書講解了很多構造系統概念,介紹了一系列常用的構造工具,提供了部分最佳實踐做法,并討論了關于建設與維護大型構造系統方面的問題。

致謝

如果沒有我妻子Grace的鼎力支持,本書不可能完成。許多個夜晚和周末,我都躲在我的“安樂窩”里,敲著鍵盤,神游物外。Grace理解我寫這本書的重要意義(它列在我的遺愿清單上),她的耐心和支持讓本書得以面世。還要感謝Stan(我們的馬爾濟斯比熊犬),它終于體會到坐在地板上通常比坐在我的筆記本電腦或鍵盤上更舒服。

感謝我的父母,Sally和Smithy,允許我在他們餐廳的桌上編寫幾個章節的內容。我還要感謝他們多年來糾正我的拼寫和語法錯誤,讓我更輕松地寫出本書這么多的內容。

我要感謝接納本書予以出版的Pearson Education團隊提供的支持,感謝Raina Chrobak、Chris Zahn和Chris Guzikowski在本書的寫作和編輯過程中給予的指導,也感謝初稿評審人從實踐者或構造系統專家的角度提出的反饋意見,他們是Monte Davidoff、Jeffrey Overbey、J. T. Conklin、Kevin Bodie、Brad Appleton、John Pantone和Usman Muzaffar。

然后,我還要感謝Kevin Cheek和Bob McLaren,以及愛立信公司團隊中的其他人,他們允許我重新協商我的長期合同,讓我有足夠的時間來寫書。還要感謝許多朋友和同事,他們貢獻出自己全部的構造系統經驗,我希望他們的每條經驗都已體現在本書中。

最后,必須感謝為構造工具的設計和制造作出貢獻的每個人。大多數軟件項目都使用某種構造工具,這讓構造系統成為軟件技術的關鍵環節之一。而創造這些工具的人們,并不總是得到應有的尊重。
內容簡介:

構造系統在軟件開發過程中處于核心地位,它的正確性和性能,在一定程度上決定了軟件開發成果的質量和軟件開發過程的效率。本書作者作為一名軟件構造系統專家,總結了自己在構造系統開發和維護方面的多年經驗,對軟件構造系統的原理進行了深入淺出的剖析,并通過各種實際使用場景,對幾種最流行的構造工具進行了對比分析,另外還討論了構造系統的性能優化、規模提升等高級主題。

本書分為四部分。第一部分:基礎知識,第1~5章分別從構造系統的高層概念、基于Make的構造系統、程序的運行時視圖、文件類型與編譯工具、子標的與構造變量等方面介紹構造系統的概念和相關主題。第二部分:構造工具,第6~10章結合實際場景案例,對GNU Make、Ant、SCons、CMake和Eclipse IDE這五種構造工具進行分析比較,品評優劣,幫助讀者了解構造工具的當前狀況,并理解每種工具的優缺點。第三部分:高級主題,第11~16章對依賴關系、元數據、軟件打包與安裝、構造機器、工具管理等高級主題進行討論,幫助讀者理解關于建設構造系統的許多高級主題,并了解最佳實踐。第四部分:提升規模,第17~19章討論了在大規模構造系統的環境下,如何降低復雜性,提高構造運行速度,幫助讀者理解如何設計出能夠適應規模增長的小型構造系統,從而對軟件構造系統有更好的認識。

本書適合軟件開發相關人員,包含軟件開發人員、項目經理、軟件構造專業人士等閱讀。
目錄:

對本書的贊譽

譯者序

前 言

致 謝

作者介紹

第一部分 基礎知識

第1章 構造系統概述2

1.1 什么是構造系統2

1.1.1 編譯型語言3

1.1.2 解釋型語言3

1.1.3 Web應用4

1.1.4 單元測試5

1.1.5 靜態分析5

1.1.6 文檔生成6

1.2 構造系統的各個組成部分6

1.2.1 版本控制工具7

1.2.2 源樹與目標樹7

1.2.3 編譯工具和構造工具8

1.2.4 構造機器9

1.2.5 發布打包與目標機器9

1.3 構造過程和構造描述11

1.4 如何使用構造系統12

構造管理工具12

1.5 構造系統的質量13

本章小結14

第2章 基于Make的構造系統15

2.1 Calculator示例15

2.2 創建一個簡單的makefile17

2.3 對這個makefile進行簡化19

2.4 額外的構造任務20

2.5 框架的運用21

本章小結23

第3章 程序的運行時視圖24

3.1 可執行程序24

3.1.1 原生機器碼25

3.1.2 單體系統鏡像25

3.1.3 程序完全解釋執行26

3.1.4 解釋型字節碼26

3.2 程序庫28

3.2.1 靜態鏈接28

3.2.2 動態鏈接29

3.3 配置文件和數據文件30

3.4 分布式程序30

本章小結31

第4章 文件類型與編譯工具33

4.1 C/C++34

4.1.1 編譯工具34

4.1.2 源文件35

4.1.3 匯編語言文件37

4.1.4 目標文件38

4.1.5 可執行程序40

4.1.6 靜態程序庫40

4.1.7 動態程序庫41

4.1.8 C++編譯42

4.2 Java43

4.2.1 編譯工具43

4.2.2 源文件44

4.2.3 目標文件45

4.2.4 可執行程序47

4.2.5 程序庫48

4.3 C#48

4.3.1 編譯工具49

4.3.2 源文件49

4.3.3 可執行程序51

4.3.4 程序庫53

4.4 其他文件類型55

4.4.1 基于UML的代碼生成56

4.4.2 圖形圖像57

4.4.3 XML配置文件58

4.4.4 國際化與資源綁定58

本章小結59

第5章 子標的與構造變量60

5.1 針對子標的進行構造61

5.2 針對軟件的不同版本進行構造62

5.2.1 指定構造變量63

5.2.2 對代碼的定制調整65

5.3 針對不同的目標系統架構進行構造68

5.3.1 多重編譯器68

5.3.2 面向指定平臺的文件/功能69

5.3.3 多個目標樹69

本章小結71

第二部分 構造工具

現實場景75

場景1:源代碼放在單個目錄中75

場景2:源代碼放在多個目錄中76

場景3:定義新的編譯工具76

場景4:針對多個變量進行構造77

場景5:清除構造樹77

場景6:對不正確的構造結果進行調試78

第6章 Make79

6.1 GNU Make編程語言80

6.1.1 makefile規則:用來建立依賴關系圖80

6.1.2 makefile規則的類型81

6.1.3 makefile變量82

6.1.4 內置變量和規則84

6.1.5 數據結構與函數85

6.1.6 理解程序流程87

6.1.7 進一步閱讀資料90

6.2 現實世界的構造系統場景90

6.2.1 場景1:源代碼放在單個目錄中90

6.2.2 場景2(a):源代碼放在多個目錄中92

6.2.3 場景2(b):對多個目錄進行迭代式Make操作93

6.2.4 場景2(c):對多個目錄進行包含式Make操作96

6.2.5 場景3:定義新的編譯工具101

6.2.6 場景4:針對多個變量進行構造102

6.2.7 場景5:清除構造樹104

6.2.8 場景6:對不正確的構造結果進行調試105

6.3 贊揚與批評107

6.3.1 贊揚107

6.3.2 批評108

6.3.3 評價109

6.4 其他類似工具110

6.4.1 Berkeley Make110

6.4.2 NMake111

6.4.3 ElectricAccelerator和Spark Build111

本章小結113

第7章 Ant115

7.1 Ant編程語言116

7.1.1 比“Hello World”稍多一些116

7.1.2 標的的定義和使用118

7.1.3 Ant的控制流119

7.1.4 屬性的定義120

7.1.5 內置的和可選的任務122

7.1.6 選擇多個文件和目錄125

7.1.7 條件126

7.1.8 擴展Ant語言127

7.1.9 進一步閱讀資料128

7.2 現實世界的構造系統場景129

7.2.1 場景1:源代碼放在單個目錄中129

7.2.2 場景2(a):源代碼放在多個目錄中130

7.2.3 場景2(b):多個目錄,多個build.xml文件130

7.2.4 場景3:定義新的編譯工具133

7.2.5 場景4:針對多個變量進行構造136

7.2.6 場景5:清除構造樹140

7.2.7 場景6:對不正確的構造結果進行調試141

7.3 贊揚與批評142

7.3.1 贊揚143

7.3.2 批評143

7.3.3 評價144

7.4 其他類似工具144

7.4.1 NAnt144

7.4.2 MS Build145

本章小結146

第8章 SCons147

8.1 SCons編程語言148

8.1.1 Python編程語言148

8.1.2 簡單編譯151

8.1.3 管理構造環境154

8.1.4 程序流程和依賴關系分析157

8.1.5 決定何時重新編譯158

8.1.6 擴展該語言160

8.1.7 其他有趣的特性162

8.1.8 進一步閱讀資料163

8.2 現實世界的構造系統場景163

8.2.1 場景1:源代碼放在單個目錄中163

8.2.2 場景2(a):源代碼放在多個目錄中163

8.2.3 場景2(b):多個SConstruct文件164

8.2.4 場景3:定義新的編譯工具165

8.2.5 場景4:針對多個變量進行構造167

8.2.6 場景5:清除構造樹168

8.2.7 場景6:對不正確的構造結果進行調試169

8.3 贊揚與批評171

8.3.1 贊揚171

8.3.2 批評172

8.3.3 評價173

8.4 其他類似工具173

8.4.1 Cons173

8.4.2 Rake174

本章小結176

第9章 CMake177

9.1 CMake編程語言178

9.1.1 CMake語言基礎178

9.1.2 構造可執行程序和程序庫179

9.1.3 控制流182

9.1.4 跨平臺支持184

9.1.5 生成原生構造系統185

9.1.6 其他有趣的特性以及進一步閱讀資料190

9.2 現實世界的構造系統場景191

9.2.1 場景1:源代碼放在單個目錄中191

9.2.2 場景2:源代碼放在多個目錄中191

9.2.3 場景3:定義新的編譯工具192

9.2.4 場景4:針對多個變量進行構造193

9.2.5 場景5:清除構造樹194

9.2.6 場景6:對不正確的構造結果進行調試194

9.3 贊揚與批評195

9.3.1 贊揚195

9.3.2 批評195

9.3.3 評價196

9.4 其他類似工具196

9.4.1 Automake196

9.4.2 Qmake197

本章小結197

第10章 Eclipse199

10.1 Eclipse的概念和GUI199

10.1.1 創建項目200

10.1.2 構造項目206

10.1.3 運行項目210

10.1.4 使用內部項目模型212

10.1.5 其他構造特性213

10.1.6 進一步閱讀資料214

10.2 現實世界的構造系統場景215

10.2.1 場景1:源代碼放在單個目錄中215

10.2.2 場景2:源代碼放在多個目錄中216

10.2.3 場景3:定義新的編譯工具217

10.2.4 場景4:針對多個變量進行構造217

10.2.5 場景5:清除構造樹220

10.2.6 場景6:對不正確的構造結果進行調試220

10.3 贊揚與批評221

10.3.1 贊揚221

10.3.2 批評221

10.3.3 評價222

10.4 其他類似工具222

本章小結224

第三部分 高級主題

第11章 依賴關系226

11.1 依賴關系圖227

11.1.1 增量式編譯228

11.1.2 完全、增量式和子標的構造228

11.2 依賴關系錯誤導致的問題229

11.2.1 問題:依賴關系缺失導致運行時錯誤229

11.2.2 問題:依賴關系缺失導致編譯錯誤230

11.2.3 問題:多余的依賴關系導致大量不必要的重新構造231

11.2.4 問題:多余的依賴關系導致依賴關系分析失敗231

11.2.5 問題:循環依賴關系232

11.2.6 問題:以隱式隊列順序替代依賴關系232

11.2.7 問題:Clean標的什么也清除不了233

11.3 步驟一:計算依賴關系圖233

11.3.1 獲取確切的依賴關系234

11.3.2 把依賴關系圖緩存起來236

11.3.3 對緩存的依賴關系圖進行更新237

11.4 步驟二:判斷哪些文件已過期239

11.4.1 基于時間戳的方法240

11.4.2 基于校驗和的方法241

11.4.3 標志參數比較242

11.4.4 其他高級方法243

11.5 步驟三:為編譯步驟排定隊列順序243

本章小結246

第12章 運用元數據進行構造247

12.1 調試支持247

12.2 性能分析支持249

12.3 代碼覆蓋分析支持250

12.4 源代碼文檔化251

12.5 單元測試253

12.6 靜態分析256

12.7 向構造系統加入元數據257

本章小結258

第13章 軟件打包與安裝259

13.1 歸檔文件260

13.1.1 用于打包的腳本260

13.1.2 其他歸檔文件格式262

13.1.3 對打包腳本的改進263

13.2 包管理工具265

13.2.1 RPM包管理工具格式265

13.2.2 rpm build過程266

13.2.3 RPM規格文件示例267

13.2.4 根據規格文件創建RPM文件272

13.2.5 安裝RPM示例274

13.3 定制式GUI安裝工具275

13.3.1 Nullsoft Scriptable Install System(NSIS)276

13.3.2 安裝工具腳本277

13.3.3 定義安裝頁面280

13.3.4 許可授權頁面281

13.3.5 選擇安裝目錄282

13.3.6 主要組件282

13.3.7 可選組件283

13.3.8 定制頁面285

13.3.9 安裝頁面和卸載程序286

本章小結288

第14章 版本管理289

14.1 對哪些東西進行版本控制290

14.1.1 構造描述文件290

14.1.2 對工具的引用292

14.1.3 大型二進制文件296

14.1.4 對源樹的配置296

14.2 哪些東西不應當放到源樹中297

14.2.1 生成的文件被保存到源樹中297

14.2.2 生成的文件被納入到版本控制中299

14.2.3 構造管理腳本299

14.3 版本編號300

14.3.1 版本編號體系300

14.3.2 協調并更新版本號301

14.3.3 版本號的保存與檢索302

本章小結303

第15章 構造機器305

15.1 原生編譯與跨平臺編譯306

15.1.1 原生編譯306

15.1.2 跨平臺編譯306

15.1.3 異構環境307

15.2 集中式開發環境307

15.2.1 構造機器為何有差異308

15.2.2 管理多個構造機器310

15.3 開源開發環境312

15.4 GNU Autoconf315

15.4.1 高層次工作流315

15.4.2 Autoconf示例317

15.4.3 運行autoheader和autoconf319

15.4.4 在構造機器上運行configure腳本320

15.4.5 使用配置信息322

本章小結323

第16章 工具管理324

16.1 工具管理的規則324

16.1.1 規則1:做筆記324

16.1.2 規則2:對源代碼進行版本控制325

16.1.3 規則3:定期升級工具326

16.1.4 規則4:對工具的二進制文件進行版本控制327

16.1.5 對規則的破壞329

16.2 編寫自己的編譯工具329

用Lex和Yacc編寫定制工具330

本章小結332

第四部分 提升規模

第17章 降低最終用戶面對的復雜性334

17.1 構造框架334

17.1.1 面向開發人員的構造描述335

17.1.2 面向框架的構造描述336

17.1.3 慣例優先于配置336

17.1.4 構造工具示例:Maven337

17.2 避免支持多個構造變量的原因338

17.2.1 需要測試更多的構造變量338

17.2.2 代碼會變得混亂339

17.2.3 構造時間會增多340

17.2.4 需要更多磁盤空間340

17.3 降低復雜性的各種技術方法340

17.3.1 使用現代構造工具340

17.3.2 自動檢測依賴關系341

17.3.3 把生成的文件放在源樹之外341

17.3.4 確保正確清除構造樹341

17.3.5 碰到第一個錯誤即中止構造342

17.3.6 提供有意義的錯誤信息343

17.3.7 校驗輸入參數343

17.3.8 不要把構造腳本搞得過分復雜344

17.3.9 避免使用晦澀的語言特性344

17.3.10 不要用環境變量控制構造過程345

17.3.11 確保構造形成的發布版與調試版保持相似345

17.3.12 準確顯示正在執行的命令346

17.3.13 把對工具的引用納入版本控制347

17.3.14 把構造指令納入版本控制347

17.3.15 自動檢測編譯標志參數的變化347

17.3.16 不要在構造系統中調用版本控制工具347

17.3.17 盡量頻繁地進行持續集成348

17.3.18 統一使用一種構造機器348

17.3.19 統一使用一種編譯器348

17.3.20 避免遺留#ifdefs的垃圾代碼348

17.3.21 使用有意義的符號名349

17.3.22 刪除垃圾代碼349

17.3.23 不要復制源文件350

17.3.24 使用統一的構造系統350

17.4 對構造系統進行規劃充分、人力充足的改進351

本章小結352

第18章 管理構造規模353

18.1 單體模型構造存在的問題354

18.2 組件式軟件355

18.2.1 使用組件的好處357

18.2.2 組件到底是什么358

18.2.3 把多個組件集成到單個產品中361

18.3 人員和過程管理364

18.3.1 開發團隊的結構365

18.3.2 組件版本隊列管理367

18.3.3 管理組件緩存368

18.3.4 協調軟件新特性的開發370

18.4 Apache Ivy372

本章小結373

第19章 更快的構造375

19.1 度量構造系統性能375

19.1.1 啟動階段的性能度量375

19.1.2 編譯階段的性能度量382

19.1.3 性能度量工具386

19.1.4 修正問題:改進性能388

19.2 構造減免:消除不必要的重新構造389

19.2.1 目標文件緩存389

19.2.2 智能依賴關系391

19.2.3 構造減免的其他技術方法395

19.3 并行396

19.3.1 構造集群/云396

19.3.2 并行構造工具397

19.3.3 對可伸縮性的限制398

19.4 減少磁盤使用398

本章小結400

參考文獻401
序: