本文主要说明下,caffe
源码分析过程中的cmake
(结合IDE CLion
)工程构建问题。在分析caffe
源码的过程中,我没有仅仅只是看代码,而是:
自己从头构建一遍工程,这样能让我更好的了解大型的项目的构建。当然原始的caffe的构建感觉还是比较复杂(主要是
cmake
),我这里仅仅使用cmake
构建,而且简化点,当然最重要的是支持CLion
直接运行调试。从Blob文件开始从头开始复制每一个类,能够自行把没有个模块给运行起来,并编写对于的测试代码,这样更能加深自己的理解。
阅读源码最好要从头搭建工程,把每个模块运行起来,可以实现简单的功能,不是直接复制源代码的文件,走马观花的看下代码就行的(这样理解代码也不会深刻)。
整个工程的构建如下(cmake
结合IDE CLion
):
下面简要的给出三个模块的构建:
cmake目录(包含FindGLog.cmake,FindOpenBLAS.cmake等),主要是获取第三方依赖的头文件以及lib文件。
整个工程的CMakeLists.txt,主要作用是使用1中的cmake获取相关的依赖给子目录、设置全局变量等。
src生产libcaffe_lib.a并输出到lib目录下,
main.cpp
以及其他的test
文件主要是测试每个类。
1. cmake目录
caffe的依赖较多,例如glog、protobuf、openblas、boost等,因此查找依赖的模块是每个单独的文件,以cmake为后缀。
下面简单给出FindOpencv.cmake,与FindGLog.cmake的内容。
FindOpencv.cmake内容很简单:
find_package(OpenCV REQUIRED)
message(in FindOpencv.cmake inc: ${OpenCV_INCLUDE_DIRS}, lib:${OpenCV_LIBS})
FindGLog.cmake的内容稍微复杂点:
include(FindPackageHandleStandardArgs)
if (NOT DEFINED GLOG_ROOT)
message("set GLOG_ROOT========================")
set (GLOG_ROOT /usr /usr/local /usr/include/)
endif (NOT DEFINED GLOG_ROOT)
#set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
find_path(GLOG_INCLUDE_DIR glog/logging.h
PATHS
${GLOG_ROOT_DIR}
PATH_SUFFIXES
src)
find_library(GLOG_LIBRARY glog libglog
PATHS
${GLOG_ROOT_DIR}
PATH_SUFFIXES
.libs
lib
lib64)
find_package_handle_standard_args(GLOG DEFAULT_MSG
GLOG_INCLUDE_DIR GLOG_LIBRARY)
if(GLOG_FOUND)
set(GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIR})
set(GLOG_LIBRARIES ${GLOG_LIBRARY})
message("GLOG_INCLUDE_DIRS ${GLOG_INCLUDE_DIRS}===========")
message("GLOG_LIBRARY ${GLOG_LIBRARY}===========")
endif()
本质就是返回对应的lib的头文件以及lib(so, .a)文件的路径。
# dependence lib
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
find_package(GLog REQUIRED)
find_package(Opencv REQUIRED)
在主CMakeLists.txt
中主要include对应的cmake
目录然后find_package
既可获取对应的lib的相关路径。
CLion
cmake
的输出如下:
2. 主CMakeLists.txt
内容如下:
cmake_minimum_required(VERSION 3.5)
project(my_caffe)
set(CMAKE_CXX_STANDARD 11)
# set variable for sub directory to use
set(INC_DIR "${CMAKE_SOURCE_DIR}/include")
set(LIB_OUTPUT_PATH "${CMAKE_SOURCE_DIR}/lib")
# dependence lib
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)
find_package(GLog REQUIRED)
find_package(ProtoBuf REQUIRED)
find_package(OpenBLAS REQUIRED)
find_package(Opencv REQUIRED)
add_subdirectory(src)
include_directories(${CMAKE_SOURCE_DIR}/src)
set(SOURCE_FILES main.cpp test_blob.h test_blob.cpp)
link_directories(${LIB_OUTPUT_PATH})
add_executable(my_caffe_test ${SOURCE_FILES})
target_link_libraries(my_caffe_test
/home/xy/caffe_analysis/my_caffe/lib/libcaffe_lib.a
${GLOG_LIBRARIES}
${PROTOBUF_LIBRARIES}
${OpenBLAS_LIB}
${OpenCV_LIBS}
-lcaffe_lib
)
3. src CMakeLists.txt
内容如下:
project(caffe_lib)
set(CMAKE_CXX_STANDARD 11)
aux_source_directory(. SRC)
add_library(caffe_lib ${SRC})
set_target_properties(
caffe_lib
PROPERTIES
ARCHIVE_OUTPUT_DIRECTORY "/home/xy/caffe_analysis/my_caffe/lib/"
LIBRARY_OUTPUT_DIRECTORY "/home/xy/caffe_analysis/my_caffe/lib/"
)
target_link_libraries(
caffe_lib
${GLOG_LIBRARIES}
${PROTOBUF_LIBRARIES}
${OpenBLAS_LIB}
${OpenCV_LIBS}
)
使用cmake(结合IDE CLion)搭建好工程后,代码的阅读与调试非常方便。C++ IED强烈建议大家使用CLion。接下来的内容是从Blob开始一个个模块分析caffe中的源代码。