只使用源码(如某些类)而不用重新编译的人可以略过此文
#######################################
配置android编译环境(for Ubuntu 10.04 64-bit)
#######################################
官方参考:http://source.android.com/source/initializing.html
网上资料:
Ubuntu 10.04下编译Android源码全过程
http://wenku.baidu.com/view/c130b16648d7c1c708a14551.html
Build android development platform in Ubuntu 10
http://wenku.baidu.com/view/042ea6fd700abb68a982fb2b.html
接着安装各种必需的软件包,如果有些包之前安装过了,可以不安装
***???*** 如果提示安装失败,可能要先安装Ubuntu重要更新???
if it failed due to dependency, try 'sudo aptitude install XXX'
instead.
1. 安装jdk
sudo add-apt-repository "deb
http://archive.canonical.com/ lucid partner"
sudo apt-get update
sudo apt-get install
sun-java6-jdk
2. sudo apt-get install git-core
3. sudo apt-get install gnupg
4. sudo apt-get install flex
5. sudo apt-get install bison
6. sudo apt-get install gperf
7. sudo apt-get install build-essential
8. sudo apt-get install zip
9. sudo apt-get install curl
10. sudo apt-get install zlib1g-dev //
注意是数字b1g是数字1,不是字母l
11. sudo apt-get install libc6-dev
12. sudo apt-get install lib32ncurses5-dev
13. sudo apt-get install ia32-libs
14. sudo apt-get install x11proto-core-dev 15. sudo apt-get install libx11-dev 16. sudo apt-get install lib32readline5-dev
17. sudo apt-get install lib32z-dev
18. sudo apt-get install libgl1-mesa-dev
19. sudo apt-get install g++-multilib
20. sudo apt-get install mingw32
21. sudo apt-get install tofrodos
22. sudo apt-get install python-markdown
23. sudo apt-get install libxml2-utils
24. sudo apt-get install xsltproc
#######################################
下载android源码
#######################################
官方参考:http://source.android.com/source/downloading.html
如果下载全部源码,确保你有一个比较快而且稳定的网络连接。
1. 下载curl, git-core:
sudo apt-get install
git-core
sudo apt-get install
curl
2. mkdir ~/bin
PATH=~/bin:$PATH
3. 下载repo
curl
https://dl-ssl.google.com/dl/googlesource/git-repo/repo >
~/bin/repo
chmod a+x ~/bin/repo
4. 创建源码放置目录,如android,然后进入此目录准备执行后续命令
mkdir android
cd android
5. 初始化repo,准备下载源码,以下是下载代码仓库里的主线(master)代码
repo init -u
https://android.googlesource.com/platform/manifest 也可以下载某个分支(branch)项目代码,如2.3.3
revision 1
repo init -u
https://android.googlesource.com/platform/manifest
-b anroid-2.3.3_r1
6. 将源代码同步到本地,这个过程很长,主线代码我下完大概占了11GB空间(汗~~)
repo sync
#######################################
编译android源码 #######################################
官方:http://source.android.com/source/building.html
***NOTICE***这种编译不会编译SDK和kernel
与Android源代码编辑相关的一切操作介绍:
http://www.cnblogs.com/jerrychoi/archive/2010/09/06/1819563.html
1. cd android
2. 初始化编译环境
source build/envsetup.sh 或 .
build/envsetup.sh
3. 选择编译模式
lunch full-eng //
除full-eng还有别的参数,见官方参考
4. 设置并行编译线程
make -j4 // 比如是一颗intel i5 4核
CPU,一个核跑一个线程,则1*4*1 = 4
# 编译android sdk
1. cd android
2. source build/envsetup.sh 或 .
build/envsetup.sh
3. make PRODUCT-sdk-sdk //
应该也可以在sdk目录下运行mm,没试过...
# 运行自己编译的emulator
在上述编译过程后,在不退出当前shell的情况下,可直接运行emulator启动
以后直接启动,可参见:
cd
~/android/prebuilts/qemu-kernel/arm
emulator -sysdir
~/android/out/target/product/generic -kernel
kernel-qemu-armv7
不过这样启动是右边是没有键盘的,不知道为什么。。。
注意:
1。 系列六里也有一些编译相关的技巧
2。 编译过程中,如果出现需要类似缺少libxxx.so这样的出错信息,请到源码主目录编译此库: make libxxx
#######################################
编译自己的Native Code
#######################################
# 在有android源码的条件下,编译自己的native代码
1.
写好自己的c/c++工程代码,放在mymodule目录,并设置好同目录下的Android.mk
比如要编译一个动态库,代码为ZPService.h和ZPService.cpp,则这样配置:
----------------------------------------------
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=ZPService.cpp // 源代码
LOCAL_SHARED_LIBRARIES:=libutils libbinder // 依赖库 LOCAL_MODULE_TAGS:=optional
// 不要忘了这行
LOCAL_MODULE:=ZPService
//
生成库名,前面不需要加lib
LOCAL_PRELINK_MODULE:=false
// 编译成库,
若编译成可执行文件,则为
// include
$(BUILD_EXECUTABLE)
include
$(BUILD_SHARED_LIBRARY)
---------------------------------------------
2. 把源代码目录mymodule放在android/development/下
3. (1)进入android根目录,运行
source
build/envsetup.sh
(2)或者,先运行source
build/envsetup.sh,再进入mymodule目录,运行
mm
4. make libZPService
5.
生成的文件将放在android/out/target/product/generic/system下的bin
或lib目录,这要视你要编成库还是可执行文件而定
# 使用下载的ndk编译自己的native代码
1. 建立工程目录ndktest, 再建立子目录jni,
在jni下放置native代码和Android.mk, 如下所示:
../ndktest
`-- jni
|-- Android.mk
`-- test.cpp
2. 进入工程主目录下, 调用ndk-build编译
zp@zp-desktop:~/ndktest$
~/android-ndk-r7/ndk-build
Compile++ thumb
: zptest <= test.cpp
StaticLibrary
: libstdc++.a
Executable : zptest
Install : zptest
=> libs/armeabi/zptest
3. 如2所示, 生成的zptest位于ndktest/libs/armeabi目录.
编译后的目录结构如下:
../ndktest
|-- jni
| |--
Android.mk
| `--
test.cpp
|-- libs
| `--
armeabi
| `-- zptest
`-- obj
`-- local
`-- armeabi
|--
libstdc++.a
|--
objs
|
`-- zptest
|
|--
test.o
|
`--
test.o.d
`--
zptest
#######################################
Run,Debug自己编译的Native Code项目
#######################################
#
在模拟器上测试自己的代码
1.
先确保自己已经有android sdk,platform,
以及platform-tools;
要在shell直接运行emulator, android,
adb等命令,请把相应的路径添加到PATH;
如果用eclipse启动emulator,然后在shell执行adb push可能会出现"out
of
memory"错误,目前解决方法是也从shell启动emulator,若还出错,加-partition-size
xxx参数,xxx为容量
2.
启动emulator.
关于如何创建模拟器见“#官方android开发介绍”
zp@zp-desktop:~/ndktest$ emulator -avd avd2.3.3
-scale 0.5
-scale选项会调整模拟器的界面大小.
3.
将自己编译的模块拷贝到virtual device
zp@zp-desktop:~$ adb push
ndktest/libs/armeabi/zptest /data
163 KB/s (8476 bytes in 0.050s)
如果要将东西拷贝到system目录,要在adb
push之前执行:
adb remount
4.
在avd上执行自己的程序
zp@zp-desktop:~$ adb shell
# /data/zptest
hello Android!
也可以在avd界面上执行, 方法是打开应用程序库 > Dev Tools >
Terminal Emulator,
在出现的控制台输入'/data/zptest'
1. 准备工作
(1)因为要调用Android源代码的framework/base里的一些类,所以要确保有android相关源代码
(2)需要交叉编译器, 链接器等工具, 这个可以使用anroid源码里提供的工具,也可以使用单独下载的android
ndk
(3)可选: 如果在模拟器(AVD)上运行和调试, 还需要有编译好或者单独下载的android sdk及相应的组件等等,
关于各种组件需求,见
这里用的环境是android源码+单独下载的SDK(包括sdk toos, sdk platform
tools和platform组件)
2.
在android源码主目录/development子目录下建立工程目录, 我们的各个模块的代码都将放在这个目录的子目录下
cd ~/android/development
mkdir zp_module
3. 建立service目录,里面放要做的native
service源码
ZPService.h
#ifndef ANDROID_ZPSERVICE_H
#define ANDROID_ZPSERVICE_H
#include
#include
#include
namespaceandroid
{
classZPService :publicBBinder
{
private:
//mutable Mutex m_Lock;
//int32_t m_NextConnId;
public:
staticintInstance();
ZPService();
virtual~ZPService();
virtualstatus_t onTransact(uint32_t,constParcel&, Parcel*, uint32_t);
};
}
#endif
ZPService.cpp
#include
#include
#include "ZPService.h"
namespaceandroid
{
//static struct sigaction oldact;
staticpthread_key_t sigbuskey;
intZPService::Instance()
{
LOGE("ZPService Instantiate\n");
intret = defaultServiceManager()->addService(
String16("zp.svc"),newZPService());
LOGE("ZPService ret = %d\n", ret);
returnret;
}
ZPService::ZPService()
{
LOGV("ZPService create\n");
//m_NextConnId = 1;
pthread_key_create(&sigbuskey,NULL);
}
ZPService::~ZPService()
{
pthread_key_delete(sigbuskey);
LOGV("ZPService destory\n");
}
status_t ZPService::onTransact(uint32_t code,
constParcel& data,
Parcel* reply,
uint32_t flags)
{
switch(code)
{
case0:
{
pid_t pid = data.readInt32();
intnum = data.readInt32();
num += 1000;
reply->writeInt32(num);
returnNO_ERROR;
} break;
default:
returnBBinder::onTransact(code, data, reply, flags);
}
}
}
Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=ZPService.cpp
LOCAL_SHARED_LIBRARIES:=libutils libbinder
LOCAL_MODULE_TAGS:=optional
LOCAL_MODULE:=libZPService
LOCAL_PRELINK_MODULE:=false
include $(BUILD_SHARED_LIBRARY)
4.
建立svcserver目录,放置server源代码,
它主要用来将我们的service注册到系统.
zpserver.cpp
#include
#include
#include
#include
#include
#include
#include
#include
#include "../service/ZPService.h"
usingnamespaceandroid;
intmain(intarg,char** argv)
{
printf("server - ain() begin\n");
sp proc(ProcessState::self());
sp sm = defaultServiceManager();
//LOGI("ServiceManager: %p\n", sm.get());
printf("server - erviceManager: %p\n", sm.get());
intret = ZPService::Instance();
printf("server - ZPService::Instance return %d\n", ret);
ProcessState::self()->startThreadPool();
Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=zpserver.cpp
LOCAL_SHARED_LIBRARIES:=libutils libbinder libZPService
LOCAL_MODULE_TAGS:=optional
LOCAL_MODULE:=zpserver
include $(BUILD_EXECUTABLE)
5.
创建svcclient目录, 放置client源代码,它用于调用service提供的服务.
它编译成一个动态库,供其他可执行程序调用, 也可以直接将它和第6步的调用程序直接编译成一个可执行文件
ZPClient.h
#ifndef ANDROID_ZPCLIENT_H
#define ANDROID_ZPCLIENT_H
namespaceandroid
{
classZPClient
{
public:
intsetN(intn);
private:
staticvoidgetZPService();
};
}
#endif
ZPClient.cpp
#include
#include
#include "ZPClient.h"
namespaceandroid
{
sp binder;
intZPClient::setN(intn)
{
getZPService();
Parcel data, reply;
data.writeInt32(getpid());
data.writeInt32(n);
LOGE("client - binder->transact()\n");
binder->transact(0, data, &reply);
intr = reply.readInt32();
returnr;
}
voidZPClient::getZPService()
{
sp sm = defaultServiceManager();
binder = sm->getService(String16("zp.svc"));
LOGE("client - etService: %p\n", sm.get());
if(binder == 0)
{
LOGW("ZPService not published, waiting...");
return;
}
}
}
Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=ZPClient.cpp
LOCAL_SHARED_LIBRARIES:=libutils libbinder
LOCAL_MODULE_TAGS:=optional
LOCAL_MODULE:=libZPClient
LOCAL_PRELINK_MODULE:=false
include $(BUILD_SHARED_LIBRARY)
6. 创建svctest目录,
在里面开发一个测试程序,调用第5步的client库提供的接口,访问我们的service
test.cpp
#include
#include "../svcclient/ZPClient.h"
usingnamespaceandroid;
intmain(intargc,char** argv)
{
ZPClient client;
intret = client.setN(2012);
printf("setN return: %d\n", ret);
return0;
}
Android.mk
LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=test.cpp
LOCAL_SHARED_LIBRARIES:=libZPClient
LOCAL_MODULE_TAGS:=optional
LOCAL_MODULE:=svctest
include $(BUILD_EXECUTABLE)
完成以上几步后,
我们的工程的目录结构如下(zp_module的父目录是development):
zp_module/
|-- Android.mk
|-- service
| |-- Android.mk
| |-- ZPService.cpp
| `-- ZPService.h
|-- svcclient
| |-- Android.mk
| |-- ZPClient.cpp
| `-- ZPClient.h
|-- svcserver
| |-- Android.mk
| `-- zpserver.cpp
`-- svctest
|-- Android.mk
`-- test.cpp
7. 编译所有项目
第一种方法, 进入android源码主目录,运行
source build/envsetup.sh 或 . build/envsetup.sh
然后进入development下你的源代码的各个子目录,
根据信赖性先后依次编译各个项目,比如进入development/zp_module/service, 运行 mm
第二种方法, 在zp_module下创建一个Android.mk文件, 输入以下内容:
include $(call all-subdir-makefiles
然后直接在zp_module目录下运行mm
8. 在模拟器里调试编译好的东西
(1) 打开emulator
emulator -avd avd4.0.3 -scale 0.6 -partition-size 256
(2) 打开adb, 等avd就绪后(用adb get-state查看状态,为device即准备好),
将编译好的库和可执行程序送入模拟器
zp@zp-desktop:~$ adb remount
remount succeeded
zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/lib/libZPService.so /system/lib
210 KB/s (10216 bytes in 0.047s)
zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/lib/libZPClient.so /system/lib
122 KB/s (5516 bytes in 0.044s)
zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/bin/zpserver /data
124 KB/s (5572 bytes in 0.043s)
zp@zp-desktop:~$ adb push /home/zp/android/out/target/product/generic/system/bin/svctest /data
121 KB/s (5568 bytes in 0.044s)
(3) 进入模拟器shell,先后运行zpserver和svctest
zp@zp-desktop:~$ adb shell
# /data/zpserver
server - ain() begin
server - erviceManager: 0xaa88
server - ZPService::Instance return 0
zp@zp-desktop:~$ adb shell
# /data/svctest
setN return: 3012
#
证明一切正确.