我正在尝试编译单个代码库,引用protobuffers 3.4.1和2.6.1。现在2.6.1变体是全局定义的,因为我使用的是ubuntu xenial,也是:
$ protoc --version
的产率:
libprotoc 2.6.1
protobuffer版本3.4.1的要求来自Google Cartographer(https://github.com/googlecartographer/cartographer),而2.6.1的要求来自转子模拟器(https://github.com/ethz-asl/rotors_simulator),因为它依赖于Gazebo-7(使用它) protobuffer 2.6.1)。为了编译Google Cartographer,我已经通过添加以下内容为Google Cartographer调整CMakeList.txt(请参阅此处的原始文件:https://raw.githubusercontent.com/googlecartographer/cartographer/master/CMakeLists.txt),将二进制文件(在proto3文件夹中添加,见下文)添加到安装中行:
set(CMAKE_PREFIX_PATH CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/proto3")
...
install(DIRECTORY proto3/ DESTINATION .)
因此,protobuffer 3.4.1的二进制文件被添加到安装文件夹中。我正在利用catkin-tools(https://catkin-tools.readthedocs.io/en/latest/)来构建整个工作区。现在在转子模拟器的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
和
catkin build rotors_gazebo_plugins
我目前正在尝试调整rotors_gazebo_plugins的包,但到目前为止还没有成功确保选择了正确的protobuffer库,我是否通过定义对本地protobuffer版本的引用而遗漏了一些东西?
答案 0 :(得分:1)
你会发现可以在mac上构建一个引用同一个库的2个版本的单个可执行文件,在windows上相当困难,而在unix上几乎不可能。这是因为两个库之间的符号名称不同,所以如果你加载这两个库,就无法知道哪个库应该为哪个调用服务。
如果要在一个makefile包中构建2个不同的可执行文件,那么您只需要在链接阶段设置要加载的正确库。在linux中,库通常安装在具有版本号后缀的系统上,以及发布没有版本号的最新版本的符号链接。通常,您只需链接到未添加的最新版本,但在您的情况下,在您的链接命令中,您需要显式添加后缀。
如果你真的需要将这个cobble-together链接到一个可执行文件中,在unix上你可以用objcopy --redefine-syms
做很多事情来重命名其中一个库中的所有入口点,以及依赖项中的所有引用在编译之后但在链接之前编码。请注意,预期的最终结果是两个库将独立运行,并且不会彼此了解。
答案 1 :(得分:0)
如果你能够将至少一个lib(即Cartographer或Rotors或两者)包装到一个单独的共享库中,并且如果protobuff仅在内部用于每个lib,你仍然可以通过使用-fvisibility=hidden
gcc标志构建共享库(以切换默认可见性以隐藏符号)并仅通过{{1导出所需的符号(应用程序正在使用)来在单个可执行文件中使用它们}}
这种方式我记得我过去在同一个应用程序中使用了两个完全不同的Boost版本(共享库没有导出静态链接的boost符号)。