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即可。
    如有写的不符合指出,还望大家指出,共同进步

  • 相关阅读:
    SQLMAP注入教程-11种常见SQLMAP使用方法详解
    VS2012/2013/2015/Visual Studio 2017 关闭单击文件进行预览的功能
    解决 IIS 反向代理ARR URLREWRITE 设置后,不能跨域跳转 return Redirect 问题
    Spring Data JPA one to one 共享主键关联
    JHipster 问题集中
    Spring Data JPA 定义超类
    Spring Data JPA查询关联数据
    maven命名
    maven仓库
    Jackson读取列表
  • 原文地址:https://www.cnblogs.com/biglucky/p/4034927.html
Copyright © 2011-2022 走看看