通常要把我们自己的的代码编译成在android里面编译的可执行文件,我们通常是建一个文件夹

.
├── Android.mk
├── Application.mk
├── convolve.cl
├── convolve_cl.cpp
├── convolve_cl.cpp~
├── inter_ocl
│   └── opencl
│   ├── CL
│   │   ├── cl_ext.h
│   │   ├── cl.h
│   │   ├── cl_platform.h
│   │   └── opencl.h
│   ├── clew.c
│   ├── clew.h
│   ├── ocl_wrapper.c
│   └── ocl_wrapper.h
└── mylog.h

类似这样,里面有android.mk 文件,然后进入到这个文件夹执行ndk-build,生成文件如下:

[armeabi-v7a] Install        : convolve-ocl => libs/armeabi-v7a/convolve-ocl
[armeabi-v7a] Install : libstlport_shared.so => libs/armeabi-v7a/libstlport_shared.so

但是今天我们要修改上一章的模板makefile来编译可以在android中执行的可执行文件。

首先我们还是用之前的三个文件hellomake.c, hellofunc.c, hellofunc.h,文件树如下:

.
├── makefile
├── makefile1
└── src
├── hellofunc.c
├── hellofunc.h
└── hellomake.c

因为要用到android的交叉编译器,所以不能用gcc,另外寻找头文件的系统路径也不一样,寻找库的路径也和linux原本的不同,所以 -I 和 -L的路径也需要修改

修改之后的makefile如下:

#Hellomake
#Magnum, 2014-10-19
# 指令编译器和选项
TOOLCHAINS_ROOT=$(NDK_HOME)/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)/bin/arm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/4.8/include-fixed

PLATFORM_ROOT=$(NDK_HOME)/platforms/android-17/arch-arm
NDKINC=$(PLATFORM_ROOT)/usr/include
NDKLIB=$(PLATFORM_ROOT)/usr/lib

CC=$(TOOLCHAINS_PREFIX)-gcc
CFLAGS=-Wall 
# 需要链接库的库名,比如libm.a,就是-lm,需要去掉前面的lib和后面的.a
LIBS=-lm 
# 设置默认搜索头文件的路径,优先是这个,然后是系统路径
IncludeDir = -I./include/ -I$(NDKINC)
# 需要链接的库的路径
LinkDir = -L$(NDKINC)
OBJ_DIR = ./obj
BIN_DIR = ./bin

#PROJECT_TOP_DIR设置成pwd 或者"./"都行
PROJECT_TOP_DIR=.#$(shell pwd)#$(shell cd ../; pwd)
PROJECT_BIN_DIR=$(PROJECT_TOP_DIR)/bin
PROJECT_SRC_DIR=$(PROJECT_TOP_DIR)/src
PROJECT_LIB_DIR=$(PROJECT_TOP_DIR)/lib
PROJECT_OBJ_DIR=$(PROJECT_TOP_DIR)/objs
MKDIR := mkdir -p

# 目标文件
EXE_NAME=hellomake
TARGET=$(BIN_DIR)/$(EXE_NAME)

