androidstrip
① 如何用c++寫安卓手機軟體
用c++寫安卓手機軟體的方法:
安裝ndk,使用純c++開發安卓程序,下邊是詳細的步驟與說明:
1、編寫入口函數
android_main為入口函數,和C++中的main函數是一樣的。這里創建CELLAndroidApp的對象,直接調用main函數。
voidandroid_main(structandroid_app*state)
{
CELLAndroidAppapp(state);
app.main(0,0);
}
2.繪制類的實現說明
protected:
EGLConfig_config;
EGLSurface_surface;
EGLContext_context;
EGLDisplay_display;
android_app*_app;
int_width;
int_height;
部分參數說明:
_surface:用於繪制圖形,相當於windows繪圖中的點陣圖
_context:可以看做是opengl對象
_display:用於繪圖的設備上下文,類似於windows繪圖中的dc
3.構造函數說明
CELLAndroidApp(android_app*app):_app(app) { _surface=0; _context=0; _display=0; _width=64; _height=48; app->userData=this;//用戶數據 app->onAppCmd=handle_cmd;//窗口的創建銷毀等 app->onInputEvent=handle_input;//回調函數 }
值得注意的是,這里的app中的userData,傳入用戶數據,這里直接傳入this,onAppCmd傳入的handle_cmd回調函數,onInputEvent傳入的事handle_input回調函數
4.類中函數main()說明
virtualvoidmain(intargc,char**argv)
{
intident;
intevents;
android_poll_source*source;
while(true)
{
while((ident=ALooper_pollAll(0,NULL,&events,(void**)&source))>=0)
{
if(source!=NULL)
source->process(_app,source);//有觸摸事件,調用input函數,相當於dispatchmessage
if(_app->destroyRequested!=0)
return;
}
render();
}
}
5.調用render()函數,繪制圖形。
6.初始化設備函數initDevice()
virtualvoidinitDevice()
{
constEGLintattribs[]=
{
EGL_SURFACE_TYPE,EGL_WINDOW_BIT,
EGL_BLUE_SIZE,8,
EGL_GREEN_SIZE,8,
EGL_RED_SIZE,8,
EGL_NONE
};
EGLintformat;
EGLintnumConfigs;
_display=eglGetDisplay(EGL_DEFAULT_DISPLAY);
eglInitialize(_display,0,0);
eglChooseConfig(_display,attribs,&_config,1,&numConfigs);
eglGetConfigAttrib(_display,_config,EGL_NATIVE_VISUAL_ID,&format);
ANativeWindow_setBuffersGeometry(_app->window,0,0,format);
_surface=eglCreateWindowSurface(_display,_config,_app->window,NULL);
#if0
EGLintcontextAtt[]={EGL_CONTEXT_CLIENT_VERSION,2,EGL_NONE,EGL_NONE};
_context=eglCreateContext(_display,_config,0,contextAtt);
#else
_context=eglCreateContext(_display,_config,0,0);
#endif
if(eglMakeCurrent(_display,_surface,_surface,_context)==EGL_FALSE)
{
LOGW("UnabletoeglMakeCurrent");
return;
}
eglQuerySurface(_display,_surface,EGL_WIDTH,&_width);
eglQuerySurface(_display,_surface,EGL_HEIGHT,&_height);
onCreate();
//InitializeGLstate.
glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_FASTEST);
glEnable(GL_CULL_FACE);
glShadeModel(GL_SMOOTH);
glDisable(GL_DEPTH_TEST);
glViewport(0,0,_width,_height);
glOrthof(0,_width,_height,0,-100,100);
7.繪制函數render()
virtualvoidrender()
{
if(_display==0)
{
return;
}
glClearColor(0,0,0,1);
glClear(GL_COLOR_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
if(g_arVertex.size()>=2)
{
glColor4f(1,1,1,1);
glVertexPointer(3,GL_FLOAT,0,&g_arVertex[0]);
glDrawArrays(GL_LINE_STRIP,0,g_arVertex.size());
}
eglSwapBuffers(_display,_surface);//雙緩存的交換緩沖區
}
8.編譯程序,將程序導入到模擬器中,最終運行的效果圖如下:
② android系統中,有關框架層的代碼應該在以下哪個目錄中
Google提供的Android包含了原始Android的目標機代碼,主機編譯工具、模擬環境,下載的代碼包經過解壓後(這里是Android2.2的源碼包),源代碼的第一層目錄結構如下:
|-- Makefile
|-- bionic (bionic C庫)
|-- bootable (啟動引導相關代碼)
|-- build (存放系統編譯規則及generic等基礎開發包配置)
|-- cts (Android兼容性測試套件標准)
|-- dalvik (dalvik java虛擬機)
|-- development (應用程序開發相關)
|-- external (android使用的一些開源的模組)
|-- frameworks (核心框架——java及C++語言)
|-- hardware (主要保護硬解適配層HAL代碼)
|-- libcore
|-- ndk
|-- device
|-- out (編譯完成後的代碼輸出與此目錄)
|-- packages (應用程序包)
|-- prebuilt (x86和arm架構下預編譯的一些資源)
|-- sdk (sdk及模擬器)
|-- system (文件系統庫、應用及組件——c語言)
`-- vendor (廠商定製代碼)
bionic 目錄
|-- libc (C庫)
| |-- arch-arm (ARM架構,包含系統調用匯編實現)
| |-- arch-x86 (x86架構,包含系統調用匯編實現)
| |-- bionic (由C實現的功能,架構無關)
| |-- docs (文檔)
| |-- include (頭文件)
| |-- inet
| |-- kernel (linux內核中的一些頭文件)
| |-- netbsd (?netbsd系統相關,具體作用不明)
| |-- private (?一些私有的頭文件)
| |-- stdio (stdio實現)
| |-- stdlib (stdlib實現)
| |-- string (string函數實現)
| |-- tools (幾個工具)
| |-- tzcode (時區相關代碼)
| |-- unistd (unistd實現)
| `-- zoneinfo (時區信息)
|-- libdl (libdl實現,dl是動態鏈接,提供訪問動態鏈接庫的功能)
|-- libm (libm數學庫的實現,)
| |-- alpha (apaha架構)
| |-- amd64 (amd64架構)
| |-- arm (arm架構)
| |-- bsdsrc (?bsd的源碼)
| |-- i386 (i386架構)
| |-- i387 (i387架構?)
| |-- ia64 (ia64架構)
| |-- include (頭文件)
| |-- man (數學函數,後綴名為.3,一些為freeBSD的庫文件)
| |-- powerpc (powerpc架構)
| |-- sparc64 (sparc64架構)
| `-- src (源代碼)
|-- libstdc++ (libstdc++ C++實現庫)
| |-- include (頭文件)
| `-- src (源碼)
|-- libthread_db (多線程程序的調試器庫)
| `-- include (頭文件)
`-- linker (動態鏈接器)
`-- arch (支持arm和x86兩種架構)
bootable 目錄
|-- bootloader (適合各種bootloader的通用代碼)
| `-- legacy (估計不能直接使用,可以參考)
| |-- arch_armv6 (V6架構,幾個簡單的匯編文件)
| |-- arch_msm7k (高通7k處理器架構的幾個基本驅動)
| |-- include (通用頭文件和高通7k架構頭文件)
| |-- libboot (啟動庫,都寫得很簡單)
| |-- libc (一些常用的c函數)
| |-- nandwrite (nandwirte函數實現)
| `-- usbloader (usbloader實現)
|-- diskinstaller (android鏡像打包器,x86可生產iso)
`-- recovery (系統恢復相關)
|-- edify (升級腳本使用的edify腳本語言)
|-- etc (init.rc恢復腳本)
|-- minui (一個簡單的UI)
|-- minzip (一個簡單的壓縮工具)
|-- mttils (mtd工具)
|-- res (資源)
| `-- images (一些圖片)
|-- tools (工具)
| `-- ota (OTA Over The Air Updates升級工具)
`-- updater (升級器)
build目錄
|-- core (核心編譯規則)
|-- history (歷史記錄)
|-- libs
| `-- host (主機端庫,有android 「cp」功能替換)
|-- target (目標機編譯對象)
| |-- board (開發平台)
| | |-- emulator (模擬器)
| | |-- generic (通用)
| | |-- idea6410 (自己添加的)
| | `-- sim (最簡單)
| `-- proct (開發平台對應的編譯規則)
| `-- security (密鑰相關)
`-- tools (編譯中主機使用的工具及腳本)
|-- acp (Android "acp" Command)
|-- apicheck (api檢查工具)
|-- applypatch (補丁工具)
|-- apriori (預鏈接工具)
|-- atree (tree工具)
|-- bin2asm (bin轉換為asm工具)
|-- check_prereq (檢查編譯時間戳工具)
|-- dexpreopt (模擬器相關工具,具體功能不明)
|-- droiddoc (?作用不明,java語言,網上有人說和JDK5有關)
|-- fs_config (This program takes a list of files and directories)
|-- fs_get_stats (獲取文件系統狀態)
|-- iself (判斷是否ELF格式)
|-- isprelinked (判斷是否prelinked)
|-- kcm (按鍵相關)
|-- lsd (List symbol dependencies)
|-- releasetools (生成鏡像的工具及腳本)
|-- rgb2565 (rgb轉換為565)
|-- signapk (apk簽名工具)
|-- soslim (strip工具)
`-- zipalign (zip archive alignment tool)
dalvik目錄 dalvik虛擬機
.
|-- dalvikvm (main.c的目錄)
|-- dexmp (dex反匯編)
|-- dexlist (List all methods in all concrete classes in a DEX file.)
|-- dexopt (預驗證與優化)
|-- docs (文檔)
|-- dvz (和zygote相關的一個命令)
|-- dx (dx工具,將多個java轉換為dex)
|-- hit (?java語言寫成)
|-- libcore (核心庫)
|-- libcore-disabled (?禁用的庫)
|-- libdex (dex的庫)
|-- libnativehelper (Support functions for Android's class libraries)
|-- tests (測試代碼)
|-- tools (工具)
`-- vm (虛擬機實現)
development 目錄 (開發者需要的一些常式及工具)
|-- apps (一些核心應用程序)
| |-- BluetoothDebug (藍牙調試程序)
| |-- CustomLocale (自定義區域設置)
| |-- Development (開發)
| |-- Fallback (和語言相關的一個程序)
| |-- FontLab (字型檔)
| |-- GestureBuilder (手勢動作)
| |-- NinePatchLab (?)
| |-- OBJViewer (OBJ查看器)
| |-- SdkSetup (SDK安裝器)
| |-- SpareParts (高級設置)
| |-- Term (遠程登錄)
| `-- launchperf (?)
|-- build (編譯腳本模板)
|-- cmds (有個monkey工具)
|-- data (配置數據)
|-- docs (文檔)
|-- host (主機端USB驅動等)
|-- ide (集成開發環境)
|-- ndk (本地開發套件——c語言開發套件)
|-- pdk (Plug Development Kit)
|-- samples (演示程序)
| |-- AliasActivity ()
| |-- ApiDemos (API演示程序)
| |-- BluetoothChat (藍牙聊天)
| |-- BrowserPlugin (瀏覽器插件)
| |-- BusinessCard (商業卡)
| |-- Compass (指南針)
| |-- ContactManager (聯系人管理器)
| |-- CubeLiveWall** (動態壁紙的一個簡單常式)
| |-- FixedGridLayout (像是布局)
| |-- GlobalTime (全球時間)
| |-- HelloActivity (Hello)
| |-- Home (Home)
| |-- JetBoy (jetBoy游戲)
| |-- LunarLander (貌似又是一個游戲)
| |-- MailSync (郵件同步)
| |-- MultiResolution (多解析度)
| |-- MySampleRss (RSS)
| |-- NotePad (記事本)
| |-- RSSReader (RSS閱讀器)
| |-- SearchableDictionary (目錄搜索)
| |-- **JNI (JNI常式)
| |-- SkeletonApp (空殼APP)
| |-- Snake (snake程序)
| |-- SoftKeyboard (軟鍵盤)
| |-- Wiktionary (?維基)
| `-- Wiktionary**(?維基常式)
|-- scripts (腳本)
|-- sdk (sdk配置)
|-- simulator (?模擬器)
|-- testrunner (?測試用)
`-- tools (一些工具)
③ ocostrip瀹夊崜鐗堟庝箞涓嬭澆
1銆侀栧厛鎵撳紑鎵嬫満涓婄殑搴旂敤杞浠訛紝鐐瑰嚮鎼滅儲ocostrip瀹夊崜鐗堛
2銆佺劧鍚庣偣鍑諱笅杞斤紝杈撳叆鎵嬫満鐨勮處鍙峰拰瀵嗙爜銆
3銆佹渶鍚庣偣鍑誨畨瑁咃紝鍗沖彲涓嬭澆瀹屾垚ocostrip瀹夊崜鐗堛
④ Android Makefile中是 如何識別 TARGET_PRODUCT 的
, f Q2 W8 i$ Y# i# make showcommands嵌入式開發聯盟; h; Q4 ?. m, q _5 q# f4 N這實際上等價於下面的完整命令 (具體參見 build/core/envsetup.mk ) # TARGET_ARCH=arm TARGET_PRODUCT=generic TARGET_BUILD_TYPE=release make showcommands 可見,默認情況下編譯系統認為TARGET_PRODUCT 是generic 的arm,linux,winbond,nuvoton,w90p710,w90n745,開源,嵌入式,操作系統,嵌入式開發,嵌入式聯盟,linux,ecos,uclinux,t-kernel,freeos,rtems,ucos,skyeye,6 p) P/ }+ a9 x" e' _/ ]8 l( H8 [, e那如何編譯特定產品的Android呢?arm,linux,winbond,nuvoton,w90p710,w90n745,開源,嵌入式,操作系統,嵌入式開發,嵌入式聯盟,linux,ecos,uclinux,t-kernel,freeos,rtems,ucos,skyeye,7 n N* t# q" c9 c C% W這就需要查看Android Makefile是如何解析環境變數TARGET_PRODUCT的。 Android Makefile 的引用關系是這樣的mcuos.com1 b" z& i3 S. J5 J9 TMakefile -> build/core/main.mk -> build/core/config.mk -> build/core/envsetup.mk -> build/core/proct_config.mk嵌入式開發聯盟2 t1 D) I' n) x4 /+ Q# X! D在build/core/proct_config.mk 中編譯系統首先調用 build/core/proct.mk中定義的函數get-all-proct-makefiles ,來 遍歷整個vendor 的子目錄, 找到vendor下所有的 AndroidProcts.mk, 不同子目錄下的AndroidProcts.mk 中定義了不同的 PRODUCT_NAME, PRODUCT_DEVICE 等信息,(我們也可以通過 打開build/core/proct_config.mk 中的#$(mp-procts) 語句使控制台編譯的時候輸出所有proct 的信息) , 接著build/core/proct_config.mk 會調用resolve-short-proct-name 將TARGET_PRODUCT匹配的AndroidProcts.mk 中定義的 PRODUCT_DEVICE 賦值給TARGET_DEVICE。 有了這個TARGET_DEVICE, 再回到 build/core/config.mk, 會include $(TARGET_DEVCIE)/BoardConfig.mk board_config_mk := / $(strip $(wildcard /arm,linux,winbond,nuvoton,w90p710,w90n745,開源,嵌入式,操作系統,嵌入式開發,嵌入式聯盟,linux,ecos,uclinux,t-kernel,freeos,rtems,ucos,skyeye,7 s6 h* H) @& B, X. [5 [' t" J& U $(SRC_TARGET_DIR)/board/$(TARGET_DEVICE)/BoardConfig.mk / vendor/*/$(TARGET_DEVICE)/BoardConfig.mk /- 我們只做簡潔、實用、專業的嵌入式開發技術論壇。2 L& f% E. T& M4 S) u))我們只做簡潔、專業的嵌入式開發技術論壇。5 }- ~6 j# s8 s/ a* v- iinclude $(board_config_mk)嵌入式開發聯盟, [. Z( H) L2 B; s, c而這個配置文件BoardConfig.mk 決定了目標系統編譯屬性,比如使用ALSA還是不是 GENERIC_AUDIO 等等 另外在這里TARGET_DEVICE 宏也決定了TARGET_DEVICE_DIR, 因為TARGET_DEVICE_DIR 取的是上面提到的BoardConfig.mk 的路徑。arm,linux,winbond,nuvoton,w90p710,w90n745,開源,嵌入式,操作系統,嵌入式開發,嵌入式聯盟,linux,ecos,uclinux,t-kernel,freeos,rtems,ucos,skyeye,' ~( W" a( p& y9 g- n) A: cTARGET_DEVICE_DIR := $(patsubst %/,%,$(dir $(board_config_mk))) 當然Android 的Ob目標輸出也是由TARGET_DEVICE決定,見build/core/envsetup.mk TARGET_OUT_ROOT_release := $(OUT_DIR)/target我們只做簡潔、專業的嵌入式開發技術論壇。 v( |. V7 ^+ T+ G& mTARGET_OUT_ROOT_debug := $(DEBUG_OUT_DIR)/target TARGET_OUT_ROOT := $(TARGET_OUT_ROOT_$(TARGET_BUILD_TYPE))( ?. c1 J& d) o9 M. [TARGET_PRODUCT_OUT_ROOT := $(TARGET_OUT_ROOT)/proctmcuos.com7 N! X' G9 T7 o& j+ }# |2 S. p# xPRODUCT_OUT := $(TARGET_PRODUCT_OUT_ROOT)/$(TARGET_DEVICE)嵌入式開發聯盟 P& ]2 q" C/ x: ?再回到 build/core/main.mk, 編譯系統接著做的一個件事情是,遍歷所有字目錄,找到所有Android.mk文件,並將這些Android.mk文件include 進來## Typical build; include any Android.mk files we can find.#subdir_makefiles := /我們只做簡潔、專業的嵌入式開發技術論壇。% T9 p" L4 e. O6 ?, h" @' @$(shell build/tools/findleaves.py --prune=out --prune=.repo --prune=.git $(subdirs) Android.mk)- 我們只做簡潔、實用、專業的嵌入式開發技術論壇。7 N. z& r* z; @! p5 n; {include $(subdir_makefiles)- 我們只做簡潔、實用、專業的嵌入式開發技術論壇。0 b% j5 a+ L2 E" r9 R3 v7 m我們再來看其中的 ./build/target/board/Android.mk ,對了它引用了
⑤ Android學習之Build環境介紹
這里略過對android在手機上的文件系統框架的闡述(google或者都能幫助你找到對應的信息),主要看google是如何把生成合適的rootfs的工作整合到它的build體系當中,同時,會順帶看一下CyanogenMod中對應各種機型的build機制。
首先,來看一下Android的build系統中,使用到的編譯選項和相關工具
具體的目錄在:mydroid/build/tools/下
|-- acp
這是一個稍微改良的cp命令,用來應付在windows/MAC/Linux下的cp命令的缺陷,其中的README很值得一看!
|-- adbs
這是一個用來查看crash問題的工具,詳細請看《Android調試工具之adbs》
|-- Android.mk
|-- apicheck
用來進行發布前的API檢查(參見mydroid/build/core/tasks/apicheck.mk),是否新編譯的系統中有破壞API兼容性或是非法的API
這里的代碼是用Java寫的用來檢查編譯時生成的API相關信息的xml文件(mydroid/framework/base/api/中),可以參考裡面對於xml文件解析的代碼
|-- apriori
實現prelink的工具,簡單介紹參見(mydroid/bionic/linker/README.TXT)
|-- atree
為android SDK服務的一個工具,用來按照指定xxx.atree文件中的內容進行一些文件操作
|-- bin2asm
不太明白具體的用處,應該是用來應付mac上編譯android一些與gcc相關的問題
|-- buildinfo.sh
生成target中的各種xxx.prop文件,如system.prop, build.prop等
|-- check_builds.sh
包裝了diff,用來看2個發布版本之間變化
|-- check_prereq
device上進行ota升級時的工具之一
|-- compare_fileslist.py
與check_builds.sh配合完成版本比較的腳本
|-- droiddoc
Android更具javadoc的一些移植
|-- mp-package-stats
簡單的查看一個jar/apk文件內的dex和其它文件的大小信息
|-- event_log_tags.py
處理event-log-tags的內容,關於event-log-tags文件的意義參見《Android學習之event-log-tags是神馬》
|-- fileslist.py
簡化的列出指定目錄下所有文件及大小的腳本 -- 可以放入自己的工具庫了使用:)
|-- findleaves.py
在指定目錄中(可多個)找指定文件的腳本 -- 可以放入自己的工具庫了使用:)
|-- fixlinebreaks.sh
把windows中的換行改為linux下的 -- 可以放入自己的工具庫了使用:大散蘆)
|-- fs_config
列出指定文件夾滾帶及文件的許可權
|-- fs_get_stats
得到指定文件夾下文件的簡單stats信息
|-- iself
判斷文件是否是ELF格式
|-- isprelinked
判斷文件是否是prelink過的
|-- java-event-log-tags.py
處理event-log-tags的內容,關於event-log-tags文件的意義參見《Android學習之event-log-tags是神馬》
|-- kcm
key character map的工具, 相關資料參照:
|-- lsd
!!!!!! ???
|-- merge-event-log-tags.py
處理event-log-tags的內容,關於event-log-tags文件的意掘野義參見《Android學習之event-log-tags是神馬》
|-- mktarball.sh
與fs_get_stats配合而執行的打包工具
|-- print_mole_licenses.sh
顯示當前目錄下所有mole信息
|-- releasetools
-- check_target_files_signatures
|-- common.py
|-- edify_generator.py
|-- img_from_target_files
|-- ota_from_target_files
`-- sign_target_files_apks
|-- rgb2565
rgb轉換工具
|-- signapk
命令行下對jar包簽名的工具
|-- soslim
Android定製的編譯工具之一,簡單介紹參見(mydroid/bionic/linker/README.TXT)
|-- warn.py
解析Android系統編譯log的工具
`-- zipalign
zipfile的對齊工具,參見該文件夾下的README.TXT
#p#副標題#e#
在來看看Android編譯系統中定義的一些通用XXX.mk文件
mydroid/build/core/
|-- armelflib.x
|-- armelf.x
|-- armelf.xsc
|-- base_rules.mk
|-- binary.mk
|-- build_id.mk
|-- build-system.html
|-- checktree
|-- cleanbuild.mk
|-- cleanspec.mk
|-- clear_vars.mk
|-- combo
|-- config.mk
|-- _headers.mk
|-- definitions.mk
|-- device.mk
|-- dex_preopt.mk
|-- distdir.mk
|-- droiddoc.mk
|-- mpvar.mk
|-- dynamic_binary.mk
|-- envsetup.mk
|-- executable.mk
|-- filter_symbols.sh
|-- find-jdk-tools-jar.sh
|-- help.mk
|-- host_executable.mk
|-- host_java_library.mk
|-- host_native_test.mk
|-- host_prebuilt.mk
|-- host_shared_library.mk
|-- host_static_library.mk
|-- java_library.mk
|-- java.mk
|-- legacy_prebuilts.mk
|-- main.mk
|-- Makefile
|-- multi_prebuilt.mk
|-- native_test.mk
|-- node_fns.mk
|-- notice_files.mk
|-- package.mk
|-- pathmap.mk |-- phony_package.mk
|-- prebuilt.mk
|-- process_wrapper_gdb.cmds
|-- process_wrapper_gdb.sh
|-- process_wrapper.sh
|-- proct_config.mk
|-- proct.mk
|-- proguard.flags
|-- proguard_tests.flags
|-- raw_executable.mk
|-- raw_static_library.mk
|-- root.mk
|-- shared_library.mk
|-- static_java_library.mk
|-- static_library.mk
|-- tasks
|-- user_tags.mk
`-- version_defaults.mk
#p#副標題#e#
這里,目錄在mydroid/build/core/tasks/有一些特別的task
|-- apicheck.mk, 判斷api是否符合AOSP的規范
|-- cts.mk cts測試, 可以在代碼根目錄, make cts, 編譯結束之後,進入out/host/linux-x86/bin/下,執行cts命令
|-- ide.mk IDE開發環境
|-- proct-graph.mk
`-- sdk-addon.mk
NDK的build環境沒有包含在標注難得AOSP的/build/目錄下
而是在mydroid/ndk/build下
$ cd ndk/build/tools
$ export ANDROID_NDK_ROOT=aosp-root/ndk
$ ./make-release --help
一些小技巧
如何顯示每次編譯所包含的所有xxx.mk文件
找到build/core/main.mk
把include $(subdir_makefiles)替換為
[plain] view plain $(foreach subdir_makefile, $(subdir_makefiles),
$(info Including $(subdir_makefile))
$(eval include $(subdir_makefile)))
subdir_makefile :=
如果遇見API相關的PACKAGING/checkapi-current-timestamp] Error 38
需要執行:make update-api
如何在AOSP代碼目錄之外編譯
[plain] view plain # Paths and settings
TARGET_PRODUCT = generic
ANDROID_ROOT = /home/karim/android/aosp-2.3.x
BIONIC_LIBC = $(ANDROID_ROOT)/bionic/libc
PRODUCT_OUT = $(ANDROID_ROOT)/out/target/proct/$(TARGET_PRODUCT)
CROSS_COMPILE =
$(ANDROID_ROOT)/prebuilt/linux-x86/toolchain/arm-eabi-4.4.3/bin/arm-eabi-
# Tool names
AS = $(CROSS_COMPILE)as
AR = $(CROSS_COMPILE)ar
CC = $(CROSS_COMPILE)gcc
CPP = $(CC) -E
LD = $(CROSS_COMPILE)ld
NM = $(CROSS_COMPILE)nm
OBJCOPY = $(CROSS_COMPILE)obj
OBJDUMP = $(CROSS_COMPILE)objmp
RANLIB = $(CROSS_COMPILE)ranlib
READELF = $(CROSS_COMPILE)readelf
SIZE = $(CROSS_COMPILE)size
STRINGS = $(CROSS_COMPILE)strings
STRIP = $(CROSS_COMPILE)strip
export AS AR CC CPP LD NM OBJCOPY OBJDUMP RANLIB READELF
SIZE STRINGS STRIP
# Build settings
CFLAGS = -O2 -Wall -fno-short-enums
HEADER_OPS = -I$(BIONIC_LIBC)/arch-arm/include
-I$(BIONIC_LIBC)/kernel/common
-I$(BIONIC_LIBC)/kernel/arch-arm
LDFLAGS = -nostdlib -Wl,-dynamic-linker,/system/bin/linker
$(PRODUCT_OUT)/obj/lib/crtbegin_dynamic.o
$(PRODUCT_OUT)/obj/lib/crtend_android.o
-L$(PRODUCT_OUT)/obj/lib -lc -ldl
# Installation variables
EXEC_NAME = example-app
INSTALL = install
INSTALL_DIR = $(PRODUCT_OUT)/system/bin
# Files needed for the build
OBJS = example-app.o
# Make rules
all: example-app
.c.o:
$(CC) $(CFLAGS) $(HEADER_OPS) -c {1}lt;
example-app: ${OBJS}
$(CC) -o $(EXEC_NAME) ${OBJS} $(LDFLAGS)
install: example-app
test -d $(INSTALL_DIR) || $(INSTALL) -d -m 755 $(INSTALL_DIR)
$(INSTALL) -m 755 $(EXEC_NAME) $(INSTALL_DIR)
clean:
rm -f *.o $(EXEC_NAME) core
distclean:
rm -f *~
rm -f *.o $(EXEC_NAME) core
如何增加一個新的設備
[plain] view plain $ cd ~/android/aosp-2.3.x
$ . build/envsetup.sh
$ mkdir -p device/acme/coyotepad
$ cd device/acme/coyotepad
進入AndroidProcts.mk
PRODUCT_MAKEFILES :=
$(LOCAL_DIR)/full_coyotepad.mk
對於full_coyotepad.mk
$(call inherit-proct, $(SRC_TARGET_DIR)/proct/languages_full.mk)
$(call inherit-proct, $(SRC_TARGET_DIR)/proct/full.mk)
DEVICE_PACKAGE_OVERLAYS :=
PRODUCT_PACKAGES +=
PRODUCT_COPY_FILES +=
PRODUCT_NAME := full_coyotepad
PRODUCT_DEVICE := coyotepad
PRODUCT_MODEL := Full Android on CoyotePad, meep-meep
在BoardConfig.mk中
TARGET_NO_KERNEL := true
TARGET_NO_BOOTLOADER := true
TARGET_CPU_ABI := armeabi
BOARD_USES_GENERIC_AUDIO := true
USE_CAMERA_STUB := true
打開vendorsetup.sh
add_lunch_combo full_coyotepad-eng
#p#副標題#e#
⑥ android 怎麼編譯so文件
android NDK編譯多個so文件
android編譯系統的makefile文件Android.mk寫法如下
(1)Android.mk文件首先需要指定LOCAL_PATH變數,用於查找源文件。由於一般情況下
Android.mk和需要編譯的源文件在同一目錄下,所以定義成如下形式:
LOCAL_PATH:=$(call my-dir)
上面的語句的意思是將LOCAL_PATH變數定義成本文件所在目錄路徑。
(2)Android.mk中可以定義多個編譯模塊,每個編譯模塊都是以include $(CLEAR_VARS)開始
以include $(BUILD_XXX)結束。
include $(CLEAR_VARS)
CLEAR_VARS由編譯系統提供,指定讓GNU MAKEFILE為你清除除LOCAL_PATH以外的所有LOCAL_XXX變數,
如LOCAL_MODULE,LOCAL_SRC_FILES,LOCAL_SHARED_LIBRARIES,LOCAL_STATIC_LIBRARIES等。
include $(BUILD_STATIC_LIBRARY)表示編譯成靜態庫
include $(BUILD_SHARED_LIBRARY)表示編譯成動態庫。
include $(BUILD_EXECUTABLE)表示編譯成可執行程序
(3)舉例如下(frameworks/base/libs/audioflinger/Android.mk):
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS) 模塊一
ifeq ($(AUDIO_POLICY_TEST),true)
ENABLE_AUDIO_DUMP := true
endif
LOCAL_SRC_FILES:= \
AudioHardwareGeneric.cpp \
AudioHardwareStub.cpp \
AudioHardwareInterface.cpp
ifeq ($(ENABLE_AUDIO_DUMP),true)
LOCAL_SRC_FILES += AudioDumpInterface.cpp
LOCAL_CFLAGS += -DENABLE_AUDIO_DUMP
endif
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libmedia \
libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
LOCAL_CFLAGS += -DGENERIC_AUDIO
endif
LOCAL_MODULE:= libaudiointerface
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_SRC_FILES += A2dpAudioInterface.cpp
LOCAL_SHARED_LIBRARIES += liba2dp
LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
LOCAL_C_INCLUDES += $(call include-path-for, bluez)
endif
include $(BUILD_STATIC_LIBRARY) 模塊一編譯成靜態庫
include $(CLEAR_VARS) 模塊二
LOCAL_SRC_FILES:= \
AudioPolicyManagerBase.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libmedia
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_LDLIBS += -ldl
else
LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:= libaudiopolicybase
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_CFLAGS += -DWITH_A2DP
endif
ifeq ($(AUDIO_POLICY_TEST),true)
LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
include $(BUILD_STATIC_LIBRARY) 模塊二編譯成靜態庫
include $(CLEAR_VARS) 模塊三
LOCAL_SRC_FILES:= \
AudioFlinger.cpp \
AudioMixer.cpp.arm \
AudioResampler.cpp.arm \
AudioResamplerSinc.cpp.arm \
AudioResamplerCubic.cpp.arm \
AudioPolicyService.cpp
LOCAL_SHARED_LIBRARIES := \
libcutils \
libutils \
libbinder \
libmedia \
libhardware_legacy
ifeq ($(strip $(BOARD_USES_GENERIC_AUDIO)),true)
LOCAL_STATIC_LIBRARIES += libaudiointerface libaudiopolicybase
LOCAL_CFLAGS += -DGENERIC_AUDIO
else
LOCAL_SHARED_LIBRARIES += libaudio libaudiopolicy
endif
ifeq ($(TARGET_SIMULATOR),true)
LOCAL_LDLIBS += -ldl
else
LOCAL_SHARED_LIBRARIES += libdl
endif
LOCAL_MODULE:= libaudioflinger
ifeq ($(BOARD_HAVE_BLUETOOTH),true)
LOCAL_CFLAGS += -DWITH_BLUETOOTH -DWITH_A2DP
LOCAL_SHARED_LIBRARIES += liba2dp
endif
ifeq ($(AUDIO_POLICY_TEST),true)
LOCAL_CFLAGS += -DAUDIO_POLICY_TEST
endif
ifeq ($(TARGET_SIMULATOR),true)
ifeq ($(HOST_OS),linux)
LOCAL_LDLIBS += -lrt -lpthread
endif
endif
ifeq ($(BOARD_USE_LVMX),true)
LOCAL_CFLAGS += -DLVMX
LOCAL_C_INCLUDES += vendor/nxp
LOCAL_STATIC_LIBRARIES += liblifevibes
LOCAL_SHARED_LIBRARIES += liblvmxservice
# LOCAL_SHARED_LIBRARIES += liblvmxipc
endif
include $(BUILD_SHARED_LIBRARY) 模塊三編譯成動態庫
(4)編譯一個應用程序(APK)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory-->直譯(建立在java子目錄中的所有Java文件)
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build-->直譯(創建APK的名稱)
LOCAL_PACKAGE_NAME := LocalPackage
# Tell it to build an APK-->直譯(告訴它來建立一個APK)
include $(BUILD_PACKAGE)
(5)編譯一個依賴於靜態Java庫(static.jar)的應用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# List of static libraries to include in the package
LOCAL_STATIC_JAVA_LIBRARIES := static-library
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build
LOCAL_PACKAGE_NAME := LocalPackage
# Tell it to build an APK
include $(BUILD_PACKAGE)
(6)編譯一個需要用平台的key簽名的應用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build
LOCAL_PACKAGE_NAME := LocalPackage
LOCAL_CERTIFICATE := platform
# Tell it to build an APK
include $(BUILD_PACKAGE)
(7)編譯一個需要用特定key前面的應用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Name of the APK to build
LOCAL_PACKAGE_NAME := LocalPackage
LOCAL_CERTIFICATE := vendor/example/certs/app
# Tell it to build an APK
include $(BUILD_PACKAGE)
(8)添加一個預編譯應用程序
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Mole name should match apk name to be installed.
LOCAL_MODULE := LocalMoleName
LOCAL_SRC_FILES := $(LOCAL_MODULE).apk
LOCAL_MODULE_CLASS := APPS
LOCAL_MODULE_SUFFIX := $(COMMON_ANDROID_PACKAGE_SUFFIX)
include $(BUILD_PREBUILT)
(9)添加一個靜態JAVA庫
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
# Build all java files in the java subdirectory
LOCAL_SRC_FILES := $(call all-subdir-java-files)
# Any libraries that this library depends on
LOCAL_JAVA_LIBRARIES := android.test.runner
# The name of the jar file to create
LOCAL_MODULE := sample
# Build a static jar file.
include $(BUILD_STATIC_JAVA_LIBRARY)
(10)Android.mk的編譯模塊中間可以定義相關的編譯內容,也就是指定相關的變數如下:
LOCAL_AAPT_FLAGS
LOCAL_ACP_UNAVAILABLE
LOCAL_ADDITIONAL_JAVA_DIR
LOCAL_AIDL_INCLUDES
LOCAL_ALLOW_UNDEFINED_SYMBOLS
LOCAL_ARM_MODE
LOCAL_ASFLAGS
LOCAL_ASSET_DIR
LOCAL_ASSET_FILES 在Android.mk文件中編譯應用程序(BUILD_PACKAGE)時設置此變數,表示資源文件,
通常會定義成LOCAL_ASSET_FILES += $(call find-subdir-assets)
LOCAL_BUILT_MODULE_STEM
LOCAL_C_INCLUDES 額外的C/C++編譯頭文件路徑,用LOCAL_PATH表示本文件所在目錄
舉例如下:
LOCAL_C_INCLUDES += extlibs/zlib-1.2.3
LOCAL_C_INCLUDES += $(LOCAL_PATH)/src
LOCAL_CC 指定C編譯器
LOCAL_CERTIFICATE 簽名認證
LOCAL_CFLAGS 為C/C++編譯器定義額外的標志(如宏定義),舉例:LOCAL_CFLAGS += -DLIBUTILS_NATIVE=1
LOCAL_CLASSPATH
LOCAL_COMPRESS_MODULE_SYMBOLS
LOCAL_COPY_HEADERS install應用程序時需要復制的頭文件,必須同時定義LOCAL_COPY_HEADERS_TO
LOCAL_COPY_HEADERS_TO install應用程序時復制頭文件的目的路徑
LOCAL_CPP_EXTENSION 如果你的C++文件不是以cpp為文件後綴,你可以通過LOCAL_CPP_EXTENSION指定C++文件後綴名
如:LOCAL_CPP_EXTENSION := .cc
注意統一模塊中C++文件後綴必須保持一致。
LOCAL_CPPFLAGS 傳遞額外的標志給C++編譯器,如:LOCAL_CPPFLAGS += -ffriend-injection
LOCAL_CXX 指定C++編譯器
LOCAL_DX_FLAGS
LOCAL_EXPORT_PACKAGE_RESOURCES
LOCAL_FORCE_STATIC_EXECUTABLE 如果編譯的可執行程序要進行靜態鏈接(執行時不依賴於任何動態庫),則設置LOCAL_FORCE_STATIC_EXECUTABLE:=true
目前只有libc有靜態庫形式,這個只有文件系統中/sbin目錄下的應用程序會用到,這個目錄下的應用程序在運行時通常
文件系統的其它部分還沒有載入,所以必須進行靜態鏈接。
LOCAL_GENERATED_SOURCES
LOCAL_INSTRUMENTATION_FOR
LOCAL_INSTRUMENTATION_FOR_PACKAGE_NAME
LOCAL_INTERMEDIATE_SOURCES
LOCAL_INTERMEDIATE_TARGETS
LOCAL_IS_HOST_MODULE
LOCAL_JAR_MANIFEST
LOCAL_JARJAR_RULES
LOCAL_JAVA_LIBRARIES 編譯java應用程序和庫的時候指定包含的java類庫,目前有core和framework兩種
多數情況下定義成:LOCAL_JAVA_LIBRARIES := core framework
注意LOCAL_JAVA_LIBRARIES不是必須的,而且編譯APK時不允許定義(系統會自動添加)
LOCAL_JAVA_RESOURCE_DIRS
LOCAL_JAVA_RESOURCE_FILES
LOCAL_JNI_SHARED_LIBRARIES
LOCAL_LDFLAGS 傳遞額外的參數給連接器(務必注意參數的順序)
LOCAL_LDLIBS 為可執行程序或者庫的編譯指定額外的庫,指定庫以"-lxxx"格式,舉例:
LOCAL_LDLIBS += -lcurses -lpthread
LOCAL_LDLIBS += -Wl,-z,origin
LOCAL_MODULE 生成的模塊的名稱(注意應用程序名稱用LOCAL_PACKAGE_NAME而不是LOCAL_MODULE)
LOCAL_MODULE_PATH 生成模塊的路徑
LOCAL_MODULE_STEM
LOCAL_MODULE_TAGS 生成模塊的標記
LOCAL_NO_DEFAULT_COMPILER_FLAGS
LOCAL_NO_EMMA_COMPILE
LOCAL_NO_EMMA_INSTRUMENT
LOCAL_NO_STANDARD_LIBRARIES
LOCAL_OVERRIDES_PACKAGES
LOCAL_PACKAGE_NAME APK應用程序的名稱
LOCAL_POST_PROCESS_COMMAND
LOCAL_PREBUILT_EXECUTABLES 預編譯including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)時所用,指定需要復制的可執行文件
LOCAL_PREBUILT_JAVA_LIBRARIES
LOCAL_PREBUILT_LIBS 預編譯including $(BUILD_PREBUILT)或者$(BUILD_HOST_PREBUILT)時所用, 指定需要復制的庫.
LOCAL_PREBUILT_OBJ_FILES
LOCAL_PREBUILT_STATIC_JAVA_LIBRARIES
LOCAL_PRELINK_MODULE 是否需要預連接處理(默認需要,用來做動態庫優化)
LOCAL_REQUIRED_MODULES 指定模塊運行所依賴的模塊(模塊安裝時將會同步安裝它所依賴的模塊)
LOCAL_RESOURCE_DIR
LOCAL_SDK_VERSION
LOCAL_SHARED_LIBRARIES 可鏈接動態庫
LOCAL_SRC_FILES 編譯源文件
LOCAL_STATIC_JAVA_LIBRARIES
LOCAL_STATIC_LIBRARIES 可鏈接靜態庫
LOCAL_UNINSTALLABLE_MODULE
LOCAL_UNSTRIPPED_PATH
LOCAL_WHOLE_STATIC_LIBRARIES 指定模塊所需要載入的完整靜態庫(這些精通庫在鏈接是不允許鏈接器刪除其中無用的代碼)
LOCAL_YACCFLAGS
OVERRIDE_BUILT_MODULE_PATH