一般要把咱們本身的的代碼編譯成在android裏面編譯的可執行文件,咱們一般是建一個文件夾linux
. ├── 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,生成文件以下:android
[armeabi-v7a] Install : convolve-ocl => libs/armeabi-v7a/convolve-ocl
[armeabi-v7a] Install : libstlport_shared.so => libs/armeabi-v7a/libstlport_shared.so
可是今天咱們要修改上一章的模板makefile來編譯能夠在android中執行的可執行文件。shell
首先咱們仍是用以前的三個文件hellomake.c, hellofunc.c, hellofunc.h,文件樹以下:app
.
├── makefile
├── makefile1
└── src
├── hellofunc.c
├── hellofunc.h
└── hellomake.c
由於要用到android的交叉編譯器,因此不能用gcc,另外尋找頭文件的系統路徑也不同,尋找庫的路徑也和linux本來的不一樣,因此 -I 和 -L的路徑也須要修改ide
修改以後的makefile以下:ui
#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-fixedidea
PLATFORM_ROOT=$(NDK_HOME)/platforms/android-17/arch-arm
NDKINC=$(PLATFORM_ROOT)/usr/include
NDKLIB=$(PLATFORM_ROOT)/usr/libspa
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 = ./bincode
#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 -porm
# 目標文件
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 1 exit status make: *** [bin/hellomake] Error 1
進入到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 1 exit status make: *** [bin/hellomake] Error 1
很差意思,這個是由於
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便可。若有寫的不符合指出,還望你們指出,共同進步