Bootstrap

安卓编译caffe错误 ‘undefined reference to `stderr'’

NDK:android-ndk-r15c

caffe:https://github.com/sh1r0

编译错误:

[ 76%] Building CXX object src/caffe/CMakeFiles/caffe.dir/util/insert_splits.cpp.o
[ 77%] Building CXX object src/caffe/CMakeFiles/caffe.dir/internal_thread.cpp.o
[ 77%] Linking CXX shared library ../../lib/libcaffe.so
/home/hezheng/caffe-android-lib/android_lib/leveldb/lib/libleveldb.a(port_posix.o): In function `leveldb::port::PthreadCall(char const*, int) [clone .part.0]':
port_posix.cc:(.text.unlikely+0x14): undefined reference to `stderr'
port_posix.cc:(.text.unlikely+0x18): undefined reference to `stderr'
/home/hezheng/caffe-android-lib/android_lib/leveldb/lib/libleveldb.a(env_posix.o): In function `leveldb::(anonymous namespace)::PosixEnv::PthreadCall(char const*, int) [clone .isra.23] [clone .part.24]':
env_posix.cc:(.text+0xc94): undefined reference to `stderr'
env_posix.cc:(.text+0xc98): undefined reference to `stderr'
/home/hezheng/caffe-android-lib/android_lib/leveldb/lib/libleveldb.a(env_posix.o): In function `leveldb::(anonymous namespace)::PosixEnv::~PosixEnv()':
env_posix.cc:(.text+0x245c): undefined reference to `stderr'
/home/hezheng/caffe-android-lib/android_lib/leveldb/lib/libleveldb.a(env_posix.o):env_posix.cc:(.text+0x2490): more undefined references to `stderr' follow
collect2: error: ld returned 1 exit status
src/caffe/CMakeFiles/caffe.dir/build.make:3371: recipe for target 'lib/libcaffe.so' failed
make[2]: *** [lib/libcaffe.so] Error 1
CMakeFiles/Makefile2:272: recipe for target 'src/caffe/CMakeFiles/caffe.dir/all' failed
make[1]: *** [src/caffe/CMakeFiles/caffe.dir/all] Error 2
Makefile:127: recipe for target 'all' failed
make: *** [all] Error 2
错误原因:

在编译leveldb的静态库libleveldb.a时,源文件里面使用了大量的标准IO设备:stderr 等。在NDK15以后,这些都不被支持了,见官方说明文档。编译静态库本身没问题,但是caffe.so链接时就找不到对应的静态库定义了,所以报错。

解决方法:

根据官网,需要给C编译器制定参数 CFLAGS=-D__ANDROID_API__=$API,这里需要把leveldb的Makefile改一下,文件位置leveldb/Makefile

原配置:

CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT) 
CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)
 
LDFLAGS += $(PLATFORM_LDFLAGS)
LIBS += $(PLATFORM_LIBS)

SIMULATOR_OUTDIR=out-ios-x86
DEVICE_OUTDIR=out-ios-arm

修改后:

CFLAGS += -I. -I./include $(PLATFORM_CCFLAGS) $(OPT)  -D__ANDROID_API__=21
CXXFLAGS += -I. -I./include $(PLATFORM_CXXFLAGS) $(OPT)  -D__ANDROID_API__=21
 
LDFLAGS += $(PLATFORM_LDFLAGS)
LIBS += $(PLATFORM_LIBS)

SIMULATOR_OUTDIR=out-ios-x86
DEVICE_OUTDIR=out-ios-arm
这里的21时安卓API的版本号,按照实际情况填写

;