为了提高ShakaApktool
的兼容性,需要订制一个aapt
,我称它为ShakaAapt
.这篇文章主要是记录ShakaAapt
的编译过程,以及搭建ShakaAapt
的修改环境.
为了编译aapt
你需要下载一份Android源码.最好是最新的.你可以完整编译Android源码来得到aapt
.但是这不是我的目的.我的目的是用最少的依赖来编译我的ShakaAapt
,以减少编译时间,加快以后修改代码测试速度.
Linux/Windows版本的ShakaAapt
都在ubunut
下编译.Mac Os
的版本我在虚拟机上安装的YOSEMITE
上编译.
先来假设几个条件 :
$RootDir/
: 整个环境的根目录
$RootDir/android-last/
: 最新版本的android源码目录.repo下载的源码就是这个目录.
$RootDir/ShakaAapt/
: ShakaAapt相关源文件,配置文件,等等.
$RootDir/ShakaAaptBin/
: 用来存放编译好的ShakaAapt二进制文件,也就是用到ShakaApktool
里面的文件
Ubuntu下编译Linux和windows版本
参考https://source.android.com/source/initializing.html
安装必要的依赖.
准备ShakaAapt
相关文件.在linux上使用软链接的方式:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
cd $RootDir /ShakaAapt/
ln -s ../android-last/build
mkdir development
mkdir external
mkdir frameworks
ln -s ../android-last/libcore
ln -s ../android-last/libnativehelper/
ln -s ../android-last/Makefile
ln -s ../android-last/prebuilts
mkdir sdk
mkdir system
cd development
../../android-last/development/build
cd ../external
ln -s ../../android-last/external/compiler-rt
ln -s ../../android-last/external/expat
ln -s ../../android-last/external/libcxx
ln -s ../../android-last/external/libcxxabi
ln -s ../../android-last/external/libpng
ln -s ../../android-last/external/zlib
cd ../frameworks
mkdir base
mkdir native
cd base
mkdir include
mkdir libs
mkdir tools
cd include
ln -s ../../../../android-last/frameworks/base/include/androidfw
cd ../libs
ln -s ../../../../android-last/frameworks/base/libs/androidfw
cd ../tools
ln -s ../../../../android-last/frameworks/base/tools/aapt
cd ../../native
ln -s ../../../android-last/frameworks/native/include
cd ../../sdk
ln -s ../../android-last/sdk/build
cd ../system
ln -s ../../android-last/system/core
cd ../..
看看完整的目录树:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
$RootDir /ShakaAapt> tree -L 4
.
├── build -> ../android-last/build
├── development
│ └── build -> ../../android-last/development/build
├── external
│ ├── compiler-rt -> ../../android-last/external/compiler-rt
│ ├── expat -> ../../android-last/external/expat
│ ├── libcxx -> ../../android-last/external/libcxx
│ ├── libcxxabi -> ../../android-last/external/libcxxabi
│ ├── libpng -> ../../android-last/external/libpng
│ └── zlib -> ../../android-last/external/zlib
├── frameworks
│ ├── base
│ │ ├── include
│ │ │ └── androidfw -> ../../../../android-last/frameworks/base/include/androidfw
│ │ ├── libs
│ │ │ └── androidfw -> ../../../../android-last/frameworks/base/libs/androidfw
│ │ └── tools
│ │ └── aapt -> ../../../../android-last/frameworks/base/tools/aapt
│ └── native
│ └── include -> ../../../android-last/frameworks/native/include
├── libcore -> ../android-last/libcore
├── libnativehelper -> ../android-last/libnativehelper/
├── Makefile -> ../android-last/Makefile
├── prebuilts -> ../android-last/prebuilts
├── sdk
│ └── build -> ../../android-last/sdk/build
└── system
└── core -> ../../android-last/system/core
比起完整的Android代码,这个代码量是不是很少了啊.
下面是编译脚本的编写.看文件名就知道是干嘛的,就不做太多的解释了.
$RootDir/build_ShakaAapt_linux-x86.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#! /bin/bash
cd ShakaAapt
export USE_CCACHE = 1
export CCACHE_DIR = $( pwd ) /.ccache
prebuilts/misc/linux-x86/ccache/ccache -M 50G
. build/envsetup.sh
lunch sdk-eng
OUT_DIR = out-x86 make LOCAL_MULTILIB = 32 aapt -j4
strip out-x86/host/linux-x86/bin/aapt
strip out-x86/host/linux-x86/lib/libc++.so
mkdir -p ../ShakaAaptBin/linux-x86/bin
mkdir -p ../ShakaAaptBin/linux-x86/lib
cp out-x86/host/linux-x86/bin/aapt ../ShakaAaptBin/linux-x86/bin/aapt
cp out-x86/host/linux-x86/lib/libc++.so ../ShakaAaptBin/linux-x86/lib/libc++.so
$RootDir/build_ShakaAapt_linux-x86_64.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#! /bin/bash
cd ShakaAapt
export USE_CCACHE = 1
export CCACHE_DIR = $( pwd ) /.ccache
prebuilts/misc/linux-x86/ccache/ccache -M 50G
. build/envsetup.sh
lunch sdk-eng
OUT_DIR = out-x86_64 make LOCAL_MULTILIB = 64 aapt -j4
strip out-x86_64/host/linux-x86/bin/aapt
strip out-x86_64/host/linux-x86/lib64/libc++.so
mkdir -p ../ShakaAaptBin/linux-x86_64/bin
mkdir -p ../ShakaAaptBin/linux-x86_64/lib64
cp out-x86_64/host/linux-x86/bin/aapt ../ShakaAaptBin/linux-x86_64/bin/aapt
cp out-x86_64/host/linux-x86/lib64/libc++.so ../ShakaAaptBin/linux-x86_64/lib64/libc++.so
$RootDir/build_ShakaAapt_windows-x86.sh
1
2
3
4
5
6
7
8
9
10
11
12
#! /bin/bash
cd ShakaAapt
export USE_CCACHE = 1
export CCACHE_DIR = $( pwd ) /.ccache
prebuilts/misc/linux-x86/ccache/ccache -M 50G
. build/envsetup.sh
lunch sdk-eng
USE_MINGW = 1 OUT_DIR = out-x86 LOCAL_MULTILIB = 32 make aapt
strip out-x86/host/windows-x86/bin/aapt.exe
mkdir -p ../ShakaAaptBin/windows-x86/bin
cp out-x86/host/windows-x86/bin/aapt.exe ../ShakaAaptBin/windows-x86/bin/aapt.exe
这里用ccache
来加快编译速度.如果你不想要ccache
,可以把相关位置去掉.也就是下面3行
1
2
3
export USE_CCACHE = 1
export CCACHE_DIR = $( pwd ) /.ccache
prebuilts/misc/linux-x86/ccache/ccache -M 50G
更多关于ccache
请查看:https://source.android.com/source/building-running.html#using-ccache
脚本编写好了,需要编译那个平台的aapt
就执行对应平台的脚本.
注意,编译windows
平台,需要另外安装一些依赖包:
sudo apt-get install mingw32 tofrodos
windows版本,目前还不支持64bit的编译.不用纠结这个了,现在sdk中的全是x86的.
虚拟机中编译MacOs版本
首先是环境设定,Mac Os默然的文件系统是不区分大小写的,但是Android源码是要求区分大小写的.
可以参考https://source.android.com/source/initializing.html#setting-up-a-mac-os-x-build-environment
来创建一块区分大小写的磁盘镜像,然后把源码拷贝到这个磁盘镜像中.
我用的是虚拟机,所以我选择了添加一块区分大小写敏感的硬盘.这里就不详细解说了.
同样的,我不需要全部的源码,下面是我写的一个编译ShakaAapt
所需全部源码的同步脚本
注意,接下来的$RootDir
全是MacOs上的根目录了.
$RootDir/rsync_ShakaApktool.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#! /bin/bash
SRCROOT = "/Volumes/VMware Shared Folders/Develop/android/source/android-last"
DESROOT = "/Volumes/OSXShareDisk/Develop/android/source/ShakaAapt"
rsync -aP "$SRCROOT/Makefile" "$DESROOT/Makefile"
array =( \
build libnativehelper prebuilts \
development/build \
frameworks/base/include \
frameworks/base/tools/aapt \
frameworks/base/libs/androidfw \
frameworks/native/include \
external/compiler-rt \
external/expat \
external/libcxx \
external/libcxxabi \
external/libpng \
external/zlib \
sdk/build \
system/core \
)
for var in ${ array [@] } ;do
echo $var
mkdir -p "$DESROOT/$var/"
rsync -aP --delete \
--exclude .git \
"$SRCROOT/$var/" "$DESROOT/$var/"
done
$SRCROOT
: 从目录名称上可以看出,这个目录是共享Ubuntu的目录,这个目录就是Ubuntu
上存放Android源码的目录.
DESROOT
: 是挂着的另外一块区分大小写的MacOs分区.
目录结果和Ubuntu上是相同的.从上面的脚本可以看出,我这里的$RootDir
目录实际是/Volumes/OSXShareDisk/Develop/android/source
如果源码没更新,只修改了部分aapt
的源码,再次同步也可以只同步aapt
相关的源码就行了,加快同步速度.
$RootDir/rsync_ShakaApktool_only_aapt.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#! /bin/bash
SRCROOT = "/Volumes/VMware Shared Folders/Develop/android/source/android-last"
DESROOT = "/Volumes/OSXShareDisk/Develop/android/source/ShakaAapt"
rsync -aP "$SRCROOT/Makefile" "$DESROOT/Makefile"
array =( \
frameworks/base/tools/aapt \
)
for var in ${ array [@] } ;do
echo $var
mkdir -p "$DESROOT/$var/"
rsync -aP --delete \
--exclude .git \
"$SRCROOT/$var/" "$DESROOT/$var/"
done
源码同步过后,就是编译了,一样的,先写编译脚本,避免每次都执行一堆命令.
$RootDir/build_ShakaAapt_maxos-x86.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
#! /bin/bash
cd ShakaAapt
export USE_CCACHE = 1
export CCACHE_DIR = $( pwd ) /.ccache
prebuilts/misc/darwin-x86/ccache/ccache -M 50G
. build/envsetup.sh
lunch sdk-eng
OUT_DIR = out-x86 make LOCAL_MULTILIB = 32 aapt -j4
mkdir -p "/Volumes/VMware Shared Folders/Develop/android/source/ShakaAaptBin/darwin-x86/bin"
mkdir -p lib "/Volumes/VMware Shared Folders/Develop/android/source/ShakaAaptBin/darwin-x86/lib"
cp out-x86/host/darwin-x86/bin/aapt "/Volumes/VMware Shared Folders/Develop/android/source/ShakaAaptBin/darwin-x86/bin/aapt"
cp out-x86/host/darwin-x86/lib/libc++.dylib "/Volumes/VMware Shared Folders/Develop/android/source/ShakaAaptBin/darwin-x86/lib/libc++.dylib"
$RootDir/build_ShakaAapt_maxos-x86_64.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
#! /bin/bash
cd ShakaAapt
export USE_CCACHE = 1
export CCACHE_DIR = $( pwd ) /.ccache
prebuilts/misc/darwin-x86/ccache/ccache -M 50G
. build/envsetup.sh
lunch sdk-eng
OUT_DIR = out-x86_64 make LOCAL_MULTILIB = 64 aapt -j4
mkdir -p "/Volumes/VMware Shared Folders/Develop/android/source/ShakaAaptBin/darwin-x86_64/bin"
mkdir -p "/Volumes/VMware Shared Folders/Develop/android/source/ShakaAaptBin/darwin-x86_64/lib64/"
cp out-x86_64/host/darwin-x86/bin/aapt "/Volumes/VMware Shared Folders/Develop/android/source/ShakaAaptBin/darwin-x86_64/bin/aapt"
cp out-x86_64/host/darwin-x86/lib64/libc++.dylib "/Volumes/VMware Shared Folders/Develop/android/source/ShakaAaptBin/darwin-x86_64/lib64/libc++.dylib"
执行相应的脚本就可以编译了.
使用Clion查看修改aapt源码的配置
我觉得用Clion
来查看修改aapt
的源码还是很爽的.
先创建一个项目,然后在项目目录下用软链接链接源码,windows平台没有软链接,建议在用Linux/Unix平台下使用.
1
2
3
4
5
6
7
8
cd $ClionProject
ln -s $RootDir /android-last/frameworks/base/tools/aapt
mkdir include
mkdir libs
cd include
ln -s $RootDir /android-last/frameworks/base/include/androidfw
cd ../libs
ln -s $RootDir /android-last/frameworks/base/libs/androidfw
看下目录树:
1
2
3
4
5
6
7
8
$ClionProject > tree -L 2
.
├── aapt -> $RootDir /android-last/frameworks/base/tools/aapt
├── CMakeLists.txt
├── include
│ └── androidfw -> $RootDir /android-last/frameworks/base/include/androidfw
└── libs
└── androidfw -> $RootDir /android-last/frameworks/base/libs/androidfw
修改CMakeLists.txt
文件:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
cmake_minimum_required ( VERSION 3.2 )
project ( ShakaAapt )
set ( CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11" )
set ( AAPTROOT aapt )
set ( aaptMain ${ AAPTROOT } /Main.cpp )
set ( aaptSources
${ AAPTROOT } /AaptAssets.cpp
${ AAPTROOT } /AaptConfig.cpp
${ AAPTROOT } /AaptUtil.cpp
${ AAPTROOT } /AaptXml.cpp
${ AAPTROOT } /ApkBuilder.cpp
${ AAPTROOT } /Command.cpp
${ AAPTROOT } /CrunchCache.cpp
${ AAPTROOT } /FileFinder.cpp
${ AAPTROOT } /Images.cpp
${ AAPTROOT } /Package.cpp
${ AAPTROOT } /pseudolocalize.cpp
${ AAPTROOT } /Resource.cpp
${ AAPTROOT } /ResourceFilter.cpp
${ AAPTROOT } /ResourceIdCache.cpp
${ AAPTROOT } /ResourceTable.cpp
${ AAPTROOT } /SourcePos.cpp
${ AAPTROOT } /StringPool.cpp
${ AAPTROOT } /WorkQueue.cpp
${ AAPTROOT } /XMLNode.cpp
${ AAPTROOT } /ZipEntry.cpp
${ AAPTROOT } /ZipFile.cpp
)
set ( LIB_androidfw_ROOT libs/androidfw )
set ( LIB_androidfw_commonSources
${ LIB_androidfw_ROOT } /Asset.cpp
${ LIB_androidfw_ROOT } /AssetDir.cpp
${ LIB_androidfw_ROOT } /AssetManager.cpp
${ LIB_androidfw_ROOT } /misc.cpp
${ LIB_androidfw_ROOT } /ObbFile.cpp
${ LIB_androidfw_ROOT } /ResourceTypes.cpp
${ LIB_androidfw_ROOT } /StreamingZipInflater.cpp
${ LIB_androidfw_ROOT } /TypeWrappers.cpp
${ LIB_androidfw_ROOT } /ZipFileRO.cpp
${ LIB_androidfw_ROOT } /ZipUtils.cpp )
set ( SOURCE_FILES ${ SOURCE_FILES }
${ aaptMain }
${ aaptSources }
${ LIB_androidfw_commonSources }
)
include_directories ( ${ AAPTROOT } )
include_directories ( include )
#set(SOURCE_FILES main.cpp)
add_executable ( ShakaAapt ${ SOURCE_FILES } )
现在就可以很舒服的修改aapt
源码了,虽然很多引用没有,但是aapt
相关部分源码已经可以正常跳转,查找引用了.这就足够了,反正也不是在clion
中编译.当然要是你有强迫症,请自行补全其他引用.