caffe:cmake编译指定glog,gflag路径

当使用cmake编译caffe的情况下,在 cmake生成Makefile时会自动找到系统安装的glog,gflag,但是如是我们自己编译了一个glog,gflag,并没有安装在(/usr)系统目录下,而是放在用户目录(/home)下,要想使用这个glog,gflag版本,不做处理cmake是找不到的。 要想在cmake编译caffe时指定glog,gflag路径,需要下面两步:

定义GLOG_ROOT_DIR,GFLAGS_ROOT_DIR参数

#$caffe_root caffe源码根目录 
cmake $caffe_root  -G "Unix Makefiles" \
    -DGLOG_ROOT_DIR=$glog_source_root \
    -DGFLAGS_ROOT_DIR=$gflags_source_root 

这里$glog_source_root,gflags_source_root 是指glog,gflag源码所在的文件夹。

修改FindGlog.cmake,FindGFlags.cmake

$caffe_root/cmake/Modules/下的FindGlog.cmake,FindGFlags.cmake中关于调用find_package寻找glog,gflag的代码有bug(目前还没修改),导致即使如上一步通过GLOG_ROOT_DIR,GFLAGS_ROOT_DIR指定了glog,gflag路径,cmake也不会找到该路径下的glog,gflag,如果你的/usr下安装了glog,gflag,它依然会找到系统路径下的版本。所以要对$caffe_root/cmake/Modules/下的FindGlog.cmake,FindGFlags.cmake做修改: FindGlog.cmake修改如下:

# modified by guyadong
set(GLOG_ROOT_DIR "" CACHE PATH "Folder contains Google glog")
if(WIN32)
    # 增加代码
    find_path(GLOG_INCLUDE_DIR glog/logging.h
        PATHS ${GLOG_ROOT_DIR}/src/windows NO_DEFAULT_PATH)

    find_path(GLOG_INCLUDE_DIR glog/logging.h
        PATHS ${GLOG_ROOT_DIR}/src/windows)
else()
    # 增加代码
    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()

if(MSVC)
    find_library(GLOG_LIBRARY_RELEASE libglog_static
        PATHS ${GLOG_ROOT_DIR}
        PATH_SUFFIXES Release NO_DEFAULT_PATH)

    find_library(GLOG_LIBRARY_RELEASE libglog_static
        PATHS ${GLOG_ROOT_DIR}
        PATH_SUFFIXES Release)

    find_library(GLOG_LIBRARY_DEBUG libglog_static
        PATHS ${GLOG_ROOT_DIR}
        PATH_SUFFIXES Debug NO_DEFAULT_PATH)

    find_library(GLOG_LIBRARY_DEBUG libglog_static
        PATHS ${GLOG_ROOT_DIR}
        PATH_SUFFIXES Debug)

    set(GLOG_LIBRARY optimized ${GLOG_LIBRARY_RELEASE} debug ${GLOG_LIBRARY_DEBUG})
else()
    # 增加代码
    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)
endif()

FindGFlags.cmake修改如下

# modified by guyadong
# 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 NO_DEFAULT_PATH)
    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}/include
                NO_DEFAULT_PATH)
    find_path(GFLAGS_INCLUDE_DIR gflags/gflags.h
        PATHS ${GFLAGS_ROOT_DIR}/include)
endif()

if(MSVC)
    # 增加代码
    find_library(GFLAGS_LIBRARY_RELEASE
        NAMES libgflags
        PATHS ${GFLAGS_ROOT_DIR}
        PATH_SUFFIXES Release NO_DEFAULT_PATH)

    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 NO_DEFAULT_PATH)

    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 PATHS ${GFLAGS_ROOT_DIR}/lib NO_DEFAULT_PATH)
    find_library(GFLAGS_LIBRARY gflags PATHS ${GFLAGS_ROOT_DIR}/lib)
endif()

比对原始代码 ,就可以发现,只是将每个find_library调用增加了NO_DEFAULT_PATH参数再执行一次

原因分析

这个问题的根本原因在于代码作者对cmake的find_library的查找机制没有全搞明白 简单说就是调用find_library时,会以从一组路径中顺序查找指定的库,这有一个优先序问题,如果没有指定了NO_DEFAULT_PATH,则会先查找默认的系统库路径 如果指定了NO_DEFAULT_PATH,则只查找PATHS提供的路径,不会查找系统库路径。因为所以原始代码中没有加NO_DEFAULT_PATH导致每次只能找到系统路径下的库。 如何保证PATHS指定的路径优先被搜索呢? 解决的办法cmake官网也给出来了,就是调用两次find_library,第一次加NO_DEFAULT_PATH,第二次则不加。

The default search order is designed to be most-specific to least-specific for common use cases. Projects may override the order by simply calling the command multiple times and using the NO_* options: find_library ( NAMES name PATHS paths… NO_DEFAULT_PATH) find_library ( NAMES name) Once one of the calls succeeds the result variable will be set and stored in the cache so that no call will search again.

另外,$caffe_root/cmake/Modules/下的FindLevelDB.cmake,FindLMDB.cmake,FindOpenBLAS.cmake,FindSnappy.cmake都存在相同的问题。解决办法是一样的。

参数资料

《find_library》

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏Android源码框架分析

Android权限检查API checkSelfPermission失效问题为什么targetSdkVersion < 23 Context 的 checkSelfPermission失效target

4553
来自专栏FreeBuf

EE 4GEE Mini本地提权漏洞(CVE-2018-14327)分析

我在前段时间从买了一个4G调制解调器。这是一个便携式4G WiFi移动宽带调制解调器。有一天,我查看了安装在电脑上的用于故障排除的服务,我看到了一个奇怪的服务,...

763
来自专栏杨建荣的学习笔记

三封报警邮件的分析(r6笔记第95天)

今天收到3封报警邮件,从邮件内容中的报警情况来看,还是比较反常的。需要引起关注,找到原因处理。 这个库是一个历史库,库中的数据非常庞大,几十亿数据的表还是有好几...

2734
来自专栏杨建荣的学习笔记

一次DB time抖动发现的expdp的bug(r6笔记第86天)

最近收到一封报警邮件,提示还是DB time突然提高,时间发生在早晨的时候,想必大过节的也不会有人这么卖力工作把数据库负载弄上去。 ############ D...

2974
来自专栏bboysoul

如何在metasploit中使用shodan

首先打开metasploit sudo service postgresql start msfconsole

1063
来自专栏gaoqin31

基于php+shell的发布系统

  一个比较完善的发布系统首先肯定是要能发布文件,其次当发布出现问题时要能支持撤销,避免长时间无法解决问题影响产品的正常运营。 对于发布脚本语言如PHP,she...

1022
来自专栏乐沙弥的世界

crs_register/crs_unregister 注册与移除RAC服务

    crs_register命令主要是将资源注册到CRS。该方法通常结合crs_stat -p 或者crs_profile先创建配置文件。同时crs_reg...

732
来自专栏乐沙弥的世界

Oracle RAC failover 测试(Server TAF方式)

    Oracle RAC中,除了基于客户端的TAF方式之外,还有基于服务器端的TAF方式,可以把服务端的TAF方式看作是客户端TAF方式的一个升级版吧。服务...

923
来自专栏何俊林

FFmpeg设置OpenMax硬件编码

OpenMax是一个统一的多媒体框架, ffmpeg中支持H264的OpenMax编码, 本文记录如何开启OpenMax编码。

1151
来自专栏向治洪

android PakageManagerService启动流程分析

PakageManagerService的启动流程图 ? 1.PakageManagerService概述 PakageManagerService是andro...

43510

扫码关注云+社区