移植dlib到android

1、文件目录
/src/face_landmark_detection_test1_ex.cpp
—-/jni/
———-Application.mk
———-Android.mk

2、文件内容
2.1 Application.mk

[zzz@localhost jni]$ cat Application.mk 
APP_STL:=gnustl_static
APP_CPPFLAGS:=-frtti -fexceptions
APP_ABI:=armeabi-v7a
APP_PLATFORM:=android-8
APP_BUILD_SCRIPT:=Android.mk
APP_CFLAGS+=-DDLIB_NO_GUI_SUPPORT=1
[zzz@localhost jni]$ 

上面的APP_CFLAGS+=-DDLIB_NO_GUI_SUPPORT=1是因为不需要使用gui相关的功能。

编译dlib的时候,还改了两个文件引用头文件的地方:

<png.h>改为"../external/libpng/png.h"
<jpeglib.h>改为"../external/libjpeg/jpeglib.h"

2.2 Android.mk

[zzz@localhost jni]$ cat Android.mk


#include $(CLEAR_VARS)

LOCAL_PATH:=$(call my-dir)
LOCAL_MODULE:=face_landmark_detection_test1_ex
LOCAL_PATH:=$(call my-dir)
LOCAL_MODULE_FILENAME:=face_landmark_detection_test1_ex
LOCAL_SRC_FILES:=../../face_landmark_detection_test1_ex.cpp  /home/zzz/software/dlib-18.18/dlib/all/source.cpp
LOCAL_C_INCLUDES:=/home/zzz/software/dlib-18.18/
#LOCAL_EXPORT_C_INCLUDES:=/home/zzz/software/dlib-18.18/
include $(BUILD_EXECUTABLE)

在LOCAL_SRC_FILES中,直接把dlib的源文件作为源文件之一,向之前在dlib移植到arm上说的一样,简单的不能再简单。
注意头文件路径。

这里有个问题:如果我在上面打开了:
include $(CLEAR_VARS)
会报以下的错误:

[zzz@localhost jni]$ ndk-build NDK_APPLICATION_MK=Application.mk
make: *** No rule to make target `/home/zzz/software/android-ndk-r9d/build/core/../../face_landmark_detection_test1_ex.cpp', needed by `/home/zzz/software/dlib-18.18/examples/build_android/obj/local/armeabi-v7a/objs/face_landmark_detection_test1_ex/__/__/face_landmark_detection_test1_ex.o'.  Stop.
[zzz@localhost jni]$ 

2.3 执行

zzz@localhost jni]$ ndk-build NDK_APPLICATION_MK=Application.mk
[armeabi-v7a] Compile++ thumb: face_landmark_detection_test1_ex <= face_landmark_detection_test1_ex.cpp
[armeabi-v7a] Compile++ thumb: face_landmark_detection_test1_ex <= source.cpp
[armeabi-v7a] Executable     : face_landmark_detection_test1_ex
[armeabi-v7a] Install        : face_landmark_detection_test1_ex => libs/armeabi-v7a/face_landmark_detection_test1_ex
[zzz@localhost jni]$ ndk-build

因为我这个是有jin目录的,所以,不需要再额外指定NDK_APPLICATION_MK也可以。

问题记录:
1、
jni/: error: iostream: No such file or directory
或者其他头文件找不到。
解决办法:
在Application.mk中加入:
APP_STL:=gnustl_static 或 gnustl_shared , c++_static , c++_shared
但是用system,stlport_static stlport_shared会有头文件找不到。
参考:
http://stackoverflow.com/questions/9130429/android-ndk-build-iostream-no-such-file-or-directory

APP_STL的取值可以为:
system stlport_static stlport_shared gnustl_static gnustl_shared gabi++_static gabi++_shared c++_static c++_shared none

2、
/build-binary.mk:393: * target pattern contains no `%’

3、
如果我把Android.mk修改为如下(先编译出dlib的静态库,再与测试程序链接),就会报如下错误:

[zzz@localhost jni]$ ndk-build
[armeabi-v7a] Compile++ thumb: dlib <= source.cpp
[armeabi-v7a] StaticLibrary  : dlib.a
make: *** No rule to make target `/home/zzz/software/android-ndk-r9d/build/core/../../face_landmark_detection_test1_ex.cpp', needed by `/home/zzz/software/dlib-18.18/examples/build_android/obj/local/armeabi-v7a/objs/face_landmark_detection_test1_ex/__/__/face_landmark_detection_test1_ex.o'.  Stop.

Android.mk的内容为:

[zzz@localhost jni]$ cat Android.mk


