Windows下基于CMake编译配置官方Caffe/Caffe-SSD

Windows下基于CMake编译配置Caffe/SSD

by ChrisZZ, imzhuo@foxmail.comc++

简要说明

最近须要在Windows下开发,在Windows下基于CMake编译配置了Caffe/PyCaffe,记录一下。git

特色:github

  • 能够修改caffe依赖库存放目录
  • 能够指定opencv版本
  • 能够用于1080Ti等显卡的正确编译
  • 给出了基于CMake调用Caffe.lib的例子
  • 使用caffe.lib的项目中也可调试到caffe源码中
  • 支持caffe-SSD,包括boost regex报错的正确处理

1. 环境说明

系统: Win7/Win10
编译器:Visual Studio 2013
构建器:CMake 3.13
Python: python2.7,用anaconda装的。注意python.exe所在目录放到系统PATH环境变量中。
CUDA: 9.2 (可选)
CuDNN:7.0(可选)
终端: cmd窗口
Caffe源码: 官方Caffe的windows分支 。后续考虑SSD代码算法

2. 配置官方Caffe

2.1 下载Caffe源码和Windows依赖包

Caffe源码
进cmd敲:express

d:
cd work
git clone https://github.com/BVLC/caffe caffe-BVLC
cd caffe-BVLC
git checkout -b windows origin/windows

或者从官方网页 下载压缩包。windows

Caffe的Windows依赖包
源码中cmake脚本里会自动下载依赖包,但为了不cmake下载遭遇网络问题,以及修改配置项的方便,根据scripts/download_prebuilt_dependencies.py手动下载依赖文件:
(若是你网路还能够,那么忽略这一小节,脚本会自动下载)网络

WIN_DEPENDENCIES_URLS = {
    ('v120', '2.7'):("https://github.com/willyd/caffe-builder/releases/download/v1.1.0/libraries_v120_x64_py27_1.1.0.tar.bz2",
                  "ba833d86d19b162a04d68b09b06df5e0dad947d4"),
    ('v140', '2.7'):("https://github.com/willyd/caffe-builder/releases/download/v1.1.0/libraries_v140_x64_py27_1.1.0.tar.bz2",
                  "17eecb095bd3b0774a87a38624a77ce35e497cd2"),
    ('v140', '3.5'):("https://github.com/willyd/caffe-builder/releases/download/v1.1.0/libraries_v140_x64_py35_1.1.0.tar.bz2",
                  "f060403fd1a7448d866d27c0e5b7dced39c0a607"),
}

依赖包存放目录:架构

  • 默认方式下,放到C:\Users\<UserName>\.caffe\dependencies\download\目录。app

  • 若是怕C盘空间占用,也能够在别的目录存放依赖包,后续CMake阶段指定-DCAFFE_DEPENDENCIES_ROOT_DIR=xxx便可,例如我放到了D:/lib/caffe_windows_deps/download/libraries_v120_x64_py27_1.1.0.tar.bz2

  • 为了方便讨论,咱们把C:\Users\<UserName>\.caffe\dependencies目录或D:/lib/caffe_windows_deps/记作CAFFE_DEPENDENCIES_ROOT_DIR

2.2 修改cuda配置(可选)

cpu模式编译的调过这一小节。

cmake/Cuda.cmake,第7行,去掉20和21的算力支持(不然新版cuda会报错),改为:

set(Caffe_known_gpu_archs "30 35 50 52 60 61")

cmake/Cuda.cmake,第40行左右,手动设定nvcc架构版本,例如我是1080Ti显卡,使用6.1:

# if(__nvcc_res EQUAL 0)
    #   # nvcc outputs text containing line breaks when building with MSVC.
    #   # The line below prevents CMake from inserting a variable with line
    #   # breaks in the cache
    #   string(REGEX MATCH "([1-9].[0-9])" __nvcc_out "${__nvcc_out}")
    #   string(REPLACE "2.1" "2.1(2.0)" __nvcc_out "${__nvcc_out}")
    #   set(CUDA_gpu_detect_output ${__nvcc_out} CACHE INTERNAL "Returned GPU architetures from caffe_detect_gpus tool" FORCE)      
    # endif()
    set(__nvcc_out "6.1")

