IT博客汇
  • 首页
  • 精华
  • 技术
  • 设计
  • 资讯
  • 扯淡
  • 权利声明
  • 登录 注册

    Build ShakaAapt

    rover12421发表于 2015-07-30 23:50:42
    love 0

    为了提高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中编译.当然要是你有强迫症,请自行补全其他引用.



沪ICP备19023445号-2号
友情链接