LOCAL_PATH:=$(call my-dir)
LOCAL_MODULE:=dlib
LOCAL_MODULE_FILENAME:=dlib
LOCAL_SRC_FILES:=/home/zzz/software/dlib-18.18/dlib/all/source.cpp
LOCAL_C_INCLUDES:=/home/zzz/software/dlib-18.18/


#LOCAL_EXPORT_C_INCLUDES:=/home/zzz/software/dlib-18.18/
#include $(BUILD_EXECUTABLE)
include $(BUILD_STATIC_LIBRARY)

####################################################
#include $(CLEAR_VARS)
LOCAL_PATH:=$(call my-dir)
LOCAL_MODULE:=face_landmark_detection_test1_ex
LOCAL_MODULE_FILENAME:=face_landmark_detection_test1_ex
LOCAL_SRC_FILES:=../../face_landmark_detection_test1_ex.cpp # /home/zzz/software/dlib-18.18/dlib/all/source.cpp
LOCAL_C_INCLUDES:=/home/zzz/software/dlib-18.18/


LOCAL_SHARED_LIBRARIES:=dlib

#LOCAL_EXPORT_C_INCLUDES:=/home/gumh/software/dlib-18.18/
#include $(BUILD_EXECUTABLE)
include $(BUILD_STATIC_LIBRARY)

原因还不明白。。。

补充(2016-1-30):
由于上面编译的时候,没有将jpeg,png的库编译进去,因此,在真正运行程序的时候,会报错。重新将相关的代码组织进mk文件进行编译,文件结构没变,各文件的情况如下:

1、Application.mk

APP_STL:=gnustl_static ##ok #APP_STL:=stlport_static ##not work! #APP_STL:=system ##not work! #APP_STL:=c++_static ##ok #APP_STL:=c++_shared ##ok #APP_STL:=gnustl_shared ##ok APP_CPPFLAGS:=-frtti -fexceptions APP_ABI:=armeabi-v7a APP_PLATFORM:=android-8 APP_BUILD_SCRIPT:=Android.mk APP_CFLAGS+=-DDLIB_NO_GUI_SUPPORT=on #APP_CFLAGS+=-DDLIB_PNG_SUPPORT=off APP_CFLAGS+=-DDLIB_JPEG_SUPPORT=on APP_CFLAGS+=-DDLIB_JPEG_STATIC=on

2、Android.mk