#源文件的文件类型
FILE_TYPE=c
src=$(wildcard $(PROJECT_SRC_DIR)/*.$(FILE_TYPE))
dir= $(notdir $(src))
PROJECT_OBJ= $(patsubst %.$(FILE_TYPE),%.o,$(dir) )
PROJECT_ALL_OBJS= $(addprefix $(PROJECT_OBJ_DIR)/, $(PROJECT_OBJ))

all: chdir $(TARGET)

$(TARGET): $(PROJECT_ALL_OBJS)
$(CC) $(CFLAGS) -o $@ $^ $(LinkDir) $(LIBS)

chdir:
@if test ! -d $(PROJECT_OBJ_DIR) ; \
then \
mkdir $(PROJECT_OBJ_DIR) ; \
fi

@if test ! -d $(PROJECT_BIN_DIR) ; \
then \
mkdir $(PROJECT_BIN_DIR) ; \
fi

.PHONY : clean
clean:
-rm -rf $(PROJECT_BIN_DIR) $(PROJECT_OBJ_DIR)

$(PROJECT_OBJ_DIR)/%.o:$(PROJECT_SRC_DIR)/%.$(FILE_TYPE)
$(CC) $(CFLAGS) -o $@ -c $< $(IncludeDir)

执行make, 报错:

/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64//bin/arm-linux-androideabi-gcc -Wall  -o objs/hellofunc.o -c src/hellofunc.c -I./include/ -I/home/magnum/work-environment/android-ndk-r9d/platforms/android-17/arch-arm/usr/include
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64//bin/arm-linux-androideabi-gcc -Wall -o objs/hellomake.o -c src/hellomake.c -I./include/ -I/home/magnum/work-environment/android-ndk-r9d/platforms/android-17/arch-arm/usr/include
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64//bin/arm-linux-androideabi-gcc -Wall -o bin/hellomake objs/hellofunc.o objs/hellomake.o -L/home/magnum/work-environment/android-ndk-r9d/platforms/android-17/arch-arm/usr/include -lm
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtbegin_dynamic.o: No such file or directory
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: cannot open crtend_android.o: No such file or directory
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lm
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lc
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: cannot find -ldl
objs/hellofunc.o:hellofunc.c:function myPrintHelloMake: error: undefined reference to 'puts'
objs/hellomake.o:hellomake.c:function main: error: undefined reference to 'log'
objs/hellomake.o:hellomake.c:function main: error: undefined reference to 'printf'
collect2: error: ld returned exit status
make: *** [bin/hellomake] Error

进入到objs目录,发现.o文件生成成功,所以问题应该是出现在链接的时候。

crtbegin_dynamic.o: No such file or directory  和
crtend_android.o: No such file or directory 错误,

需要修改:

CFLAGS=-Wall -nostdlib .  然后执行make,错误只剩下:

/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64//bin/arm-linux-androideabi-gcc -Wall -nostdlib  -o bin/hellomake objs/hellofunc.o objs/hellomake.o -L/home/magnum/work-environment/android-ndk-r9d/platforms/android-17/arch-arm/usr/include -lm
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.8/../../../../arm-linux-androideabi/bin/ld: error: cannot find -lm
objs/hellofunc.o:hellofunc.c:function myPrintHelloMake: error: undefined reference to 'puts'
objs/hellomake.o:hellomake.c:function main: error: undefined reference to 'log'
objs/hellomake.o:hellomake.c:function main: error: undefined reference to 'printf'
collect2: error: ld returned exit status
make: *** [bin/hellomake] Error

不好意思,这个是因为

LinkDir = -L$(NDKINC),  这里复制后并没有修改,应该是LinkDir = -L$(NDKLIB),这个可以解决然后

undefined reference to 'log'

执行make,还是有一个错误:

/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64//bin/arm-linux-androideabi-gcc -Wall -nostdlib  -o objs/hellofunc.o -c src/hellofunc.c -I./include/ -I/home/magnum/work-environment/android-ndk-r9d/platforms/android-17/arch-arm/usr/include
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64//bin/arm-linux-androideabi-gcc -Wall -nostdlib -o objs/hellomake.o -c src/hellomake.c -I./include/ -I/home/magnum/work-environment/android-ndk-r9d/platforms/android-17/arch-arm/usr/include
/home/magnum/work-environment/android-ndk-r9d/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64//bin/arm-linux-androideabi-gcc -Wall -nostdlib -o bin/hellomake objs/hellofunc.o objs/hellomake.o -L/home/magnum/work-environment/android-ndk-r9d/platforms/android-17/arch-arm/usr/lib -lm -ldl
objs/hellofunc.o:hellofunc.c:function myPrintHelloMake: error: undefined reference to 'puts'
objs/hellomake.o:hellomake.c:function main: error: undefined reference to 'printf'

修改LIBS=-lm  更改为:LIBS=-lm -lc  再次执行make, 编译成功,

adb push ./bin/hellomake /data/local/tmp;

然后执行:

adb shell  /data/local/tmp/hellomake, 奇怪没有任何输出,需要修改:

PROJECT_ALL_OBJS+=$(NDKLIB)/crtbegin_dynamic.o
PROJECT_ALL_OBJS+=$(NDKLIB)/crtend_android.o

然后从新编译,push,执行得到:

Hello makefiles!
Value:2.708050

好啦,完成

最后的makefile是:

#Hellomake
#Magnum, 2014-10-19
# 指令编译器和选项
TOOLCHAINS_ROOT=$(NDK_HOME)/toolchains/arm-linux-androideabi-4.8/prebuilt/linux-x86_64/
TOOLCHAINS_PREFIX=$(TOOLCHAINS_ROOT)/bin/arm-linux-androideabi
TOOLCHAINS_INCLUDE=$(TOOLCHAINS_ROOT)/lib/gcc/arm-linux-androideabi/4.8/include-fixed

PLATFORM_ROOT=$(NDK_HOME)/platforms/android-17/arch-arm
NDKINC=$(PLATFORM_ROOT)/usr/include
NDKLIB=$(PLATFORM_ROOT)/usr/lib

CC=$(TOOLCHAINS_PREFIX)-gcc
CFLAGS=-Wall -nostdlib #-Bdynamic
# 需要链接库的库名,比如libm.a,就是-lm,需要去掉前面的lib和后面的.a
LIBS=-lm -lc #-lgcc
# 设置默认搜索头文件的路径,优先是这个,然后是系统路径
IncludeDir = -I./include/ -I$(NDKINC)
# 需要链接的库的路径
LinkDir = -L$(NDKLIB)
OBJ_DIR = ./obj
BIN_DIR = ./bin

#PROJECT_TOP_DIR设置成pwd 或者"./"都行
PROJECT_TOP_DIR=.#$(shell pwd)#$(shell cd ../; pwd)
PROJECT_BIN_DIR=$(PROJECT_TOP_DIR)/bin
PROJECT_SRC_DIR=$(PROJECT_TOP_DIR)/src
PROJECT_LIB_DIR=$(PROJECT_TOP_DIR)/lib
PROJECT_OBJ_DIR=$(PROJECT_TOP_DIR)/objs
MKDIR := mkdir -p

# 目标文件
EXE_NAME=hellomake
TARGET=$(BIN_DIR)/$(EXE_NAME)

#源文件的文件类型
FILE_TYPE=c
src=$(wildcard $(PROJECT_SRC_DIR)/*.$(FILE_TYPE))
dir= $(notdir $(src))
PROJECT_OBJ= $(patsubst %.$(FILE_TYPE),%.o,$(dir) )
PROJECT_ALL_OBJS= $(addprefix $(PROJECT_OBJ_DIR)/, $(PROJECT_OBJ))
PROJECT_ALL_OBJS+=$(NDKLIB)/crtbegin_dynamic.o
PROJECT_ALL_OBJS+=$(NDKLIB)/crtend_android.o

all: chdir $(TARGET)

$(TARGET): $(PROJECT_ALL_OBJS)
$(CC) $(CFLAGS) -o $@ $^ $(LinkDir) $(LIBS)

chdir:
@if test ! -d $(PROJECT_OBJ_DIR) ; \
then \
mkdir $(PROJECT_OBJ_DIR) ; \
fi

@if test ! -d $(PROJECT_BIN_DIR) ; \
then \
mkdir $(PROJECT_BIN_DIR) ; \
fi

.PHONY : clean
clean:
-rm -rf $(PROJECT_BIN_DIR) $(PROJECT_OBJ_DIR)

$(PROJECT_OBJ_DIR)/%.o:$(PROJECT_SRC_DIR)/%.$(FILE_TYPE)
$(CC) $(CFLAGS) -o $@ -c $< $(IncludeDir)

后面要把一些代码编译成可执行文件在android设备上验证,用这个makefile即可。
如有写的不符合指出,还望大家指出,共同进步

一步一步写一个简单通用的makefile(四)--写一个通用的makefile编译android可执行文件的更多相关文章

  1. win7中的Uac与开机自动启动(好几种办法,特别是用不带UAC的程序启动UAC程序是一个简单的好办法,写驱动自启动更是了不得)

    在另一篇文章中已经介绍了给Exe加上Uac的方法,在使用的过程中我们会发现,如果把带Uac的Exe写入注册表的Run中,是无法实现开机自动启动的,原因就是带Uac的exe需要申请管理员权限,以便运行执 ...

  2. 从一个简单的组件化封装写优化DOM操作

    /* *缺点 * 1. 还需要我们自己手工维护dom状态,以数据的思想去思考 *2. 数据改变后,还需要我们自己手动改变dom *3. * */ class LikeButton{ construct ...

  3. TCP/TP编程 - 一个简单的Linux下C写的socket服务器客户端程序

    服务端: hello_server.c #include <stdio.h> #include <stdlib.h> #include <string.h> #in ...

  4. Python学习笔记23:Django构建一个简单的博客网站(一个)

    在说如何下载和安装Django,本节将重点讨论如何使用Django站点. 一 新建project 命令:django-admin startproject mysite # 有的须要输入:django ...

  5. SpringMVC4+thymeleaf3的一个简单实例(篇四:form表单数据验证)

    关于表单数据验证有很多中方法,这里我仅介绍JSR303注解验证.JSR303仅仅是一个规范,这里我们要用到它的一个实现:hibernate-validator. 注意在spring的配置文件sprin ...

  6. (原创)如何使用boost.asio写一个简单的通信程序(一)

    boost.asio相信很多人听说过,作为一个跨平台的通信库,它的性能是很出色的,然而它却谈不上好用,里面有很多地方稍不注意就会出错,要正确的用好asio还是需要花一番精力去学习和实践的,本文将通过介 ...

  7. (2)自己写一个简单的servle容器

    自己写一个简单的servlet,能够跑一个简单的servlet,说明一下逻辑. 首先是写一个简单的servlet,这就关联到javax.servlet和javax.servlet.http这两个包的类 ...

  8. GNU Make 学习系列一:怎样写一个简单的Makefile

    编程通常遵循一个相当简单的程序:编辑源文件,编译源代码成可执行的格式,调试结果.尽管将源代码翻译成可执行程序是常规的过程,如果做的不正确,程序员可能会浪费大量的时间去追踪问题.大多数的开发者都经历过这 ...

  9. 写一个简单的C词法分析器

    写一个简单的C词法分析器 在写本文过程中,我参考了<词法分析器的实现>中的一些内容.这里我们主要讨论写一个C语言的词法分析器. 一.关键字 首先,C语言中关键字有: auto.break. ...

随机推荐

  1. js 中对象属性特性2

    对象的存储描述: get   和   set 方法 <script> var obj ={ get age(){ return 22 }, set age(value){ console. ...

  2. Javascript自执行匿名函数(function() { })()的原理浅析

    匿名函数就是没有函数名的函数.这篇文章主要介绍了Javascript自执行匿名函数(function() { })()的原理浅析的相关资料,需要的朋友可以参考下 函数是JavaScript中最灵活的一 ...

  3. 4种方法生成二维码 (js 控制canvas 画出 二维码)

    随着网络的迅速发展 发展 发展,二维码的应用将会越来越多.同时很多只是很平凡的二维码,请拿起你的手 把这个二维码 设计起来吧.下面分享了几个非常好的二维码设计.  二维码原理: 二维条码/二维码可以分 ...

  4. sql server2005主从数据库同步配置

    网站规模到了一定程度之后,该分的也分了,该优化的也做了优化,但是还是不能满足业务上对性能的要求:这时候我们可以考虑使用主从库.主从库是两台服务器上的两个数据库,主库以最快的速度做增删改操作+最新数据的 ...

  5. #ifndef#define#endif的用法-b

    The special operator defined is used in #if and #elif expressions to test whether a certain name is ...

  6. MySQL中的max_connections和max_user_connections 及 MySQL服务器最大连接数的合理设置

    max_connections 是指整个mysql服务器的最大连接数: max_user_connections 是指每个数据库用户的最大连接数,比如:虚拟主机可以用这个参数控制每个虚拟主机用户的数据 ...

  7. 转:PHP – Best Practises

    原文来自于:http://thisinterestsme.com/php-best-practises/ There are a number of good practises that you s ...

  8. delphi xe5 android 开发实现手机打电话和发短信

    转载自  http://www.raysoftware.cn/ 其实都可以通过intent和URI调用系统功能.Windows程序员可以理解成是ShellExecute.这个是万金油.可以有调用各种功 ...

  9. simhash--文本排重

    转载自 https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/zh/06.12.md http: ...

  10. 移除Ubuntu“下载额外数据不成功”的提示通知

    参考自经过几天的摸索,终于得出安装flashplugin-installer的方法 移除"下载额外数据不成功"的恼人提示通知,方法: $cd /usr/share/package- ...