原文: Compile a native C Android application
翻译: Zhiwei.Li

通过上网搜索,你可以发现很多种编译Android native应用的方法.我想说的是,不同的控制台应用, 守护程序(daemon), C/C++库,等等.这些程序在你自己的计算机上
编译没有任何问题.

为了给Android编译程序,你需要ARM工具链(toolchain). 我发现有两种主张,分别是使用Android Prebuild toolchain和CodeSourcery
1)Android Prebuild toolchain
Android没有使用传统的libc库.相反,它用了Bionic库,一个由Google开发的,用在Android移动软件平台上的轻量级的libc
Bionic被裁剪到只支持 Android系统.  请看 六百万美元的c程序库

2)CodeSourcery
CodeSourcery是ARM的合作伙伴. 专门为ARM处理器开发增强GUN工具链的,并提供验证过的GNU工具链.这些工具链有很多不同的版本.
对于Android平台,需要 arm-none-linux-gnueabi, 而 arm-none-eabi是没有glibc包含在里面的,主要面向那些编译完整的native库和应用(比如FreeRTOS)
译者注: arm-none-eabi就是用来编译裸机程序的,请参考 最简单的ARM裸机程序

我个人的观点,如果白手起家开始创建一个Android的应用程序,你应该选择Bionic.
但是如果你选择从你的PC环境移植一个库到Android,你应该选择CodeSourcery
如果你使用到线程或者C++异常,Bionic库也不能完全支持它们(实际上,它根本就不支持异常)

agcc.pl是Andrew Ross开发的一个脚本,让你以一种很简单的方法来自动包含常用的库,使用Android的ARM工具链gcc
某种程度上,他像makefile

第1种方法  使用Makefile和Android NDK

AR = arm-linux-androideabi-ar
AS = arm-linux-androideabi-as
CC = arm-linux-androideabi-gcc
CXX = arm-linux-androideabi-g++
LD = arm-linux-androideabi-ld.gold NDK_KIT = /home/tim/android-ndk-r10b
PLATF_KIT = platforms/android-9 ARM_INC = $(NDK_KIT)/$(PLATF_KIT)/arch-arm/usr/include
ARM_LIB = $(NDK_KIT)/$(PLATF_KIT)/arch-arm/usr/lib OBJS = hello.o
EXES = hello hello : hello.o
$(LD) --dynamic-linker=/system/bin/linker -nostdlib \
-rpath-link=$(ARM_LIB) \
$(ARM_LIB)/crtbegin_dynamic.o \
-L$(ARM_LIB) -lc \
-o hello hello.o hello.o: hello.c
$(CC) -I $(ARM_INC) -c hello.c clean:
rm -f $(OBJS) $(EXES)

源代码

#include <stdio.h>

int main(int argc, char* argv[])
{
printf("Hello Android\n");
return 0;
}

设置环境变量 envsetup.sh

export PATH=$PATH:/home/tim/android-ndk-r10b/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin

最后,运行 make 就可以了

关于 -rpath-link选项,请参考 gcc链接选项

第二种简单方法,使用shell脚本

#!/bin/sh

OS='linux'
ANDROIDSDK='android-14' PROGDIR='/home/tim/android-ndk-r10b/' PROGDIR=`cd $PROGDIR && pwd`
ARMEABIGCC=$PROGDIR/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc
ARMEABILIB=$PROGDIR/platforms/$ANDROIDSDK/arch-arm/usr/lib
ARMEABIINC=$PROGDIR/platforms/$ANDROIDSDK/arch-arm/usr/include
ARMEABICRT="$ARMEABILIB/crtbegin_dynamic.o $ARMEABILIB/crtend_android.o" LINKER=/system/bin/linker echo "GCC:"$ARMEABIGCC "LIB:"$ARMEABILIB "LINKER":$LINKER "PARAMS:"$@
echo "CRT:"$ARMEABICRT $ARMEABIGCC $@ -Wl,-rpath-link=$ARMEABILIB,-dynamic-linker=$LINKER -L$ARMEABILIB $ARMEABICRT -I$ARMEABIINC -nostdlib -lc

保存为b
./b hello.c -o hello
就可以了

实际就是运行命令

/home/tim/android-ndk-r10b/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc \
-Wl,-rpath-link=/home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/lib,-dynamic-linker=/system/bin/linker \
-L/home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/lib \
/home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/lib/crtbegin_dynamic.o /home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/lib/crtend_android.o \
-I/home/tim/android-ndk-r10b/platforms/android-16/arch-arm/usr/include -nostdlib -lc \
hello.c -o hello

crtbegin_dynamic.o 和 crtend_android.o必须配对使用

第三种方法,用–sysroot也是可以的

#!/bin/sh

NDK=/home/tim/android-ndk-r8e
SYSROOT=$NDK/platforms/android-9/arch-arm
CC="$NDK/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --sysroot=$SYSROOT"
CFLAGS='-march=armv7-a -mfloat-abi=softfp -mfpu=neon'
LDFLAGS='-Wl,--fix-cortex-a8'
$CC $@

http://www.srombauts.fr/2011/03/06/standalone-toolchain/

#include  <stdio.h>
#include <android/log.h> #define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "hello-ndk", __VA_ARGS__)) int main(void)
{
printf("Hello from NDKn");
LOGI("Hello from NDK");
return 0;
}

果然厉害,上面这段代码都可以这样编译

./b9 -l log nl.c -o hn

用Makefile也能搞

CC  = arm-linux-androideabi-gcc
CFLAGS = -Wall -g
LDFLAGS = -llog
SRC =hello-ndk.c
OBJ =$(SRC:.c=.o)
EXE =hello-ndk all: $(SRC) $(EXE) $(EXE): $(OBJ)
$(CC) -o $@ $^ $(LDFLAGS) %.o: %.c
$(CC) -o $@ -c $< $(CFLAGS) clean:
rm -f *.o $(EXE)