all_cpp_files_recursively = \
 $(eval src_files = $(wildcard $1/*.cpp)) \
 $(eval src_files = $(src_files:$(LOCAL_PATH)/%=%))$(src_files) \
 $(eval item_all = $(wildcard $1/*)) \
 $(foreach item, $(item_all) $(),\
  $(eval item := $(item:%.cpp=%)) \
  $(call all_cpp_files_recursively, $(item))\
 )


#3 自定义了一个all_c_files_recursively 函数,递归遍历返回给定目录下所有C源文件。
all_c_files_recursively = \
 $(eval src_files = $(wildcard $1/*.c)) \
 $(eval src_files = $(src_files:$(LOCAL_PATH)/%=%))$(src_files) \
 $(eval item_all = $(wildcard $1/*)) \
 $(foreach item, $(item_all) $(),\
  $(eval item := $(item:%.c=%)) \
  $(call all_c_files_recursively, $(item))\
 )


LOCAL_PATH:=$(call my-dir)
include $(CLEAR_VARS)
#####################程序################
LOCAL_SRC_FILES := $(call all_cpp_files_recursively,$(LOCAL_PATH)/../../../dlib/external/libjpeg/) #将jpeg相关代码加入
LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../dlib/all/source.cpp
LOCAL_C_INCLUDES:=/home/gumh/software/dlib-18.18/ $(LOCAL_PATH)/../../../dlib/entropy_decoder/
LOCAL_CPP_INCLUDES:=${LOCAL_C_INCLUDES}
LOCAL_CXX_INCLUDES:=${LOCAL_C_INCLUDES}

$(warning "-------------the value of LOCAL_SRC_FILES is $(LOCAL_SRC_FILES)--------------------")

##neon start
TARGET_ARCH_ABI :=armeabi-v7a
LOCAL_ARM_MODE := arm 
LOCAL_ARM_NEON := true

ifeq ($(TARGET_ARCH_ABI),armeabi-v7a)
    LOCAL_CFLAGS := -DHAVE_NEON=1
    LOCAL_CXXFLAGS := -DHAVE_NEON=1
endif
LOCAL_CFLAGS += -mfloat-abi=softfp -mfpu=vfpv4
###neon end


##放在一起编译
LOCAL_MODULE:=face_landmark_detection_test1_ex
LOCAL_MODULE_FILENAME:=face_landmark_detection_test1_ex
LOCAL_SRC_FILES+=../../face_landmark_detection_test1_ex.cpp 

include $(BUILD_EXECUTABLE)

从上面的文件可以看到,其实就是配合source.cpp定义的宏,把相关的jpeg的源代码加入一起编译。

是否可以先编译出dlib的静态库,给后面的应用程序编译使用呢?
新加一个Android-prebuild.mk:



all_cpp_files_recursively = \ $(eval src_files = $(wildcard $1/*.cpp)) \ $(eval src_files = $(src_files:$(LOCAL_PATH)/%=%))$(src_files) \ $(eval item_all = $(wildcard $1/*)) \ $(foreach item, $(item_all) $(),\ $(eval item := $(item:%.cpp=%)) \ $(call all_cpp_files_recursively, $(item))\ ) #3 自定义了一个all_c_files_recursively 函数,递归遍历返回给定目录下所有C源文件。 all_c_files_recursively = \ $(eval src_files = $(wildcard $1/*.c)) \ $(eval src_files = $(src_files:$(LOCAL_PATH)/%=%))$(src_files) \ $(eval item_all = $(wildcard $1/*)) \ $(foreach item, $(item_all) $(),\ $(eval item := $(item:%.c=%)) \ $(call all_c_files_recursively, $(item))\ ) LOCAL_PATH:=$(call my-dir) ############1################## #####################libdlib.a################ $(warning "--------build dlib ---------") include $(CLEAR_VARS) LOCAL_MODULE:=dlib LOCAL_SRC_FILES := $(call all_cpp_files_recursively,$(LOCAL_PATH)/../../../dlib/external/libjpeg/) LOCAL_SRC_FILES += $(LOCAL_PATH)/../../../dlib/all/source.cpp LOCAL_C_INCLUDES:=/home/gumh/software/dlib-18.18/ $(LOCAL_PATH)/../../../dlib/entropy_decoder/ LOCAL_CPP_INCLUDES:=${LOCAL_C_INCLUDES} LOCAL_CXX_INCLUDES:=${LOCAL_C_INCLUDES} $(warning "-------------the value of LOCAL_SRC_FILES is $(LOCAL_SRC_FILES)--------------------") ##neon start TARGET_ARCH_ABI :=armeabi-v7a LOCAL_ARM_MODE := arm LOCAL_ARM_NEON := true ifeq ($(TARGET_ARCH_ABI),armeabi-v7a) LOCAL_CFLAGS := -DHAVE_NEON=1 LOCAL_CXXFLAGS := -DHAVE_NEON=1 endif LOCAL_CFLAGS += -mfloat-abi=softfp -mfpu=vfpv4 ########海思的设置:set(CMAKE_CXX_FLAGS "-mthumb -mcpu=cortex-a7 -mfloat-abi=softfp -mfpu=neon-vfpv4 -mno-unaligned-access -fno-aggressive-loop-optimizations" CACHE STRING "c++ flags") ###neon end include $(BUILD_STATIC_LIBRARY) ########2################## ##########build app############## $(warning "--------build app---------") #use prebuild dlib LOCAL_MODULE:=mydlib LOCAL_SRC_FILES:=libdlib.a LOCAL_EXPORT_C_INCLUDES:=/home/gumh/software/dlib-18.18/ $(LOCAL_PATH)/../../../dlib/entropy_decoder/ include $(PREBUILT_STATIC_LIBRARY) ###app####### include $(CLEAR_VARS) LOCAL_MODULE:=face_landmark_detection_test1_ex LOCAL_SRC_FILES:=../../face_landmark_detection_test1_ex.cpp LOCAL_STATIC_LIBRARIES:=mydlib include $(BUILD_EXECUTABLE) ############## 

在把Application.mk里的APP_BUILD_SCRIPT改为:Android-prebuilt.mk
APP_BUILD_SCRIPT:=Android-prebuilt.mk

一个简单的make.sh

[zzz@localhost jni]$ cat make.sh 
#!/bin/sh 
ndk-build NDK_PROJECT_PATH=. NDK_APPLICATION_MK=Application.mk 

(如何传递参数,在Android.mk里可以根据参数来编译不同的部分?如
ifeq ($(my_target),”dlib”)就编译dlib库,否则编译其他程序。

执行:
1、先构建libdlib.a
2、将编译出来的libdlib.a拷贝到Android.mk的同目录下,
2、再构建app

你可能感兴趣的:(android,dlib)