Ubuntu 20.04.3 LTS编译安卓2.2

最近在看《Android框架解密》,但是里面的分析是基于安卓2.2来分析的,故记录一下源码编译过程和编译过程中的问题。

1.安装git和repo并配置

安装git

sudo apt-get install git

设置git的账户名和密码

git config --global user.name "your name"
git config --global user.email "[email protected]"

新建一个文件夹用来存放源码,我为了方便的文档下新建了Android文件夹,安装配置repo,会通过repo下载源码

git clone https://aosp.tuna.tsinghua.edu.cn/git-repo/
chmod a+x git-repo/repo

完成这步之后,对应文件夹内会生成git-repo和.repo文件夹,以.开头的为隐藏文件夹
然后添加repo(路径目录如:~/git-repo/repo)到PATH环境变量

export PATH=~/git-repo:$PATH

然后到打开~/git-repo/repo文件,将REPO_URL替换为清华镜像地址,以避免下载android源码时可能出现的无法连接到 gerrit.googlesource.com问题。

REPO_URL = 'https://mirrors.tuna.tsinghua.edu.cn/git/git-repo'

2.下载源码

获取源码版本信息

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest

然后执行如下命令可以查看可以下载的android源码分支

cd .repo/manifests.git/
git branch -a

找到对应的分支名,用以下命令进行下载,我下载的是2.2

repo init -u https://aosp.tuna.tsinghua.edu.cn/platform/manifest -b 你想要下载的分支名
repo sync

接下来即可静等源码下载完成,源码体积较大,要保证你的硬盘存储充足,一般来说至少50G以上,之后编译可能会生成更多文件,可能需要更多的存储空间

3.编译准备

编译Android2.2需要下载jdk5 ,下载地址安装jdk并配置环境变量.具体可参考Ubuntu安装JDK并配置JAVA环境变量.
root权限下无法运行java命令,可参考解决Ubuntu中root权限下无法运行Java相关命令的问题.
jdk版本的切换参考Ubuntu下多个Java安装和切换

提前安装好必要的依赖

sudo apt-get install git-core gnupg flex bison gperf libsdl1.2-dev libesd0-dev squashfs-tools build-essential zip curl libncurses5-dev zlib1g-dev pngcrush schedtool libxml2 libxml2-utils xsltproc

安装Gcc 和g++ ,需要注意版本号。这里默认的版本号太高,需要降级.现在安装gcc低版本可能会找不到库,可以采取如下办法,安装gcc时出错的解决方法
可能还会报Ubuntu 安装软件报错,可参考Ubuntu 安装软件报错
安装gcc和g++

sudo apt-get install gcc-4.4
sudo apt-get install g++-4.4

然后gcc和g++降级,其实就是修改gcc的引用,之前的gcc最好做好备份,以便恢复

gcc降级:
sudo rm -rf /usr/bin/gcc
sudo ln -s /usr/bin/gcc-4.4 /usr/bin/gcc
gcc -v

g++降级
sudo rm -rf /usr/bin/g++
sudo ln -s /usr/bin/g++-4.4 /usr/bin/g++
g++ -v

4.编译源码

首先cd到应的源码目路,初始化编译环境

. build/envsetup.sh

初始化编译环境后,引入了一些执行脚本,其中就包括马上要使用的lunch指令。通过lunch指令可以设置编译目标,所谓的编译目标就是生成的镜像要运行在什么样的设备上,执行命令看看需要编译哪个

lunch

我这里选择generic-eng,选择1,或者执行以下命令

lunch generic-eng

最后,我们便可通过如下命令来开始编译andriod源码,如果提示权限不够,可用夹sudo

make -j8

4.编译中的问题

首先明确怎么解决问题

  • 一般问题都有路径,有文件路径的直接到对应文件路径去看下。其余的可用根据异常信息进行查询
  • 如果提示找不到方法多半是依赖库不全,需要去网上查一下缺少哪个依赖
/home/zoufeng/Documents/Android/source/android2.2/frameworks/base/tools/aapt/XMLNode.cpp:101: undefined reference to `pseudolocalize_string(std::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: ld returned 1 exit status

解决方案,执行以下命令
sudo apt-get install lib64z1-dev
sudo apt-get install lib32z1-dev

打开Android.mk文件
$gedit frameworks/base/tools/aapt/Android.mk
编辑下面一行:
ifeq ($(HOST_OS),linux)
#LOCAL_LDLIBS += -lrt       把这行注释掉,改为下面一行。
LOCAL_LDLIBS += -lrt -lpthread
endif
g++: selected multilib '32' not installed

参考gcc-4.4和g+±4.4无法定位安装包问题安装以下g++即可

/usr/bin/ld: /home/zoufeng/Documents/Android/source/android2.2/external/genext2fs/genext2fs.c:1745: undefined reference to `minor'
/usr/bin/ld: /home/zoufeng/Documents/Android/source/android2.2/external/genext2fs/genext2fs.c:1745: undefined reference to `major'

找到对应路径的文件,添加#include <sys/sysmacros.h>

升级了安卓ndk从r14到r15以后,项目无法编译成功。报错 undefined reference to `major'
谷歌以后发现 https://github.com/axboe/fio/issues/367 https://github.com/android-ndk/ndk/issues/398
坑爹的升级
Android's had <sys/sysmacros.h> for a long time, but in NDK r15 we're likely to have to remove the transitive include from <sys/types.h>
于是 #include <sys/sysmacros.h> 解决了这个问题

4

/bin/bash: jar:未找到命令

参考此方案也可用于jdk版本的切换Ubuntu下多个Java安装和切换把jar生成一个新的

out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/libwebcore.a(PreloadScanner.o): In function `findEntity(char const*, unsigned int)':
PreloadScanner.cpp:(.text._Z10findEntityPKcj+0x0): multiple definition of `findEntity(char const*, unsigned int)'
out/target/product/generic/obj/STATIC_LIBRARIES/libwebcore_intermediates/libwebcore.a(HTMLTokenizer.o):/home/zoufeng/Documents/Android/source/android2.2/external/webkit/WebCore/html/HTMLEntityNames.gperf:376: first defined here
collect2: ld returned 1 exit status

external/webkit/WebCore/html/文件夹下找到对应PreloadScanner.cpp文件,做如下修改

将
// Use __GNUC__ instead of PLATFORM(GCC) to stay consistent with the gperf generated c file
#ifdef __GNUC__
// The main tokenizer includes this too so we are getting two copies of the data. However, this way the code gets inlined.
#include "HTMLEntityNames.c"
#else
// Not inlined for non-GCC compilers
struct Entity {
    const char* name;
    int code;
};
const struct Entity* findEntity(register const char* str, register unsigned int len);
#endif

改为

// Use __GNUC__ instead of PLATFORM(GCC) to stay consistent with the gperf generated c file
//#ifdef __GNUC__
// The main tokenizer includes this too so we are getting two copies of the data. However, this way the code gets inlined.
//#include "HTMLEntityNames.c"
//#else
// Not inlined for non-GCC compilers
struct Entity {
    const char* name;
    int code;
};
const struct Entity* findEntity(register const char* str, register unsigned int len);
//#endif

5.运行模拟器

运行以下命令

emulator

如果提示

SDL init failure.reson is: No available video device

执行以下命令:
sudo apt-add-repository "deb http://archive.canonical.com/ $(lsb_release -sc) partner"
sudo apt-get update
sudo apt-get install libsdl1.2debian:i386

不出意外,大功告成!接下来开始源码的学习分析过程.

猜你喜欢

转载自blog.csdn.net/sinat_34388320/article/details/126045282