编译so库也是可以,厉害

CC  = arm-linux-androideabi-gcc
CFLAGS = -Wall -g
LDFLAGS = -llog -shared
SRC =hello-ndk.c
OBJ =$(SRC:.c=.o)
EXE =libhello-ndk.so

还可以直接运行 gcc

/home/tim/android-ndk-r10/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/arm-linux-androideabi-gcc --sysroot=/home/tim/android-ndk-r10/platforms/android-3/arch-arm   -lc -lm   -g main.c -o mm

第4种方法,用ndk-build 
创建工程目录hello,然后在其下创建子目录jni
然后在jni下创建两个文件,一个是hello.c,另外一个是Android.mk,内容如下

LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:=hello.c
LOCAL_MODULE := helloworld
LOCAL_MODULE_TAGS := optional
include $(BUILD_EXECUTABLE)

其中 LOCAL_MODULE_TAGS := optional  这行可以不要

进入到hello目录下,运行下面的命令

# export NDK_PROJECT_PATH=`pwd`
# ndk-build
Compile thumb : helloworld <= hello.c Executable : helloworld Install : helloworld => libs/armeabi/helloworld

Compile a native C Android application的更多相关文章

  1. Android application testing with the Android test framework

    目录(?)[-] Android automated testing 1 How to test Android applications Tip 2 Unit tests vs functional ...

  2. android studio - 导入工程报错[Plugin with id 'com.android.application' not found]

    出错现象: 大概意思是找不到:com.android.application 插件,以上现象对于初学者来说会经常碰到,下面分析下产生的原因. 原因分析 首先来看看导入后的工程结构: 对于此工程结构,是 ...

  3. My First Android Application Project 第一个安卓应用

    一.前言: 安卓(Android):是一种基于Linux的自由及开放源代码的操作系统,主要用在移动设备上,如手机.平板电脑.其他的设备也有使用安卓操作系统,比如:电视机,游戏机.数码相机等等. 二.具 ...

  4. Failed to apply plugin [id 'com.android.application'] 和 Could not find com.android.tools.build:gradle:2.XX的最正确的解决方法

    发现android studio是真的可爱啊,上一秒还没问题可以build运行,下一秒就出错...好,你任性,你牛逼.. 说下今天又遇到的两个问题:Failed to apply plugin [id ...

  5. eclipse:File->New没有Android Application Project的解决办法

    我的Eclipse版本是:Kepler Service Release 1,截图: 解决步骤: 1.单击Window,选择Customize Perspective,如图: 2.勾选Android A ...

  6. 使用Cydia Substrate 从Native Hook Android Native世界

    同系列文章: 使用Cydia Substrate 从Native Hook Android Java世界 使用Cydia Substrate Hook Android Java世界 一.建立工程 手机 ...

  7. Professional Android Application Development

    Professional Android Application Development 访问地址 http://docs.google.com/fileview?id=0ByVHV5sjM4fNNj ...

  8. Plugin with id 'com.android.application' not found.

    构建报错: Error:(1, 0) Plugin with id 'com.android.application' not found. <a href="openFile&quo ...

  9. React Native For Android 架构初探

    版权声明:本文由王少鸣原创文章,转载请注明出处: 文章原文链接:https://www.qcloud.com/community/article/171 来源:腾云阁 https://www.qclo ...

随机推荐

  1. 自定义Drawable

    本文由 伯乐在线 - treesouth 翻译,toolate 校稿.未经许可,禁止转载! 英文出处:ryanharter.com.欢迎加入翻译小组. 我们看过一些博客文章,讲述了为什么要适时地使用自 ...

  2. Redis 客户端配置及示例

    一.redis自定义配置节点 <configSections> <section name ="RedisConfig" type="Amy.Toolk ...

  3. scjp考试准备 - 7 - Java构造器

    题目——如下代码的执行结果: class Hello{ String title; int value; public Hello(){ title += " World!"; } ...

  4. ASP.NET&AJAX&JSON - 动态读取数据

    因为之前帮WM组做了一个delivery的dashboard,大概用了3周的时间,.net也忘了差不多了,ajax和highchart表也是现学的,蛮费劲!总算也搞出来了.发帖纪录一下. 1. 前台A ...

  5. 49.关于Quartus和ISE中ROM的初始化和仿真的一些小结

    最近在玩Altera的FPGA,当我用Quartus II自带的IP核生成ROM时,出现了各种问题,于是在网上各种查资料,终于解决了我的问题.这里做一下小结,方便自己日后查阅. Quartus II ...

  6. Java Day 16

    基本数据类型包装类 Integer.MAX_VALUE  Integer.parseInt(); intValue(); valueOf(); 自动装拆箱 如果是一个字节范围,数据共享 字符串中 数值 ...

  7. Careercup - Google面试题 - 5377673471721472

    2014-05-08 22:42 题目链接 原题: How would you split a search query across multiple machines? 题目:如何把一个搜索que ...

  8. SQL SERVER中查询无主键的SQL

    --生成表 IF  EXISTS ( SELECT  name                FROM    sysobjects                WHERE   xtype = 'u' ...

  9. 【转】eclipse技巧1

    俗话说的好啊,“工于利启事,必先善其器”,如果说你的编程功底是一个枪法的话,那么强大的eclipse就是android战士们最好的武器. 这里,我们来总结eclipse的使用技巧,从而使我们的编程达到 ...

  10. VS2012配置Lua环境

    1.VS2012配置BabeLua插件 2.VS2012配置Lua 1.VS2012配置BabeLua插件 BabeLua插件简介: 安装方法: 关闭VS2012后直接安装BabeLua插件. 下载地 ...