Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 试图编译同时引用protobuffers 2.6.1和3.4.1的代码_C++_Cmake_Protocol Buffers_Ros - Fatal编程技术网

C++ 试图编译同时引用protobuffers 2.6.1和3.4.1的代码

C++ 试图编译同时引用protobuffers 2.6.1和3.4.1的代码,c++,cmake,protocol-buffers,ros,C++,Cmake,Protocol Buffers,Ros,我试图编译一个代码库,同时引用protobuffers 3.4.1和2.6.1。现在,2.6.1版本被全局定义为我使用的ubuntu xenial,并且: $ protoc --version 收益率: libprotoc 2.6.1 protobuffer版本3.4.1的要求来自Google Maptopher(),而2.6.1的要求来自rotors simulator(),因为它依赖于Gazebo-7(使用protobuffer 2.6.1)。为了编译Google制图器,我在安装中添加了

我试图编译一个代码库,同时引用protobuffers 3.4.1和2.6.1。现在,2.6.1版本被全局定义为我使用的ubuntu xenial,并且:

$ protoc --version
收益率:

libprotoc 2.6.1
protobuffer版本3.4.1的要求来自Google Maptopher(),而2.6.1的要求来自rotors simulator(),因为它依赖于Gazebo-7(使用protobuffer 2.6.1)。为了编译Google制图器,我在安装中添加了二进制文件(添加到proto3文件夹中,请参见下文),通过添加以下行修改Google制图器的CMakeList.txt(请参见此处的原始文件:):

set(CMAKE_PREFIX_PATH CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/proto3")
...
install(DIRECTORY proto3/ DESTINATION .)
因此,protobuffer 3.4.1的二进制文件被添加到安装文件夹中。我正在使用catkin工具()构建整个工作区。现在,在转子模拟器的CMakelist.txt中,我有以下行:

find_package(Protobuf 2.6.1 REQUIRED HINTS "/usr")
但目前在尝试编译时,它似乎无法找到protobuffer 2.4.1,因为它返回以下内容:

Could not find a configuration file for package "Protobuf" that is
compatible with requested version "2.6.1".

The following configuration files were considered but not accepted:

/home/jochem/catkin_ws/install/lib/cmake/protobuf/protobuf-config.cmake, 
version: 3.4.1
另外,如果我单独编译这些包,我就能够编译和安装这些包。这是通过以下命令完成的:

 catkin build cartographer_ros 


我目前正在尝试调整rotors_gazebo_插件包,但到目前为止未能确保选择了正确的protobuffer库,通过定义对本地protobuffer版本的引用,我是否遗漏了什么?

您会发现,在mac上构建一个引用同一库的两个版本的可执行文件是可能的,在windows上非常困难,在unix上几乎不可能。这是因为两个库之间的符号名称不明显,因此如果同时加载两个库,则无法知道哪个库应该为哪个调用提供服务

如果要在一个makefile包中构建两个不同的可执行文件,则只需设置要在链接阶段加载的正确库。在linux中,库通常安装在您的系统上,带有版本号后缀,以及发布最新版本而不带版本号的符号链接。通常,您只需链接到未加后缀的最新版本,但在您的情况下,在link命令中,您需要显式添加后缀


如果您真的需要将这些鹅卵石链接到一个可执行文件中,那么在unix上,您可以使用
objcopy——重新定义syms
来重命名其中一个库中的所有入口点,以及依赖代码中的所有引用—所有这些都是在编译之后,但在链接之前完成的。请注意,预期的最终结果是这两个库将独立运行,并且不会相互了解。

如果您能够将至少一个LIB(即制图器或转子或两者)打包到一个单独的共享库中,并且如果protobuff仅在每个库中内部使用,通过使用
-fvisibility=hidden
gcc标志构建共享lib(将默认可见性切换为隐藏符号),并通过
\uuu属性(可见性(“默认”))
仅导出所需的符号(应用程序正在使用),您仍然可以在单个可执行文件中使用它们


通过这种方式,我回忆起过去我能够在同一个应用程序中使用两个完全不同的Boost版本(通过共享库不导出静态链接的Boost符号).

我非常确定您将无法在同一应用程序中混合使用proto 2和proto 3。如果至少有一个模块通过共享库链接(技术上允许使用不同版本的依赖项,以及“-fvisibility=hidden”),则可能仍能在同一ap中工作,但如果所有模块都静态链接,则可能无法工作。
 catkin build rotors_gazebo_plugins