(为啥这里的自动获取计算能力版本有问题?大概是字符编码致使输出不少警告,警告信息影响了正确结果的获取)
(每一个Nvidia显卡型号对应的compute ability表见:https://blog.csdn.net/real_myth/article/details/44308169)

CAFFE_DEPENDENCIES_ROOT_DIR目录下的libraries_v120_x64_py27_1.1.0\libraries\include\boost-1_61\boost\config\compiler\nvcc.hpp:注释掉最后三行:

#if !defined(__CUDACC_VER__) || (__CUDACC_VER__ < 70500)
#   define BOOST_NO_CXX11_VARIADIC_TEMPLATES
#endif

(缘由:cuda7.5之后,__CUDACC_VER__被废除,应当使用__CUDACC_VER_MAJOR___CUDACC_VER_MINOR__等,若是不注释掉,会报错:

libraries_v140_x64_py35_1.1.0/libraries/include/boost-1_61\boost/config/compiler/nv
cc.hpp(22): fatal error C1017: invalid integer constant expression

参考https://github.com/BVLC/caffe/issues/599四、https://blog.csdn.net/qq_37817177/article/details/80604294)。

2.3 使用官方提供的步骤编译

这种方式下,调用的是.\scripts\build_win.cmd脚本,CMake依赖包必须放到C:\Users\<UserName>\.caffe\dependencies\download\目录。缺点是:
1.浪费C盘空间;

2.定制项被写死了,不灵活。
例如opencv版本被限定死了为3.1。例如imread读取jpg在[3.0.0, 3.4.1]版本区间内的结果是一种,在2.4.x和>=3.4.2版本中的结果是另外一种,输入数据的不一致会致使卷积网计算结果不一致。

所以,这种方式主要适合小白入门用用,实际项目开发中不方便。其具体操做为:

回到刚才的cmd,继续敲(#后面是注释,不用敲进去)

set PATH=%PATH%;C:\Windows\Microsoft.NET\Framework\v4.0.30319  #临时添加MSBuild.exe的路径
set MSVC_VERSION=12 #12对应到我用的vs2013.  build_win.cmd中默认为vs2015,也就是13
set WITH_NINJA=0  # 不使用ninja,用visual studio。由于编译中间出了问题在vs里面好查看。
# set CPU_ONLY=1  # 若是没有GPU,或者就是想编译CPU版本,则开启
set RUN_INSTALL=1 #安装。默认走的非appveyor分支,RUN_INSTALL为0,这不是坑人么。

.\scripts\build_win.cmd # 前面我写明的修改项都完成后,本行会顺利执行。

编译期间出现“锟斤拷”的乱码能够忽略,最后:
成功编译

成功编译和安装

build_win.cmd脚本中的设定,默认编译的是release模式的。修改脚本,或者干脆打开cmake生成的build/Caffe.sln工程来编译debug版本。

2.4 手动CMake构建,使用官方依赖包

.\scripts\build_win.cmd脚本包含了太多内容,对于本地开发来讲没有用还干扰视线。

caffe根目录下建立编辑compile-xxx.bat脚本,手动调用CMake,简化流程。

vs2013, cpu模式,使用官方依赖包
compile-vs2013-cpu.bat

set BUILD_DIR=build-vs2013
if exist %BUILD_DIR% rd /s /q %BUILD_DIR%
md %BUILD_DIR%
cd %BUILD_DIR%

set DEP_ROOT=F:/zhangzhuo/lib/caffe_windows_deps

cmake -G "Visual Studio 12 2013 Win64" ^
    -DCAFFE_DEPENDENCIES_ROOT_DIR=%DEP_ROOT% ^
    -DCPU_ONLY=ON ^
    -DBLAS=Open ^
    ..

cd ..

vs2013, 手工指定opencv目录、动态库
opencv249的windows pack同时提供动态共享库和静态库,默认静态库。编译caffe须要共享库,须要手动开启:OpenCV_STATIC=OFF

set BUILD_DIR=build-vs2013-opencv249
if exist %BUILD_DIR% rd /s /q %BUILD_DIR%
md %BUILD_DIR%
cd %BUILD_DIR%

set DEP_ROOT=D:/lib/caffe_windows_deps
set OpenCV_DIR=D:/lib/opencv_249/build

cmake -G "Visual Studio 12 2013 Win64" ^
    -DCAFFE_DEPENDENCIES_ROOT_DIR=%DEP_ROOT% ^
    -DCPU_ONLY=ON ^
    -DBLAS=Open ^
    -DOpenCV_DIR=%OpenCV_DIR% ^
    -DOpenCV_STATIC=OFF ^
    ..

cd ..

opencv310windows pack只提供了动态库,因此不用指定-DOpenCV_STATIC=OFF

set BUILD_DIR=build-vs2013-opencv310
if exist %BUILD_DIR% rd /s /q %BUILD_DIR%
md %BUILD_DIR%
cd %BUILD_DIR%

set DEP_ROOT=F:/zhangzhuo/lib/caffe_windows_deps
set OpenCV_DIR=F:/zhangzhuo/lib/opencv_310/build

cmake -G "Visual Studio 12 2013 Win64" ^
    -DCAFFE_DEPENDENCIES_ROOT_DIR=%DEP_ROOT% ^
    -DCPU_ONLY=ON ^
    -DBLAS=Open ^
    -DOpenCV_DIR=%OpenCV_DIR% ^
    ..

cd ..

执行完compile-xxx.bat脚本后,打开生成的.sln文件,分别Release和Debug模式,执行CMakeTargets/INSTALL

2.5 配置pycaffe

若是系统只有一个pycaffe版本
方便点,把build/install/python/caffe文件夹,拷贝到D:\soft\Anaconda2\Lib下。之后再开VSCode时,import caffe不再会报红了。

系统有多个版本的pycaffe

#coding: utf-8
import sys
sys.path.insert(0, '/path/to/caffe/build/pycaffe')

3. 配置Caffe-SSD

目标检测算法SSD,其论文做者官方代码是基于Caffe的魔改版本,我称其为Caffe-SSD。在Windows上基于CMake编译Caffe-SSD,步骤与Caffe-BVLC的windows分支思路一致,都须要排查编译错误、修改少许源码从而编译成功。在前面一步中成功的在Windows下基于CMake和官方依赖包进行构建的基础上,编译配置Caffe-SSD不难,步骤以下:

3.1 下载代码、依赖项

cd /d/work
git clone https://github.com/weiliu89/caffe caffe-SSD
cd caffe-SSD
git checkout -b ssd origin/ssd

依赖包的话,使用Caffe-BVLC官方windows分支的依赖包,下载地址、存放目录见前一节。

3.2 替换CMake脚本

鉴于Caffe-BVLC的windows分支已经为windows适配作了不少,这里直接拿来用。从Caffe-BVLC的windows分支里,拷贝并替换下列文件到Caffe-SSD中:

  • 整个cmake子目录
  • 根目录CMakeLists.txt
  • src/caffe/CMakeLists.txt
  • src/gtest/CMakeLists.txt
  • tools/CMakeLists.txt
  • python/CMakeLists.txt

3.3 编写编译脚本

参考本文 2.4小节 "手动CMake构建,使用官方依赖包"。

3.4 CPU编译相关的报错和解决办法

我遇到的编译报错和解决办法以下。若是你但愿省时间,那么先按照个人解决方案改一遍再编译;若是你但愿体验自行修改Caffe-SSD以在windows下成功编译的快感,不妨先编译,遇到报错按照我下面的方法来修改。(我的仍是比较推崇reproducable的modification的

D:\work\caffe-SSD\src\caffe\common.cpp(36): error C3861: “getpid”: 找不到标识符

解决办法:common.cpp添加

#ifdef _MSC_VER
#include <process.h>
#endif

fatal error C1083: 没法打开包括文件: “gtest/gtest.h”: No such file or directory

解决办法:net.cpp,注释掉:

//#include "caffe/test/test_caffe_main.hpp"

error C3861: “snprintf”: 找不到标识符

解决办法:bbox_util.hpp添加:

#ifdef _MSC_VER
#define snprintf _snprintf
#endif

error C3861: “mkdir”: 找不到标识符

解决办法:在db_lmdb.cpp头部添加:

#if defined(_MSC_VER)
#include <direct.h>
#define mkdir(X, Y) _mkdir(X)
#endif

src\caffe\util\hdf5.cpp(34): error C2360: “occurrences_32”的初始化操做由“case”标签跳过

缘由:使用的LOG_FIRST_N宏,逐层展开后有定义变量。在switch-case的case后若是定义了变量,应当使用花括号包起来。
解决办法:
src/caffe/util/hdf5.cpp中找到LOG_FIRST_N宏,使用花括号包裹case后的语句块:

case H5T_INTEGER:
      LOG_FIRST_N(INFO, 1) << "Datatype class: H5T_INTEGER";
      break;
case H5T_INTEGER:
  {
      LOG_FIRST_N(INFO, 1) << "Datatype class: H5T_INTEGER";
  }
  break;

src\caffe\util\io.cpp(44): error C3861: “open”: 找不到标识符

解决办法:src/caffe/util/io.cpp#include <fcntl.h>后添加:

#if defined(_MSC_VER)
#include <io.h>
#endif

src\caffe\util\signal_handler.cpp(16): error C2065: “SIGHUP”: 未声明的标识符
解决办法:src/caffe/util/signal_handler.cpp,16行开始几行,原有的:

case SIGHUP:
      got_sighup = true;
      break;

修改成:

#ifdef _MSC_VER
    case SIGBREAK:  // there is no SIGHUP in windows, take SIGBREAK instead.
      got_sighup = true;
      break;
#else
    case SIGHUP:
      got_sighup = true;
      break;
#endif

src\caffe\util\signal_handler.cpp(37): error C2079: “sa”使用未定义的 struct“`anonymous-namespace'::HookupHandler::sigaction”

解决办法:src/caffe/util/signal_handler.cpp,37行开始几行,原有的:

struct sigaction sa;
    // Setup the handler
    sa.sa_handler = &handle_signal;
    // Restart the system call, if at all possible
    sa.sa_flags = SA_RESTART;
    // Block every signal during the handler
    sigfillset(&sa.sa_mask);
    // Intercept SIGHUP and SIGINT
    if (sigaction(SIGHUP, &sa, NULL) == -1) {
      LOG(FATAL) << "Cannot install SIGHUP handler.";
    }
    if (sigaction(SIGINT, &sa, NULL) == -1) {
      LOG(FATAL) << "Cannot install SIGINT handler.";
    }

修改成:

#ifdef _MSC_VER
    if (signal(SIGBREAK, handle_signal) == SIG_ERR) {
      LOG(FATAL) << "Cannot install SIGBREAK handler.";
    }
    if (signal(SIGINT, handle_signal) == SIG_ERR) {
      LOG(FATAL) << "Cannot install SIGINT handler.";
    }
#else
    struct sigaction sa;
    // Setup the handler
    sa.sa_handler = &handle_signal;
    // Restart the system call, if at all possible
    sa.sa_flags = SA_RESTART;
    // Block every signal during the handler
    sigfillset(&sa.sa_mask);
    // Intercept SIGHUP and SIGINT
    if (sigaction(SIGHUP, &sa, NULL) == -1) {
      LOG(FATAL) << "Cannot install SIGHUP handler.";
    }
    if (sigaction(SIGINT, &sa, NULL) == -1) {
      LOG(FATAL) << "Cannot install SIGINT handler.";
    }
#endif

一样的,UnhookHandler函数也作相似修改:原来的:

struct sigaction sa;
        // Setup the sighub handler
        sa.sa_handler = SIG_DFL;
        // Restart the system call, if at all possible
        sa.sa_flags = SA_RESTART;
        // Block every signal during the handler
        sigfillset(&sa.sa_mask);
        // Intercept SIGHUP and SIGINT
        if (sigaction(SIGHUP, &sa, NULL) == -1) {
            LOG(FATAL) << "Cannot uninstall SIGHUP handler.";
        }
        if (sigaction(SIGINT, &sa, NULL) == -1) {
            LOG(FATAL) << "Cannot uninstall SIGINT handler.";
        }

修改成:

#ifdef _MSC_VER
        if (signal(SIGBREAK, SIG_DFL) == SIG_ERR) {
            LOG(FATAL) << "Cannot uninstall SIGBREAK handler.";
        }
        if (signal(SIGINT, SIG_DFL) == SIG_ERR) {
            LOG(FATAL) << "Cannot uninstall SIGINT handler.";
        }
#else
        struct sigaction sa;
        // Setup the sighub handler
        sa.sa_handler = SIG_DFL;
        // Restart the system call, if at all possible
        sa.sa_flags = SA_RESTART;
        // Block every signal during the handler
        sigfillset(&sa.sa_mask);
        // Intercept SIGHUP and SIGINT
        if (sigaction(SIGHUP, &sa, NULL) == -1) {
            LOG(FATAL) << "Cannot uninstall SIGHUP handler.";
        }
        if (sigaction(SIGINT, &sa, NULL) == -1) {
            LOG(FATAL) << "Cannot uninstall SIGINT handler.";
        }
#endif

LINK : fatal error LNK1149: 输出文件名匹配输入文件名“D:\work\caffe-SSD\build-vs2013-opencv249\lib\Debug\caffe-d.lib”

报错的意思是,目标输出的文件与输入的文件重名了。
解决办法:使用caffe-BVLC-windows/tools/CMakeLists.txt进行替换

**common.obj) : error LNK2019: 没法解析的外部符号 "__declspec(dllimport) void __cdecl google::InstallFailureSignalHandler(void**
解决办法:
common.cpp,56行左右,原来的:

::google::InstallFailureSignalHandler();

修改成:

#if !defined(_MSC_VER)
  ::google::InstallFailureSignalHandler();
#endif

LINK : fatal error LNK1104: 没法打开文件“python27_d.lib”
缘由:间接的包含了pyconfig.h(anaconda安装路径下的),这个文件里面有这样几行:

#           ifdef _DEBUG
#               pragma comment(lib,"python27_d.lib")
#           else
#               pragma comment(lib,"python27.lib")
#           endif /* _DEBUG */

看到网上有人说“修改pyconfig.h”,显然这没有必要也不正确。

解决方法:
_caffe.cpp,去掉第一行的:

#include <Python.h>  // NOLINT(build/include_alpha)

Python.h会间接的包含pyconfig.h致使引入python27_d.lib

若是你是VS2015,那么极可能还须要在_caffe.cpp中,#define BP_REGISTER_SHARED_PTR_TO_PYTHON(PTR)后面,添加这个:

#if defined(_MSC_VER) && (_MSC_FULL_VER >= 190024210)
// Workaround for VS 2015 Update 3 which breaks boost python
// See: http://stackoverflow.com/questions/38261530/unresolved-external-symbols-since-visual-studio-2015-update-3-boost-python-link
// and https://msdn.microsoft.com/vs-knownissues/vs2015-update3
#define BP_GET_POINTER(cls) \
namespace boost { \
template <> \
const volatile caffe::cls * \
get_pointer(const volatile caffe::cls *c) { \
    return c; \
} \
}

#define BP_GET_POINTER_T(cls, dtype) BP_GET_POINTER(cls<dtype>)

// forward declare the NCCL class
// in case we are not using NCCL
namespace caffe {
template <typename Dtype> class NCCL;
}

BP_GET_POINTER_T(Net, float);
BP_GET_POINTER_T(Layer, float);
BP_GET_POINTER_T(Solver, float);
BP_GET_POINTER_T(SGDSolver, float);
BP_GET_POINTER_T(NesterovSolver, float);
BP_GET_POINTER_T(AdaGradSolver, float);
BP_GET_POINTER_T(RMSPropSolver, float);
BP_GET_POINTER_T(AdaDeltaSolver, float);
BP_GET_POINTER_T(AdamSolver, float);
BP_GET_POINTER_T(NCCL, float);
BP_GET_POINTER(Timer);

#endif

3.5 GPU(cuda)编译相关的报错和解决办法

src/caffe/layers/bnll_layer.cu(35): error : identifier "caffe::kBNLL_THRESHOLD" is undefined in device code
解决办法:
修改kBNLL_THRESHOLD的定义,从:

const float kBNLL_THRESHOLD = 50.;

修改成

#ifdef _MSC_VER
__constant__ float kBNLL_THRESHOLD = 50.;
#else
const float kBNLL_THRESHOLD = 50.;
#endif

libraries_v120_x64_py27_1.1.0\libraries\include\boost-1_61\boost/regex/v4/perl_matcher.hpp(362): error C2292: 'boost::re_detail_106100::perl_matcher<const char ,std::allocator<boost::sub_match<const char >>,boost::regex_traits<char,boost::w32_regex_traits >>': best case inheritance representation: 'virtual_inheritance' declared but 'single_inheritance' required

这个错误,网上绝大多数博客给出的解决办法是“注释掉regex和rv相关的代码”。但我以为这就像是“干掉了提出问题的人”,过于粗暴。个人解决办法:
在caffe windows依赖包中修改libraries_v120_x64_py27_1.1.0\libraries\include\boost-1_61\boost\regex\v4\perl_matcher.hpp文件:
#include <boost/regex/v4/iterator_category.hpp>后,添加:

#ifdef _MSC_VER
#pragma pointers_to_members( full_generality, single_inheritance )
#endif

解释一下:

MSDN上对于pointer_to_memmers的解释 提到,其语法为:

#pragma pointers_to_members( pointer-declaration, [most-general-representation] )

而且,most-general-representation的默认值为best_case
经过google检索#pragma pointers_to_members发现,这个宏应该是cl.exe特有的,gcc的话我没有找到,llvm的话彷佛有人提issue要去实现。

以上是我遇到的编译报错和解决方法。所有修改掉后,Visual Studio里分别在Debug和Release模式下执行"CMakeTargets/INSTALL"这一目标,完成编译和安装。


4. 在C++项目中使用Caffe

好比不想在原始的caffe工程中添加本身的代码,这样保持了caffe自身代码不变,只要在本身的使用了caffe库的工程中正确设定,就独立的开发本身的代码了。

假设本身的这个工程也是基于cmake构建,最关键的一点是,正确配置了前面编译的caffe的依赖项,而不是本身再去从新配一遍..

注意使用caffe-builder-config.cmake文件

set(CAFFE_DEPENDENCIES_DIR "C:/Users/Administrator/.caffe/dependencies/libraries_v120_x64_py27_1.1.0")
include(${CAFFE_DEPENDENCIES_DIR}/libraries/caffe-builder-config.cmake)

注意opencv版本一致
编译Caffe用的opencv版本,和须要使用caffe.lib的项目中的opencv版本,应当保持一致。

样例CMakeLists.txt

cmake_minimum_required(VERSION 3.1)

project(caffe_cpp_play)
set (CMAKE_CXX_STANDARD 11)

#--- caffe dependencies ---
set(CAFFE_DEPENDENCIES_DIR "D:/work/caffe_windows_deps/libraries_v120_x64_py27_1.1.0")
include(${CAFFE_DEPENDENCIES_DIR}/libraries/caffe-builder-config.cmake)

set(PROJ_LINKER_LIBS "")
set(PROJ_INCLUDE_DIR "")

set(CMAKE_VERBOSE_MAKEFILE OFF)


# --- options ---
option(use_opencv "Use OpenCV?" ON)
option(use_cuda "Use CUDA?" OFF)
option(use_glog "Use Glog?" ON)
option(use_gflags "Use GFlags?" ON)
option(use_protobuf "Use Protobuf?" ON)
option(use_caffe "Use Caffe?" ON)
option(use_boost "Use Boost?" ON)

# --- pthread ---
# windows does not need it
#find_package(Threads REQUIRED)
#message("CMAKE_THREAD_LIBS_INIT: ${CMAKE_THREAD_LIBS_INIT}")


# --- opencv ---
if (use_opencv)
    list(APPEND CMAKE_PREFIX_PATH "D:/lib/opencv_249/build")
    find_package(OpenCV REQUIRED)
    message(STATUS "OpenCV library status:")
    message(STATUS "    version: ${OpenCV_VERSION}")
    message(STATUS "    libraries: ${OpenCV_LIBS}")
    message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")
    list(APPEND PROJ_LINKER_LIBS ${OpenCV_LIBS})
endif()


# --- cuda ---
if (use_cuda)
    if (CMAKE_SYSTEM_NAME MATCHES "Windows")
    set(CUDA_DIR "$ENV{CUDA_PATH}")
    else()
        set(CUDA_DIR "/usr/local/cuda")
    endif()
    find_package(CUDA REQUIRED)
    include_directories(${CUDA_DIR}/include)
endif()


#--- Glog & GFlags & Protobuf ---
if (use_glog)
    find_package (Glog REQUIRED)         #OK
    list(APPEND PROJ_LINKER_LIBS ${GLOG_LIBRARIES})
endif()
if (use_gflags)
    find_package (GFlags REQUIRED)       #OK
    list(APPEND PROJ_LINKER_LIBS ${GFLAGS_LIBRARIES})
endif()
if (use_protobuf)
    find_package(Protobuf REQUIRED)      #OK
    list(APPEND PROJ_LINKER_LIBS ${PROTOBUF_LIBRARIES})
endif()


#--- caffe ---
if (use_caffe)
    list(APPEND CMAKE_PREFIX_PATH "D:/work/caffe-BVLC/build-vs2013-opencv249-cuda/install")
    find_package (Caffe REQUIRED)       #OK
    message(STATUS "Caffe library status:")
    message(STATUS "    Caffe_DIR: ${Caffe_DIR}")
    message(STATUS "    Caffe_LIBRARIES: ${Caffe_LIBRARIES}")
    message(STATUS "    CAFFE_INCLUDE_DIRS: ${Caffe_INCLUDE_DIRS}")
    list(APPEND PROJ_LINKER_LIBS ${Caffe_LIBRARIES})
endif()

# --- boost ---
if (use_boost)
    find_package(Boost 1.54 REQUIRED COMPONENTS system thread filesystem regex)
    message(STATUS "Boost library status:")
    message(STATUS "    Boost_INCLUDE_DIRS: ${Boost_INCLUDE_DIRS}")
    message(STATUS "    Boost_LIBRARIES: ${Boost_LIBRARIES}")
    list(APPEND PROJ_LINKER_LIBS ${Boost_LIBRARIES})
endif()


# 添加头文件搜索路径
include_directories(${Caffe_INCLUDE_DIRS})


# 添加可执行文件
add_executable(net_demo src/net_demo.cpp)

# Link your application with OpenCV libraries
target_link_libraries(net_demo ${PROJ_LINKER_LIBS})

完整的例子见:
https://github.com/zchrissirhcz/z-toolbox/tree/master/cmake_examples/caffe_cpp_play_better

值得注意的是:前面编译出来的caffe-BVLC的,其构建类型要与本身的工程一致,也就是debug搭配debug,release搭配release。我这里实验发现debug模式下个别库名字不对,缺乏“d”或者"-d",在Visual Studio里手动改一下就能够了。

5. reference

caffe_pvanet,cuda7.5,VS2013

6. changelog

2018-08-24 23:35:41 建立博客,支持Caffe-BVLC Windows分支的编译 2019-04-06 11:58:08 增长”指定opencv版本和依赖包路径“相关内容 2019-04-07 14:49:58 增长Caffe-SSD的Windows CPU编译 2019-04-12 09:13:11 增长Caffe-SSD的Windows GPU编译

相关文章
相关标签/搜索