文档章节

Compile a native C Android application

ruigal
 ruigal
发布于 2016/02/29 18:01
字数 1054
阅读 34
收藏 2

http://www.cnblogs.com/GoAhead/p/4186707.html

通过上网搜索,你可以发现很多种编译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

本文转载自:http://www.cnblogs.com/GoAhead/p/4186707.html

共有 人打赏支持
ruigal
粉丝 2
博文 49
码字总数 35801
作品 0
浦东
to update Andrioid SDK Tools to revision 15

According to http://developer.android.com/sdk/android-4.0.3.html ------------------------------------------ The Android 4.0.3 API is assigned an integer identifier—15—that is......

markchen
2012/02/17
0
0
React Native 轻松集成统计功能(Android 篇)

关于推送的集成请参考这篇文章,本篇文章将引导你集成统计功能,只需要简单的三个步骤就可以集成统计功能。 第一步 安装 在你的项目路径下执行命令: 执行完上述命令后,使用 Android Studio...

极光推送
2017/11/06
0
0
Cordova 3.x 基础(1) -- 环境搭建(Windows / Android)

Cordova 3.x 基础(1) -- 环境搭建(Windows / Android) Mobile App分为三大类:Native App,Hybrid App,Web App。其中Hybrid App介于Native App和Web App之间,它能兼顾Native App的良好用...

youxizhe
2014/09/29
0
0
Android 2.3 NDK的新特性

This release of the NDK includes many new APIs, most of which are introduced to support the development of games and similar applications that make extensive use of native code.......

晨曦之光
2012/03/13
0
0
rust on android

Is it possible to write a GUI Android app in rust? (self.rust) submitted 4 months ago by rmc Hi all, I'm new to rust, so forgive me if this is a really simple question, but is i......

MtrS
2015/03/14
0
1

没有更多内容

加载失败,请刷新页面

加载更多

学习设计模式——命令模式

任何模式的出现,都是为了解决一些特定的场景的耦合问题,以达到对修改封闭,对扩展开放的效果。命令模式也不例外: 命令模式是为了解决命令的请求者和命令的实现者之间的耦合关系。 解决了这...

江左煤郎
32分钟前
1
0
字典树收集(非线程安全,后续做线程安全改进)

将500W个单词放进一个数据结构进行存储,然后进行快速比对,判断一个单词是不是这个500W单词之中的;来了一个单词前缀,给出500w个单词中有多少个单词是该前缀. 1、这个需求首先需要设计好数据结...

算法之名
昨天
7
0
GRASP设计模式

此文参考了这篇博客,建议读者阅读原文。 面向对象(Object-Oriented,OO)是当下软件开发的主流方法。在OO分析与设计中,我们首先从问题领域中抽象出领域模型,在领域模型中以适当的粒度归纳...

克虏伯
昨天
0
0
Coding and Paper Letter(四十)

资源整理。 1 Coding: 1.Tomislav Hengl撰写的非官方作者指南:Michael Gould•Wouter Gerritsma。 UnofficialGuide4Authors 2.R语言包rwrfhydro,社区贡献的工具箱,用于管理,分析和可视化...

胖胖雕
昨天
0
0
JAVA 内存回收

参考:https://www.cnblogs.com/leesf456/p/5218594.html 1,JMV 中哪些可以作为 GC Root? 1. 虚拟机栈(栈帧中的局部变量区,也叫做局部变量表)中引用的对象。 2. 方法区中的类静态属性引...

Carlyle_Lee
昨天
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部