通常要把我们自己的的代码编译成在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. mini2440 MJPG_STREAMER 产生问题

    usb摄像头芯片是中芯微的zc0301pl, http://www.vimicro.com.cn/product/pdf/ZC301PL-1107-V10-EN.pdf [root@FriendlyA ...

  2. java String字符串——进度1

    String字符串    在JAVA中提供了多种创建字符串对象的方法,这里介绍最简单的两种,    第一种是直接赋值,    第二种是使用String类的构造方法:    如下所示:    Strin ...

  3. Cassandra1.2文档学习(1)——Cassandra基本说明

    参考文档:http://www.datastax.com/documentation/cassandra/1.2/webhelp/index.html#cassandra/architecture/a ...

  4. c#中struct和class的区别 z

    1.struct 是值类型,class是对象类型 2.struct 不能被继承,class可以被继承 3.struct 默认的访问权限是public,而class默认的访问权限是private. 4. ...

  5. iOS 常用基础框架

    框架名称 功能 Foundation 提供OC的基础类(像NSObject).基本数据类型等 UIKit 创建和管理应用程序的用户界面 QuartzCore 提供动画特效以及通过硬件进行渲染的能力 C ...

  6. NOI冲刺计划2

    吐槽:距离上一次写计划还没有一个月呢,咋又喊要重写捏?可以直接从上一次的计划粘上个一大半. bzoj刷题速度还是在计划之内的,这大半个月中,我bzoj刷进500道,知识方面主要是把莫比乌斯反演系统性的 ...

  7. php 文件上传 以及保存在本地的乱码问题处理

    要知道两点: ①浏览器传到PHP程序中是UTF-8编码 ②PHP程序保存上传的文件,要转换成GBK编码才保存在本地中,否则如果直接使用浏览器传过来的文件名保存在本地,会出现文件名乱码. <?ph ...

  8. const char * 的终结贴(看完无需其他任何文章,从此不再蛋疼)

    我之前也是以为我对const char *ptr 这种形式的写法是掌握了的,真的,不就是说一个指针是不可改变的吗? 那么问题就来了,到底是ptr指针本身不能改变,还是ptr执行的值不能改变呢? 从网上 ...

  9. Java RMI远程方法调用

    RMI(远程接口调用) 1. RMI的原理: RMI系统结构,在客户端和服务器端都有几层结构. 方法调用从客户对象经占位程序(Stub).远程引用层(Remote Reference Layer)和传 ...

  10. FFMPEG之TimeBase成员理解

    http://blog.csdn.net/supermanwg/article/details/14521869