android中移植 c/c++程序

来源:互联网 发布:centos 7 squid 测试 编辑:程序博客网 时间:2024/05/03 23:01

android中移植 c/c++程序

   在android的linux内核中要移植 c/c++程序,一般要编译成static的,而若要运行dynamically linked的程序,则要按照android的相关机制。
Android 并没有采用glibc作为C库,而是采用了Google自己开发的Bionic Libc,它的官方Toolchain也是基于Bionic Libc而并非glibc的。
这使得使用或移植其他Toolchain来用于Android要比较麻烦:
与glibc相比,Bionic Libc有如下一些特点:
-          采用BSD License,而不是glibc的GPL License;
-          大小只有大约200k,比glibc差不多小一半,且比glibc更快;
-          实现了一个更小、更快的pthread;
-          提供了一些Android所需要的重要函数,如”getprop”, “LOGI”等;
-          不完全支持POSIX标准,比如C++ exceptions,wide chars等;
-          不提供libthread_db 和 libm的实现
另外,Android中所用的其他一些二进制工具也比较特殊:
-          加载动态库时使用的是/system/bin/linker而不是常用的/lib/ld.so;
-          prelink工具不是常用的prelink而是apriori,其源代码位于” /build/tools/apriori”
-         strip工具也没有采用常用的strip,即“/prebuilt/linux-x86/toolchain/arm-eabi-4.2.1/bin”目录下的arm-eabi-strip,
               而是位于/out/host/linux-x86/bin/的soslim工具。


===================================================================
Android编译环境 - 编译Native C的helloworld模块


    Android编译环境本身比较复杂,且不像普通的编译环境:只有顶层目录下才有Makefile文件,而其他的每个component都使用统一标准的 Android.mk.
Android.mk文件本身是比较简单的,不过它并不是我们熟悉的Makefile,而是经过了Android自身编译系统的很多处理,编写一个新的Android.mk来给
Android增加一个新的Component会比较简单。

在Android 中增加一个C程序的Hello World:
1. 在$(YOUR_ANDROID)/development 目录下创建hello目录,其中$(YOUR_ANDROID)指Android源代码所在的目录。
- # mkdir $(YOUR_ANDROID)/development/hello
2. 在$(YOUR_ANDROID)/development/hello/目录编写hello.c文件,hello.c的内容当然就是经典的HelloWorld程序:

#include <stdio.h>
int main()
{
 printf("Hello World!/n");
 return 0;
}


3. 在$(YOUR_ANDROID)/development/hello/目录编写Android.mk文件。这是Android Makefile的标准命名,不要更改。
Android.mk文件的格式和内容可以参考其他已有的Android.mk文件的写法,针对 helloworld程序的Android.mk文件内容如下:

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= /
hello.c

LOCAL_MODULE := helloworld
include $(BUILD_EXECUTABLE)

注意上面LOCAL_SRC_FILES用来指定源文件;
LOCAL_MODULE指定要编译的模块的名字,下一步骤编译时就要用到;
include $(BUILD_EXECUTABLE)表示要编译成一个可执行文件,
如果想编译成动态库则可用 BUILD_SHARED_LIBRARY,
这些可以在$(YOUR_ANDROID)/build/core/config.mk查到。


4. 回到Android源代码顶层目录进行编译:
# cd $(YOUR_ANDROID) && make helloworld
注意make helloworld中的目标名helloworld就是上面Android.mk文件中由LOCAL_MODULE指定的模块名。编译结果如下:

target thumb C: helloworld <= development/hello/hello.c
target Executable: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/LINKED/helloworld)
target Non-prelinked: helloworld (out/target/product/generic/symbols/system/bin/helloworld)
target Strip: helloworld (out/target/product/generic/obj/EXECUTABLES/helloworld_intermediates/helloworld)
Install: out/target/product/generic/system/bin/helloworld


5.如上面的编译结果所示,编译后的可执行文件存放在out/target/product/generic/system/bin/helloworld,
   通过”adb push”将它传送到模拟器上,再通过”adb shell”登录到模拟器终端,就可以执行了


===================================================================
Android编译完成后,将在根目录中生成一个out文件夹,所有生成的内容均放置在这个文件夹中。out文件夹如下所示:
  out/
  -- CaseCheck.txt
  -- casecheck.txt
  -- host
    -- common
    -- linux-x86
  -- target
    -- common
    -- product
  主要的两个目录为host和target,前者表示在主机(x86)生成的工具,后者表示目标机(默认为ARMv5)运行的内容。
  host目录的结构如下所示:
  out/host/
     -- common
        -- obj (JAVA库)
     -- linux-x86
        -- bin (二进制程序)
        -- framework (JAVA库,*.jar文件)
        -- lib (共享库*.so)
        -- obj (中间生成的目标文件)
  host目录是一些在主机上用的工具,有一些是二进制程序,有一些是JAVA的程序。
  target目录的结构如下所示:
  out/target/
  -- common
  -- R (资源文件)
  -- docs
  -- obj (目标文件)
  -- product
     -- generic
  其中common目录表示通用的内容,product中则是针对产品的内容。
  在common目录的obj中,包含两个主要的目录:
  APPS 中包含了JAVA使用程序生成的目标,每个使用程序对应其中一个子目录,将结合每个使用程序的原始文件生成Android使用程序的APK包。
  JAVA_LIBRARIES 中包含了JAVA的库,每个库对应其中一个子目录。
  在默认的情况下,Android编译将生成generic目录,如果选定产品还可以生成其他的目录。generic包含了以下内容:
  out/target/product/generic/
  -- android-info.txt
  -- clean_steps.mk
  -- data
  -- obj
  -- ramdisk.img
  -- root
  -- symbols
  -- system
  -- system.img
  -- userdata-qemu.img
  -- userdata.img
  在generic/obj/APPS目录中包含了各种JAVA使用,与common/APPS相对应,但是已经打成了APK包。
  system目录是主要的文件系统,

      data目录是存放数据的文件系统。
  obj/SHARED_LIBRARIES中存放所有动态库。
  obj/STATIC_LIBRARIES中存放所有静态库。
  多个以img为结尾的文件是多个目标映像文件,其中ramdisk是作为内存盘的根文件系统映像,system.img是主要文件系统的映像,这是一个比较大的文件,data.img是数据内容映像。这多个image文件是模拟器运行时真实需要的文件。