Caffe: Could not find PROTOBUF Compiler(Profobuf 3.0 above)
2017-07-15 11:25
926 查看
在用cmake生成Caffe工程文件的时候,如果你使用Protobuf 3.0以上的版本,cmake可能会产生如下的报错:
CMake Error at cmake/ProtoBuf.cmake:18 (message):
Could not find PROTOBUF Compiler
Call Stack (most recent call first):
cmake/Dependencies.cmake:48 (include)
CMakeLists.txt:81 (include)
注意区分大小写
设置
这个办法的好处是不用修改caffe的代码
打开CMakeLists.txt,查找是否有类型下面这行代码
如果有,直接把后面的
如果没有,就在
“”包含的字符串只是描述信息,内容是什么不重要
进一步我们分析caffe_folder/cmake/ProtuBuf.cmake分析,如下代码,就能看到”Could not find PROTOBUF Compiler”这个错误信息的输出位置:
为什么
进一步我们追踪到protobuf_installation/cmake/protobuf-config.cmake,就能找到
Protobuf 3.0以后的版本采用imported target这种新的形式来为应用软件提供library和include dir.
以libprotobuf-lite库为例说明,
打开protobuf_installation/cmake/protobuf-targets.cmake,你会发现文件中有如下的代码
打开protobuf_installation/cmake/protobuf-targets-release.cmake,进一步还能找到如下的代码
这两段代码定义了一个IMPORTED 类型的target,名字叫
那么应用程序要使用libprotobuf-lite库,只需像以前一样调用 target_link_libraries将
也许你会问那还需要调用
不需要了,your_target指定连接一个imported target时,会自动把imported target的
关于imported-target的详细说明,参见 imported-targets
《imported-targets》
CMake Error at cmake/ProtoBuf.cmake:18 (message):
Could not find PROTOBUF Compiler
Call Stack (most recent call first):
cmake/Dependencies.cmake:48 (include)
CMakeLists.txt:81 (include)
解决办法
通过设置protobuf_MODULE_COMPATIBLE=on指定打开Protobuf的兼容模式。
注意区分大小写
设置
protobuf_MODULE_COMPATIBLE=on也有两种办法:
命令行添加
cmake生成Makefile时命令行添加-Dprotobuf_MODULE_COMPATIBLE=on,指定打开Protobuf兼容模式,类似下面的命令行:
d:\caffe> cmake -G "Visual Studio 12 2013 Win64" . -Dprotobuf_MODULE_COMPATIBLE=on
这个办法的好处是不用修改caffe的代码
修改CMakeLists.txt
也可以在直接修改Caffe根目录下的CMakeLists.txt打开CMakeLists.txt,查找是否有类型下面这行代码
caffe_option(protobuf_MODULE_COMPATIBLE "Make the protobuf-config.cmake compatible with the module mode" ON IF MSVC)
如果有,直接把后面的
IF MSVC删除,强制将protobuf_MODULE_COMPATIBLE 置为ON。
如果没有,就在
# ---[ Options后面添加一行,下面三种写法任选一行就可以
# 写法1 caffe_option(protobuf_MODULE_COMPATIBLE "Make the protobuf-config.cmake compatible with the module mode" ON) # 写法2 set (protobuf_MODULE_COMPATIBLE on CACHE BOOL "CMake build-in FindProtobuf.cmake module compatible" ) # 写法3 option(protobuf_MODULE_COMPATIBLE "CMake build-in FindProtobuf.cmake module compatible" ON)
“”包含的字符串只是描述信息,内容是什么不重要
问题溯源
产生这个问题的根本原因是Protobuf3.0以后的版本的cmake脚本默认不向下兼容。需要设置protobuf_MODULE_COMPATIBLE=on开启兼容模式。
进一步我们分析caffe_folder/cmake/ProtuBuf.cmake分析,如下代码,就能看到”Could not find PROTOBUF Compiler”这个错误信息的输出位置:
find_package( Protobuf REQUIRED NO_MODULE) set(PROTOBUF_INCLUDE_DIR ${PROTOBUF_INCLUDE_DIRS}) list(APPEND Caffe_INCLUDE_DIRS PUBLIC ${PROTOBUF_INCLUDE_DIR}) list(APPEND Caffe_LINKER_LIBS PUBLIC ${PROTOBUF_LIBRARIES}) # As of Ubuntu 14.04 protoc is no longer a part of libprotobuf-dev package # and should be installed separately as in: sudo apt-get install protobuf-compiler if(EXISTS ${PROTOBUF_PROTOC_EXECUTABLE}) message(STATUS "Found PROTOBUF Compiler: ${PROTOBUF_PROTOC_EXECUTABLE}") else() # 没有找到 protoc(.exe)可执行文件,就报错 message(FATAL_ERROR "Could not find PROTOBUF Compiler") endif()
为什么
PROTOBUF_PROTOC_EXECUTABLE会没有定义呢?
进一步我们追踪到protobuf_installation/cmake/protobuf-config.cmake,就能找到
protobuf_MODULE_COMPATIBLE这个变量真正起作用的位置(protobuf_installation是你的ProtuBuf安装的位置):
# User options include("${CMAKE_CURRENT_LIST_DIR}/protobuf-options.cmake") # Depend packages # Imported targets include("${CMAKE_CURRENT_LIST_DIR}/protobuf-targets.cmake") # CMake FindProtobuf module compatible file if(protobuf_MODULE_COMPATIBLE) # 加载 兼容旧版本的脚本,生成MODULE模式下的变量PROTOBUF_INCLUDE_DIRS PROTOBUF_LIBRARIES...等等 # 参见 https://cmake.org/cmake/help/v3.8/module/FindProtobuf.html # 也就是protobuf-module.cmake 这个脚本才会定义 Protobuf_PROTOC_EXECUTABLE 这个变量 include("${CMAKE_CURRENT_LIST_DIR}/protobuf-module.cmake") endif()
延伸阅读 : Imported Target
那么你也许会问,如果不设置protobuf_MODULE_COMPATIBLE=on要如何使用ProtoBuf 3.0的库呢?
Protobuf 3.0以后的版本采用imported target这种新的形式来为应用软件提供library和include dir.
以libprotobuf-lite库为例说明,
打开protobuf_installation/cmake/protobuf-targets.cmake,你会发现文件中有如下的代码
add_library(protobuf::libprotobuf-lite STATIC IMPORTED) set_target_properties(protobuf::libprotobuf-lite PROPERTIES # 指定 include 文件夹 INTERFACE_INCLUDE_DIRECTORIES "${_IMPORT_PREFIX}/include" )
打开protobuf_installation/cmake/protobuf-targets-release.cmake,进一步还能找到如下的代码
# Import target "protobuf::libprotobuf-lite" for configuration "release" set_property(TARGET protobuf::libprotobuf-lite APPEND PROPERTY IMPORTED_CONFIGURATIONS RELEASE) set_target_properties(protobuf::libprotobuf-lite PROPERTIES IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX" # 指定 library 的位置 IMPORTED_LOCATION_RELEASE "${_IMPORT_PREFIX}/lib/libprotobuf-lite.lib" )
这两段代码定义了一个IMPORTED 类型的target,名字叫
protobuf::libprotobuf-lite,target的属性中定义了include文件夹的位置以及库的位置。
那么应用程序要使用libprotobuf-lite库,只需像以前一样调用 target_link_libraries将
protobuf::libprotobuf-lite添加 到依赖库列表中就可以了。
target_link_libraries( your_target,protobuf::libprotobuf-lite)
也许你会问那还需要调用
include_directories添加protobuf的include_dir么?
不需要了,your_target指定连接一个imported target时,会自动把imported target的
INTERFACE_INCLUDE_DIRECTORIES属性指定的include文件夹加到your_target的include文件夹列表中的。
关于imported-target的详细说明,参见 imported-targets
参考资料
《Using find_package(Protobuf) with 3.0.0》《imported-targets》
相关文章推荐
- 出现错误:ERROR: no such package '@protobuf//src/google/protobuf': Could not find handler for bind rule /
- gmp4.3.2 安装 configure: error: could not find a working compiler
- gmp4.3.2 安装时 ./configure报错: error: could not find a working compiler
- Android studio 升级3.0后ReactNative 打包报错 Could not find com.android.tools.build:gradle:3.0.0.
- 转:could not find the main class, Program will exit (说明编译器compiler版本要不高于installed JREs,JVM版本)
- compile android for x86_64 - ccache: FATAL: Could not find compiler "arm-eabi-gcc" in PATH
- Spyder在Windows环境下出现RuntimeError: Could not open file ../caffe/deploy.prototxt
- 升级Rails3.0后出现这样的问题。Could not find gem 'mysql2 ....
- android studio 3.0升级 问题 Could not find commons-codec.jar (commons-codec:commons-codec:1.6).
- Spyder在Windows环境下出现RuntimeError: Could not open file ../caffe/deploy.prototxt
- maven-compiler-plugin:3.5.2 or one of its dependencies could not be resolved: Failure to find org.ap
- Could not find the main class program will exit的终极解决办法,神坑
- 处理TNS-01101: Could not find service name LISTENER_SCAN1
- Could not find parameter map
- Could not find parameter map java.lang.Long
- caffe_.mexa64: undefined symbol:protobuf8internal10WireFormat 分析思路与解决方案
- !include: could not find: "nsProcess.nsh"
- org.hibernate.PropertyNotFoundException: Could not find a getter for
- struts2中报“ Could not find action or result”
- Could not find generator devise:install.