Android的優(yōu)勢就在于其開源,手機和平板生產(chǎn)商可以根據(jù)自己的硬件進行個性定制自己的手機產(chǎn)品,如小米,LePhone,M9等,因此,在我們在對Android的源碼進行定制的時候,很有必要了解下,Android的編譯過程。
如果你從來沒有做過Android代碼的編譯,那么官方的編譯過程就是查看Android的官方網(wǎng)站://source.android.com/source/building.html
但是,這兒只是告訴你了如何去編譯一個通用的系統(tǒng),并沒有詳細(xì)告訴你細(xì)節(jié),我們跟著編譯過程來了解下。
+--------------------------------------------------------------------------------------------+
本文使用Android版本為2.1,采用開發(fā)板為華清遠(yuǎn)見研發(fā)的FS_S5PC100 A8開發(fā)板。
+--------------------------------------------------------------------------------------------+
1、 source build/envsetup.sh
這個命令是用來將envsetup.sh里的所有用到的命令加載到環(huán)境變量里去,我們來分析下它。
envsetup.sh里的主要命令如下:
[plain] view plaincopyprint?
1. function help() # 顯示幫助信息
2. function get_abs_build_var() # 獲取絕對變量
3. function get_build_var() # 獲取絕對變量
4. function check_product() # 檢查product
5. function check_variant() # 檢查變量
6. function setpaths() # 設(shè)置文件路徑
7. function printconfig() # 打印配置
8. function set_stuff_for_environment() # 設(shè)置環(huán)境變量
9. function set_sequence_number() # 設(shè)置序號
10. function settitle() # 設(shè)置標(biāo)題
11. function choosetype() # 設(shè)置type
12. function chooseproduct() # 設(shè)置product
13. function choosevariant() # 設(shè)置variant
14. function tapas() # 功能同choosecombo
15. function choosecombo() # 設(shè)置編譯參數(shù)
16. function add_lunch_combo() # 添加lunch項目
17. function print_lunch_menu() # 打印lunch列表
18. function lunch() # 配置lunch
19. function m() # make from top
20. function findmakefile() # 查找makefile
21. function mm() # make from current directory
22. function mmm() # make the supplied directories
23. function croot() # 回到根目錄
24. function cproj()
25. function pid()
26. function systemstack()
27. function gdbclient()
28. function jgrep() # 查找java文件
29. function cgrep() # 查找c/cpp文件
30. function resgrep()
31. function tracedmdump()
32. function runhat()
33. function getbugreports()
34. function startviewserver()
35. function stopviewserver()
36. function isviewserverstarted()
37. function smoketest()
38. function runtest()
39. function godir () # 跳到指定目錄
40.
41.
42. # 這是系統(tǒng)自動增加了一個默認(rèn)的編譯項 generic-eng
43. # add the default one here
44. <strong><span style="color:#ff0000;">add_lunch_combo generic-eng</span></strong>
45.
46.
47. # 下面的代碼很重要,它要從vendor目錄下查找vendorsetup.sh文件,如果查到了,就加載它
48. # Execute the contents of any vendorsetup.sh files we can find.
49. <strong><span style="color:#ff0000;">for f in `/bin/ls vendor/*/vendorsetup.sh vendor/*/build/vendorsetup.sh 2> /dev/null`
50. do
51. echo "including $f"
52. . $f
53. done</span></strong>
根據(jù)上面的內(nèi)容,可以推測出,如果要想定義自己的產(chǎn)品編譯項,簡單的辦法是直接在envsetup.sh后,添加上add_lunch_combo myProduct-eng,當(dāng)然這么做,不太符合上面代碼后的本意,我們還是老實的在vendor目錄下創(chuàng)建自己公司名字,然后在公司目錄下創(chuàng)建一個新的vendorsetup.sh,在里面添加上自己的產(chǎn)品編譯項。
[plain] view plaincopyprint?
1. #mkdir vendor/farsight/
2. #touch vendor/farsight/vendorsetup.sh
3. #echo "add_lunch_combo fs100-eng" > vendor/farsight/vendorsetup.sh
這樣,當(dāng)我們在執(zhí)行source build/envsetup.sh命令的時候,可以在shell上看到下面的信息:
[plain] view plaincopyprint?
1. including vendor/farsight/vendorsetup.sh
2. 按照android官網(wǎng)的步驟,開始執(zhí)行l(wèi)unch full-eng
當(dāng)然如果你按上述命令執(zhí)行,它編譯的還是通用的eng版本系統(tǒng),不是我們個性系統(tǒng),我們可以執(zhí)行l(wèi)unch命令,它會打印出一個選擇菜單,列出可用的編譯選項
如果你按照第一步中添加了vendorsetup.sh那么,你的選項中會出現(xiàn):
[plain] view plaincopyprint?
1. You're building on Linux
2.
3. generic-eng simulator fs100-eng
4. Lunch menu... pick a combo:
5. generic-eng
6. simulator
7. fs100-eng
其中第3項是我們自己添加的編譯項。
lunch命令是envsetup.sh里定義的一個命令,用來讓用戶選擇編譯項,來定義Product和編譯過程中用到的全局變量。
我們一直沒有說明前面的fs100-eng是什么意思,現(xiàn)在來說明下,fs100是我定義的產(chǎn)品的名字,eng是產(chǎn)品的編譯類型,除了eng外,還有user, userdebug,分別表示:
eng: 工程機,
user:終用戶機
userdebug:調(diào)試測試機
由此可見,除了eng和user外,另外兩個一般不能交給終用戶的,記得m8出來的時候,先放出了一部分eng工程機,然后出來了user機之后,可以用工程機換。
好了,我們來分析下lunch命令干了什么?
[plain] view plaincopyprint?
1. function lunch()
2. {
3. local answer
4.
5. if [ "$1" ] ; then
6. # lunch后面直接帶參數(shù)
7. answer=$1
8. else
9. # lunch后面不帶參數(shù),則打印處所有的target product和variant菜單提供用戶選擇
10. print_lunch_menu
11. echo -n "Which would you like? [generic-eng] "
12. read answer
13. fi
14.
15. local selection=
16.
17. if [ -z "$answer" ]
18. then
19. # 如果用戶在菜單中沒有選擇,直接回車,則為系統(tǒng)缺省的generic-eng
20. selection=generic-eng
21. elif [ "$answer" = "simulator" ]
22. then
23. # 如果是模擬器
24. selection=simulator
25. elif (echo -n $answer | grep -q -e "^[0-9][0-9]*$")
26. then
27. # 如果answer是選擇菜單的數(shù)字,則獲取該數(shù)字對應(yīng)的字符串
28. if [ $answer -le ${#LUNCH_MENU_CHOICES[@]} ]
29. then
30. selection=${LUNCH_MENU_CHOICES[$(($answer-$_arrayoffset))]}
31. fi
32. # 如果 answer字符串匹配 *-*模式(*的開頭不能為-)
33. elif (echo -n $answer | grep -q -e "^[^\-][^\-]*-[^\-][^\-]*$")
34. then
35. selection=$answer
36. fi
37.
38. if [ -z "$selection" ]
39. then
40. echo
41. echo "Invalid lunch combo: $answer"
42. return 1
43. fi
44.
45. # special case the simulator
46. if [ "$selection" = "simulator" ]
47. then
48. # 模擬器模式
49. export TARGET_PRODUCT=sim
50. export TARGET_BUILD_VARIANT=eng
51. export TARGET_SIMULATOR=true
52. export TARGET_BUILD_TYPE=debug
53. else
54.
55. # 將 product-variant模式種的product分離出來
56. local product=$(echo -n $selection | sed -e "s/-.*$//")
57.
58. # 檢查之,調(diào)用關(guān)系 check_product()->get_build_var()->build/core/config.mk比較羅嗦,不展開了
59. check_product $product
60. if [ $? -ne 0 ]
61. then
62. echo
63. echo "** Don't have a product spec for: '$product'"
64. echo "** Do you have the right repo manifest?"
65. product=
66. fi
67.
68. # 將 product-variant模式種的variant分離出來
69. local variant=$(echo -n $selection | sed -e "s/^[^\-]*-//")
70.
71. # 檢查之,看看是否在 (user userdebug eng) 范圍內(nèi)
72. check_variant $variant
73. if [ $? -ne 0 ]
74. then
75. echo
76. echo "** Invalid variant: '$variant'"
77. echo "** Must be one of ${VARIANT_CHOICES[@]}"
78. variant=
79. fi
80.
81. if [ -z "$product" -o -z "$variant" ]
82. then
83. echo
84. return 1
85. fi
86. <span style="white-space:pre"> </span># 導(dǎo)出環(huán)境變量,這兒很重要,因為后面的編譯系統(tǒng)都是依賴于這里定義的幾個變量的
87. export TARGET_PRODUCT=$product
88. export TARGET_BUILD_VARIANT=$variant
89. export TARGET_SIMULATOR=false
90. export TARGET_BUILD_TYPE=release
91. fi # !simulator
92.
93. echo
94.
95. # 設(shè)置到環(huán)境變量,比較多,不再一一列出,簡單的方法 set >env.txt 可獲得
96. set_stuff_for_environment
97. # 打印一些主要的變量, 調(diào)用關(guān)系 printconfig()->get_build_var()->build/core/config.mk->build/core/envsetup.mk 比較羅嗦,不展開了
98. printconfig
99. }
由上面分析可知,lunch命令可以帶參數(shù)和不帶參數(shù),終導(dǎo)出一些重要的環(huán)境變量,從而影響編譯系統(tǒng)的編譯結(jié)果。導(dǎo)出的變量如下(以實際運行情況為例)
[plain] view plaincopyprint?
1. TARGET_PRODUCT=fs100
2. TARGET_BUILD_VARIANT=eng
3. TARGET_SIMULATOR=false
4. TARGET_BUILD_TYPE=release
執(zhí)行完上述兩個步驟,就該執(zhí)行:make命令了,下篇來分析。