月度归档:2011年08月

webkit android移植(1):开篇

看到这个标题,您可能会觉得奇怪,android浏览器本来就是基于webkit的,而且android还提供了一个非常方便的WebView及相关类。系统的浏览器当然稳定而且强大,但在某些情况下,可能还是不够,比如android浏览器不支持wml,也不支持html5 video。其实webkit本身是支持的,只不过android没有打开编译开关。另外一个原因,就是android中使用的webkit内核比较老,对于html5的支持比较差。因此萌发了自己编译libwebcore,作为独立的应用进行开发。这样做的一个缺点就是和android平台相关了,没有办法做到2.1/2.2/2.3通用。

首先说说开发环境,webkit选择android4.0版本包含的webkit。构建系统选择的是android的源码构建系统。这样选择也是为了选择一个稳定的版本,不在build system上花费太多的时间。开发机环境为ubuntu 11.10,64位系统。

阅读webkit android的代码,我们可以知道,实际上浏览器的代码包括两部分:一部分是java代码,是对webkit的一个封装,提供方便使用的WebView及相关类;一部分是c++代码,也就是webkit代码(包括WebCore和JavaScriptCore,在android 2.2之后,google用V8取代了JavaScriptCore),编译成so,供Java侧代码使用。

分析webkit的代码接口,主要需要做如下工作:

1. WTF库的移植

2. WebCore platform代码的移植

3. WebCore核心代码的移植

4. WebCore Support代码的实现

5. WebKit JNI

6. WebKit Java封装

使用CMake进行android native开发

Android NDK中提供了ndk-build脚本,以及若干mk文件,以简化ndk的开发,这对于开发一些小型应用来说足够了,但是对于一些大型项目,特别是涉及到很多第三方库时,管理起来就不是那么方便了(个人意见,Makefile写得好的人,可以无视)。在linux开源界,用得比较广泛的就是automake和cmake。本篇文章就是介绍如何使用cmake构建native程序的。

我之前写了一篇博客使用CMake构建android原生库,不过介绍的方法比较繁琐,最近在google code看到一个项目android-cmake,里面提供了脚本,这样使用起来就更方便了。下面就是介绍android-cmake的安装及使用方法。首先交代一下我的工作环境,ubuntu 10.10 32bit、Android NDK r6及Android SDK r12。接下来的步骤是:

1)下载android-cmake

    hg clone https://code.google.com/p/android-cmake/ $HOME/android/android-cmake

2)使用NDK创建单独的工具链

    export NDK=~/android/android-ndk-r6

    $NDK/build/tools/make-standalone-toolchain.sh -platform=android-5 -install-dir=$HOME/android/android-toolchain

3)将如下代码加入$HOME/.profile

    export ANDROID_NDK_TOOLCHAIN_ROOT=$HOME/android/android-toolchain

    export ANDTOOLCHAIN=$HOME/android/android-cmake/toolchain/android.toolchain.cmake

    alias android-cmake=’cmake –DCMAKE_TOOLCHAIN_FILE=$ANDTOOLCHAIN ’

android-cmake包含了若干示例,从helloworld到复杂的boost库,先从一个简单的hello-cmake开始吧。

    cd samples/hello-cmake

    mkdir androidbuild

    cd androidbuild

    android-cmake ..

    make

即可编译出libhello-cmake.so,位于libs/armeabi-v7a。可以使用cmake GUI来修改某些设置:

    cmake-gui ..

image 

注:这个例子只包含了java和jni的代码,并没有包括android工程,android工程在hello-android-cmake目录下。

在编译过程中,可能会出现如下错误:

- SWIG is not found
- The C compiler identification is GNU
- The CXX compiler identification is GNU
- Check for working C compiler: /home/alex/android/android-toolchain/bin/arm-linux-androideabi-gcc
- Check for working C compiler: /home/alex/android/android-toolchain/bin/arm-linux-androideabi-gcc — works
- Detecting C compiler ABI info
CMake Error: Could not COPY_FILE.
  OutputFile: ”
    copyFile: ‘/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeDetermineCompilerABI_C.bin’
Unable to find executable for try_compile: tried "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/cmTryCompileExec" and "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/Debug/cmTryCompileExec" and "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/Development/cmTryCompileExec".
- Detecting C compiler ABI info - done
CMake Error at /usr/share/cmake-2.8/Modules/CMakeDetermineCompilerABI.cmake:40 (FILE):
  file STRINGS file
  "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeDetermineCompilerABI_C.bin"
  cannot be read.
Call Stack (most recent call first):
  /usr/share/cmake-2.8/Modules/CMakeTestCCompiler.cmake:71 (CMAKE_DETERMINE_COMPILER_ABI)
  CMakeLists.txt:3 (project)
- Check for working CXX compiler: /home/alex/android/android-toolchain/bin/arm-linux-androideabi-g++
- Check for working CXX compiler: /home/alex/android/android-toolchain/bin/arm-linux-androideabi-g++ — works
- Detecting CXX compiler ABI info
CMake Error: Could not COPY_FILE.
  OutputFile: ”
    copyFile: ‘/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeDetermineCompilerABI_CXX.bin’
Unable to find executable for try_compile: tried "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/cmTryCompileExec" and "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/Debug/cmTryCompileExec" and "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeTmp/Development/cmTryCompileExec".
- Detecting CXX compiler ABI info - done
CMake Error at /usr/share/cmake-2.8/Modules/CMakeDetermineCompilerABI.cmake:40 (FILE):
  file STRINGS file
  "/home/alex/android/android-cmake/samples/hello-cmake/androidbuild/CMakeFiles/CMakeDetermineCompilerABI_CXX.bin"
  cannot be read.
Call Stack (most recent call first):
  /usr/share/cmake-2.8/Modules/CMakeTestCXXCompiler.cmake:64 (CMAKE_DETERMINE_COMPILER_ABI)
  CMakeLists.txt:3 (project)
- Configuring incomplete, errors occurred!

原因在于在测试编译器时,链接后的程序默认放在bin/armeabi-v7a目录下,而测试代码在另外的目录下去查找生成文件,解决的方法是修改$ANDTOOLCHAIN文件,将

set( EXECUTABLE_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH_ROOT}/bin/${ARMEABI_NDK_NAME} CACHE PATH "Output directory for applications" FORCE)

改成
set( EXECUTABLE_OUTPUT_PATH ${LIBRARY_OUTPUT_PATH_ROOT} CACHE PATH "Output directory for applications" FORCE)

补充:

在使用cmake构建webkit android porting时,出现错误:

Could NOT find BISON (missing: BISON_EXECUTABLE)

原因在于$ANDTOOLCHAIN文件中修改了CMake系统变量:

set( CMAKE_FIND_ROOT_PATH_MODE_PROGRAM ONLY )

解决的方法是将代码中这样的语句注释掉。