深入理解軟件構造系統:原理與最佳實踐 (Software Build Systems: Principles and Experience)

(加)史密斯著

買這商品的人也買了...

商品描述

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

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

作者簡介

PeterSmith,資深軟件開發工程師和軟件構造系統專家,專注於軟件生產效率的探索和研究,對各種新型軟件工具的選用與開發、軟件項目管理、IT基礎設施項目管理、基於軟件工具的流程改進,以及如何使企業的現有流程實現自動化等能幫助企業提高軟件生產效率的一系列核心問題都有非常深入的認識,實踐經驗極為豐富。
  Peter畢業於哥倫比亞大學,擁有計算機科學博士學位,研究方向是編譯器和語言設計。他曾在大學任教,主要教授編譯器設計、編程語言設計、軟件工程和計算機網絡等方面的課程。此外,他還是OOPSLA(面向對象編程、系統、語言與應用)協會的委員。

目錄大綱

第一部分基礎知識
第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