zoukankan      html  css  js  c++  java
  • 一步一步写一个简单通用的makefile(四)--写一个通用的makefile编译android可执行文件

    通常要把我们自己的的代码编译成在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 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即可。
    如有写的不符合指出,还望大家指出,共同进步

  • 相关阅读:
    DP大作战—状态压缩dp
    DP大作战—组合背包
    DP大作战——多重背包
    单链表的使用——计算多项式加法
    单链表逆置
    钢条切割问题
    哈夫曼树及解码
    双“11”的抉择
    矩阵链相乘助教版代码
    abs()函数的返回值问题
  • 原文地址:https://www.cnblogs.com/biglucky/p/4034927.html
Copyright © 2011-2022 走看看