REDHAT+GFLAGS+GLOG源码编译CAFFE2指南
为什么要从源码编译?
caffe2出来有一段时间了,但是源码编译的教程少的令人发指,因为服务器没有相关环境,同时划重点,服务器不联网,所有的库都要自己下载上传编译。所以需要从头到尾自己编译caffe2。
编译前的准备
确认你已经安装或者下载好了这些类库(有一些不是一定要的,可以根据自己的选择自由决定)
- cuda
- glog
- gloo
- glflags
- mpi
- leveldb
- lmdb
- opencv
- intel-compiler
安装好的务必记住其各个库的根目录位置,apt安装最为简便,因为服务器没有相关库,所以要自己源码编译这些开源的库才能使用。编译方式很简单,configure结束后make,make install即可。
编译CAFFE2
在CAFFE2根目录执行以下指令:
makedir build && cd build
cmake ..
/*
在下面的界面更改prefix-install路径,因为不是管理员权限,只能安装到本地路径
*/
ccmake ..
如果以上类库安装无误,同时提示你没有任何问题,那么恭喜你有很大可能安装成功。有问题的话之后再细说。
执行make install
,无错误的话整个过程就解说,但是,如果这么简单就没有这个blog了,哈哈哈哈
CAFFE2安装智障的地方就是其神奇一般的cmake脚本,以至于你都不知道如何去适配你自己源码编译各种库文件(也许我太菜了2333)。
1. 首先来看CAFFE2编译过程中的第一段错误
-- Caffe2: Cannot find glog automatically. Using legacy find.
-- Could NOT find glog (missing: GLOG_LIBRARY)
CMake Warning at cmake/public/glog.cmake:66 (message):
Caffe2: glog cannot be found. Depending on whether you are building Caffe2
or a Caffe2 dependent library, the next warning / error will give you more
info.
Call Stack (most recent call first):
cmake/Dependencies.cmake:134 (include)
CMakeLists.txt:182 (include)
这段错误的意思是找不到glog库,可是我已经源码编译安装好glog库了,设置好了环境变量为什么依然看不到这个类库。第一步肯定是百度(google不好用啊= =),于是找到了大神的blogcaffe:cmake编译指定glog,gflag路径,虽然是caffe的,但是也可以一探究竟为啥会出问题:
当使用cmake编译caffe的情况下,在 cmake生成Makefile时会自动找到系统安装的glog,gflag,但是如是我们自己编译了一个glog,gflag,并没有安装在(/usr)系统目录下,而是放在用户目录(/home)下,要想使用这个glog,gflag版本,不做处理cmake是找不到的。
caffe2的cmake不太一样,所以要这样子添加
#在 $caffe2_source_root/cmake/public/glog.cmake中做如下修改
include(FindPackageHandleStandardArgs)
set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
if(NOT WIN32)
#添加函数
find_path(GLOG_INCLUDE_DIR glog/logging.h
PATHS ${GLOG_ROOT_DIR}
NO_DEFAULT_PATH)
#添加结束
find_path(GLOG_INCLUDE_DIR glog/logging.h
PATHS ${GLOG_ROOT_DIR})
endif()
#添加函数
find_library(GLOG_LIBRARY glog
PATHS ${GLOG_ROOT_DIR}
PATH_SUFFIXES lib lib64
NO_DEFAULT_PATH)
#添加结束
find_library(GLOG_LIBRARY glog
PATHS ${GLOG_ROOT_DIR}
PATH_SUFFIXES lib lib64)
执行指令
/*glog_root指向你glog类库的根目录*/
cmake .. -DGLOG_ROOT_DIR=$glog_root
重新查看cmake输出可以看到cmake找到了你自定义的glog类库了。
但是!但是!机智的CAFFE2怎么可能这么快让你通关了,这只是考验的开始,于是遇到了下一个问题:
/caffe2source/pytorch/caffe2/core/flags.cc: In function ‘void caffe2::SetUsageMessage(const string&)’:
/caffe2source/pytorch/caffe2/core/flags.cc:17:3: error: ‘gflags’ has not been declared
gflags::SetUsageMessage(str);
^
/caffe2source/pytorch/caffe2/core/flags.cc: In function ‘const char* caffe2::UsageMessage()’:
/caffe2source/pytorch/caffe2/core/flags.cc:21:10: error: ‘gflags’ has not been declared
return gflags::ProgramUsage();
^
/caffe2source/pytorch/caffe2/core/flags.cc: In function ‘bool caffe2::ParseCaffeCommandLineFlags(int*, char***)’:
/caffe2source/pytorch/caffe2/core/flags.cc:26:10: error: ‘gflags’ has not been declared
return gflags::ParseCommandLineFlags(pargc, pargv, true);
^
At global scope:
cc1plus: warning: unrecognized command line option "-Wno-invalid-partial-specialization" [enabled by default]
make[2]: *** [caffe2/CMakeFiles/caffe2.dir/core/flags.cc.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [caffe2/CMakeFiles/caffe2.dir/all] Error 2
make[1]: *** Waiting for unfinished jobs....
Compiling src/broadcast.cu > /caffe2source/pytorch/third_party/nccl/build/obj/broadcast.o
ptxas warning : Too big maxrregcount value specified 96, will be ignored
Compiling src/reduce.cu > /caffe2source/pytorch/third_party/nccl/build/obj/reduce.o
ptxas warning : Too big maxrregcount value specified 96, will be ignored
Compiling src/reduce_scatter.cu > /caffe2source/pytorch/third_party/nccl/build/obj/reduce_scatter.o
ptxas warning : Too big maxrregcount value specified 96, will be ignored
Linking libnccl.so.1.3.5 > /caffe2source/pytorch/third_party/nccl/build/lib/libnccl.so.1.3.5
Archiving libnccl_static.a > /caffe2source/pytorch/third_party/nccl/build/lib/libnccl_static.a
[ 37%] No install step for 'nccl_external'
[ 37%] Completed 'nccl_external'
[ 37%] Built target nccl_external
make: *** [all] Error 2
但是之前cmak的提示是
Caffe2: Found gflags with new-style gflags target.
这就很尴尬了,这是咋回事,这里的问题原因经过我的搜索在官方github的issue找到了,简单点来说就是官方在最新3.0版本的gflags将命名空间从google改为了gflags,服务器上仍旧为2.2.1的老旧版本,最新的caffe2用的是新版gflags,所以不兼容,解决方法也很简单,下载最新的gflags吧。但是!同样的文件夹下的cmake怎么格式不一样啊,我编译出来的gflags文件夹下有lib,include,bin
三个文件夹,你这个find_library
,find_path
也太敷衍了吧好歹glog
还像回事,你这个只搜索GFLAGS_ROOT_DIR好像不行啊(cmake是不是还会递归搜索,反正这里没有搜索到),于是手动滑稽一下吧。
#原始的gflags.cmake
include(FindPackageHandleStandardArgs)
set(GFLAGS_ROOT_DIR "" CACHE PATH "Folder contains Gflags")
# We are testing only a couple of files in the include directories
if(WIN32)
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR}/src/windows)
else()
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR})
endif()
if(WIN32)
find_library(GFLAGS_LIBRARY_RELEASE
NAMES libgflags
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Release)
find_library(GFLAGS_LIBRARY_DEBUG
NAMES libgflags-debug
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Debug)
set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG})
else()
find_library(GFLAGS_LIBRARY gflags)
endif()
#修改后的gflags.cmake
if(WIN32)
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR}/src/windows)
else()
# find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
# PATHS ${GFLAGS_ROOT_DIR})
find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
PATHS ${GFLAGS_ROOT_DIR}/include
NO_DEFAULT_PATH)
#find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
# PATHS ${GFLAGS_ROOT_DIR}/include)
endif()
if(WIN32)
find_library(GFLAGS_LIBRARY_RELEASE
NAMES libgflags
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Release)
find_library(GFLAGS_LIBRARY_DEBUG
NAMES libgflags-debug
PATHS ${GFLAGS_ROOT_DIR}
PATH_SUFFIXES Debug)
set(GFLAGS_LIBRARY optimized ${GFLAGS_LIBRARY_RELEASE} debug ${GFLAGS_LIBRARY_DEBUG})
else()
# find_library(GFLAGS_LIBRARY gflags)
find_library(GFLAGS_LIBRARY gflags
PATH ${GFLAGS_ROOT_DIR}/lib
NO_DEFAULT_PATH)
endif()
最后cmake执行的指令是(cudnn_root也是源码编译的,其它类库是自带的)
cmake $caffe_root -G "Unix Makefiles" \
-DGLOG_ROOT_DIR=$glog_root \
-DCUDNN_ROOT_DIR=$cudnn_root \
-DGFLAGS_ROOT_DIR=$gflags_root
make install
编译成功!开心一下吧