I have a project which depends on Triton library which have prebuilt binaries using Protobuf of some version. I also have GRPC dependency which depends on system wide installed Protobuf of more recent version. When I built my program with these 2 dependencies, building system(meson in my case) picks up includes one or the other protobuf version and throws a lot of errors, because they are not compatible :
error: #error This file was generated by an older version of protoc which is incompatible with your Protocol Buffer headers. Please regenerate this file with a newer version of protoc.
and following a lot of API incompatibility errors.
I think I can rebuild either project using one protobuf version and all be ok. But it will require rebuilding either Triton package, or installing specific version of protoc to my system.
Is there a way for building system to handle this case?(Meson or Cmake)
Related
The GitHub project, https://github.com/bluzelle/swarmDB , that I am working on provides an option that installs Boost 1.70.0 in the build folder and links from there.
Unfortunately, on macOS only, if the developer has installed a previous version of boost, 1.68.0 say, manually or via brew, the include and lib files are placed in
/usr/local
which causes the compiler to ignore the boost in the build folder, as it sees the older version of boost first. Since we are using new functionality in boost 1.70.0 this results in difficult to diagnose linker errors (well, not now, we know what the problem is).
The fix is to request developers remove the older version of boost, a better fix would be to ignore the older boost include folders and libraries.
How do we get the macOS c++ compilers to ignore the older boost versions include folder and libraries in favour of those installed in the build folder?
I am trying to compile a single codebase with references to both protobuffers 3.4.1 and 2.6.1. Now the 2.6.1 variant is globally defined as I am using ubuntu xenial, also:
$ protoc --version
yields:
libprotoc 2.6.1
The requirement for protobuffer version 3.4.1 comes from Google Cartographer (https://github.com/googlecartographer/cartographer) while the requirement for 2.6.1 comes from rotors simulator (https://github.com/ethz-asl/rotors_simulator) as it relies on Gazebo-7 (which uses protobuffer 2.6.1). In order to compile Google Cartographer I have added the binaries (added them in a proto3 folder, see below) to the installation by adapting the CMakeList.txt (see original file here: https://raw.githubusercontent.com/googlecartographer/cartographer/master/CMakeLists.txt) for Google Cartographer by adding the following lines:
set(CMAKE_PREFIX_PATH CMAKE_PREFIX_PATH "${CMAKE_SOURCE_DIR}/proto3")
...
install(DIRECTORY proto3/ DESTINATION .)
So the binaries of the protobuffer 3.4.1 are added to the install folder. I am utilizing catkin-tools (https://catkin-tools.readthedocs.io/en/latest/) to build the whole workspace. Now in a CMakelist.txt for Rotors Simulator I have the following line:
find_package(Protobuf 2.6.1 REQUIRED HINTS "/usr")
But at the moment while trying to compile it does not seem to be able to find the protobuffer 2.4.1 as it returns the following:
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
As a side-note, if I compile the packages separately I am able to compile and install the packages. This is done with the following commands:
catkin build cartographer_ros
and
catkin build rotors_gazebo_plugins
I am at the moment trying to adapt the package of rotors_gazebo_plugins but am so far unsuccessful at making sure the correct protobuffer library is selected, am I missing something by defining references to a local protobuffer version?
You will find it possible to build a single executable that references 2 versions of the same library on mac, quite difficult on windows, and pretty much impossible on unix. This is because the symbol names are not distinct between the two libraries, so if you load both libraries, there is no way to know which library should service which call.
If you are building 2 different executables in one makefile package, then you just need to set the right libraries to load in the link stage. In linux, libraries are usually installed on your system with a version-number suffix, and a symlink that publishes the latest version without the version number. Normally you simply link to the unsuffixed latest version, but in your case, in your link command you will need to explicitly add the suffix.
If you really do need to link this cobble-together into a single executable, on unix you can do a lot with objcopy --redefine-syms to rename all the entrypoints in one of the libraries, and all the references in the dependant code all after compilation, but before linking. Note that the intended end result is that both libraries will run independently and will not be aware of each other.
If you will be able to wrap up at least one of the libs (i.e. either Cartographer or Rotors or both) into a separate shared library, and if the protobuff is only used internally in each of them, you still might be able to use them both in a single executable by building the shared libs with -fvisibility=hidden gcc flag (to switch the default visibility to hide symbols) and only exporting the symbols that are needed (that the app is using) via __attribute__((visibility("default"))).
This way I recall I was able to use two completely different Boost versions in the past, in the same app (by the shared lib not exporting the boost symbols linked in statically).
I am using cpprestsdk/casablanca in my project. cpprestsdk is dependent on Boost library. Several weeks ago I downloaded cpprest's source and built *.so library with Boost 1.65.1 and some version of OpenSSL. My system is Arch Linux.
Due to a recent events with Meltdown and Spectre exploits, I've made a full system upgrade (kernel 4.14, latest versions of libraries) and now I have Boost 1.66.0 and a more recent version of OpenSSL.
When I try to compile my project, linker states that
libboost_[random, system, etc. - there are many of them].so.1.65.1, needed by /usr/local/lib/libcpprest.so, not found (try using -rpath or -rpath-link)
It also shows warning about SSL because latest version of cpprestsdk is incompatible with OpenSSL 1.1+ so you have to build it (cpprest) with the previous.
libcrypto.so.1.0.0, needed by /usr/local/lib/libcpprest.so, may conflict with libcrypto.so.1.1.
Obviously, there is no boost 1.65.1 installation on my system, so there is no point in using -rpath.
I figured that I should build another version of boost, but several sources claim that it is bad idea to store multiple versions of boost on one system. I am not sure how to correctly store custom boost version either.
I can rebuild libccprest with the current library but it'll only work till the next update.
I guess that in order to completely build my project, I should embed specific versions of Boost, SSL and other dependencies into my project.
What are general solutions for such a problem? How do you manage and deploy custom (non-system-side) versions of shared libraries? Every "big" library has it's own installation system/scripts so I have no idea how to integrate it to my own project's build system. I've never encounter issues with libraries before so I am not sure what path to choose. I am using Makefile to build my project.
I am trying to cross compile an application for a different platform (quark processor) using cmake. The platform has provided an SDK to me. My application requires a newer version of one of the libraries in the SDK. I have added the new source code for the library using add_subdirectory(). But my problem is when I use target_link_libraries(), cmake is linking the older version of the library in my SDK. How to enable cmake ignore the library version in the SDK sysroot, and only use the new library version present in the subdirectory?
Edit: My apologies for the initial lack of details.Adding more details to the question as suggested.
My CMakeLists.txt include the following statements
add_subdirectory(libs/mosquitto-1.4.10)
target_link_libraries(myapp mosquittopp)
As mentioned, my problem is that the SDK I am using contains a 1.4 version of mosquitto library. The target_link_libraries() only links the 1.4 version and not the newer 1.4.10 version, even though cmake successfully builds the 1.4.10 version.
I have magic error with running fork of Caffe and Protobuf library version of 2.5.0.
[libprotobuf FATAL google/protobuf/stubs/common.cc:72] This program was compiled against version 2.4.1 of the Protocol Buffer runtime library, which is not compatible with the installed version (2.5.0). Contact the program author for an update. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library. (Version verification failed in "/Users/teamcity/buildAgent/work/fb4f05c74a361f59/External/common/ext/mapkit/routing/protobuf/RouterProtoFormat.pb.cc".)
The magic is that is no RouterProtoFormat.pb.cc anywhere on my computer. Google didn't know anything about this file.
Here make file I used for build protobuf library. Any advice?
Edit
I decide include sources directly to project(without precompiled *.a library) and now I have another error:
libprotobuf FATAL /Users/teamcity/buildAgent/work/fb4f05c74a361f59/External/lib/google/protobuf/stubs/common.cc:61] This program requires version 2.5.0 of the Protocol Buffer runtime library, but the installed version is 2.4.1. Please update your library. If you compiled the program yourself, make sure that your headers are from the same version of Protocol Buffers as your link-time library. (Version verification failed in "project_dir/sources/caffe/src/caffe/proto/caffe.pb.cc".)
I setup debug breakpoint and seams that code executes in some hidden library. I can't get location of this library. I delete all libprotobuf.a files from computer and I still do not know witch file is executes..
Edit 2 (Solved)
There is only one solution I found. I rename everywhere google namespace to google2, and now seams all working fine.