Compile a native C Android application

原文: 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:"[email protected]
echo "CRT:"$ARMEABICRT

$ARMEABIGCC [email protected] -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 [email protected]

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 [email protected] $^ $(LDFLAGS)

%.o: %.c
    $(CC) -o [email protected] -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
时间: 2024-08-30 04:50:20

Compile a native C Android application的相关文章

Android application testing with the Android test framework

目录(?)[-] Android automated testing 1 How to test Android applications Tip 2 Unit tests vs functional tests 3 JUnit 3 4 Running tests on a server without display Test hooks into the Android framework 1 Instrumentation 2 How the Android system executes

React Native嵌入Android原生应用中

开发环境准备 首先你要搭建好React Native for Android开发环境, 没有搭建好的可以参考:React Native for Android Windows环境搭建 用Android Studio新建Android原生项目 我创建了一个名叫ReactNativeDemo的原生项目. 把React Native集成到原生项目当中 利用Windows命令行在项目根目录(ReactNativeDemo文件夹)下执行下面三行命令: npm init npm install –save

android studio - 导入工程报错[Plugin with id &#39;com.android.application&#39; not found]

出错现象: 大概意思是找不到:com.android.application 插件,以上现象对于初学者来说会经常碰到,下面分析下产生的原因. 原因分析 首先来看看导入后的工程结构: 对于此工程结构,是否有个疑问? 这是未正常同步完成的结构,Gradle Scripts下面似乎少了个 build.gradle ,上图红框部分描述清楚了是 Module: GraphicsDemo ,表示该 build.gradle 是Module的,而不是Project的.来看看一个正常的 Project+Modu

Android架构设计和软硬整合完整训练:HAL&amp;Framework&amp;Native Service&amp;Android Service&amp;Best Practice

如何理解Android架构设计的初心并开发出搭载Android系统并且具备深度定制和软硬整合能力特色产品,是本课程解决的问题. 课程以Android的五大核心:HAL.Binder.Native Service.Android Service(并以AMS和WMS为例).View System为主轴,一次性彻底掌握Android的精髓. 之所以是开发Android产品的必修课,缘起于: 1, HAL是Android Framework&Application与底层硬件整合的关键技术和必修技术: 2

Android架构设计和软硬整合:HAL&amp;Framework&amp;Native Service&amp;Android Service&amp;Best Practice

如何理解Android架构设计的初心并开发出搭载Android系统并且具备深度定制和软硬整合能力特色产品,是本课程解决的问题. 课程以Android的五大核心:HAL.Binder.Native Service.Android Service(并以AMS和WMS为例).View System为主轴,一次性彻底掌握Android的精髓. 之所以是开发Android产品的必修课,缘起于: 1, HAL是Android Framework&Application与底层硬件整合的关键技术和必修技术: 2

Android 学习笔记 3 My First Android Application

按照老师进度...First Android Application 打开Eclipse 依次点击File ->New->Android Application Project 创建一个新的Android Application工程. 注意这里选择该Android Application所需要的SDK版本,其中 Minimum Required SDK为工程最低Android版本要求 Target SDK为工程的Android目标版本 Compile With为工程的兼容版本. 点击next

Android架构设计和软硬整合完整训练:HAL&amp;Framework&amp;Native Service&amp;Android Service&amp;Best Practice

如何理解Android架构设计的初心并开发出搭载Android系统并且具备深度定制和软硬整合能力特色产品,是本课程解决的问题. 课程以Android的五大核心:HAL.Binder.Native Service.Android Service(并以AMS和WMS为例).View System为主轴,一次性彻底掌握Android的精髓. 之所以是开发Android产品的必修课,缘起于: 1,     HAL是Android Framework&Application与底层硬件整合的关键技术和必修技

王家林最受欢迎的一站式云计算大数据和移动互联网解决方案课程 V3之Android架构设计和实现完整训练:HAL&amp;Framework&amp;Native Service&amp;Android Service&amp;Best Practice

如何理解Android架构设计的初心并开发出搭载Android系统并且具备深度定制和软硬整合能力特色产品,是本课程解决的问题. 课程以Android的五大核心:HAL.Binder.Native Service.Android Service(并以AMS和WMS为例).View System为主轴,一次性彻底掌握Android的精髓. 之所以是开发Android产品的必修课,缘起于: 1,  HAL是Android Framework&Application与底层硬件整合的关键技术和必修技术:

Gradle build Android application groovy—DSL特定领域语言

前言 现在,搞APP开发居多,编译/打包等问题立即就成痛点了.一个APP有多个版本,Release版.Debug版.Test版.甚至针对不同APP Store都有不同的版本.在以前ROM的环境下,虽然可以配置Android.mk,但是需要依赖整个Android源码,而且还不能完全做到满足条件,很多事情需要手动搞.一个app如果涉及到多个开发者,手动操作必然会带来混乱. library工程我们需要编译成jar包,然后发布给其他开发者使用.以前是用eclipse的export,做一堆选择.要是能自动