Linking with a newer library rather than the old one - c++

I am trying to compile the Point Cloud Library from source (http://pointclouds.org/). After running cmake and make, I receive the following linking error:
Linking CXX executable ../../bin/pcl_convert_pcd_ascii_binary
../../lib/libpcl_io.so.1.7.2: undefined reference to `png_set_longjmp_fn'
As a newbie, I'm not sure what this error means, but I am assuming: the executable file plc_convert_pcd_ascii_binary which it is trying to build, needs to be linked to the library libpcl_io.so.1.7.2, but this library contains the function png_set_longjump_fun, and the definition of this function cannot be found?
So, I have tried looked at some similar questions on Stack Overflow, and it turns out that png_set_longjump_fun is contained in the libpng library, but was only introduced after libpng-1.4.x. After running dpkg -l | grep libpng*, I get the following output:
ii libpng12-0:amd64 1.2.50-1ubuntu2 amd64 PNG library - runtime
ii libpng12-dev 1.2.50-1ubuntu2 amd64 PNG library - development
So it looks like I need to upgrade from libpng12-dev to at least libpng14-dev. From the libpng website, I see that I can download the source for the latest version (but the latest version I can get through apt-get is only libpng12-dev). But I am worried that there may be some conflictions if I have one version installed via apt-get, and another version installed manually. However, uninstalling libpng12-dev may cause issues if there are packages which depend on this, but are not compatible with the newer version.
Therefore, what I would like to know, is whether I should uninstall/purge libpng12-dev, and then install the new version manually, or to simply install the new version whilst keeping the old version. And if I do the latter, how can I be sure that the PCL binary I am trying to compile, will link with this new library, rather than the old one?
Thanks :)

If you compile from source, you probably don't even need to install. Once you have compiled libpng, set the CMAKE_PREFIX_PATH when you compile PCL to point at the right place in the libpng build tree. This generally is what is done with cmake, so should work in this case. More information:
http://www.cmake.org/cmake/help/v3.0/variable/CMAKE_PREFIX_PATH.html
https://blogs.kde.org/2008/12/12/how-get-cmake-find-what-you-want-it
cmake - find_library - custom library location
How to point cmake at specific directory for library?

Related

Trying to compile code with references to both protobuffers 2.6.1 and 3.4.1

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

lapack complains about libgcc_s_sjlj-1.dll

I am trying to write a program that uses armadillo in Visual Studio. I downloaded Prebuilt libraries for lapack and blas from http://icl.cs.utk.edu/lapack-for-windows/lapack/. I also downloaded MinGW and added C:/MinGW/bin to my System PATH. C:/MinGW/bin has libgfortran-3.dll and libgcc_s_dw2-1.dll which are what the lapack documentation states is needed. However, when I attempt to run my program I get a runtime error stating that the program can't run because libgcc_s_sjlj-1.dll is missing. This dll does not come with MinGW and I tried downloading multiple versions. How can I get rid of this error?
The MinGW-w64 project have something called "personal builds". One of them is "sjlj". The library is built using a gcc compiler from this personal build.
Assuming that it was used the current latest version (6.3.0) and win32 threads the you can find the toolchain binaries here. If not, you can check some other versions.
You can either extract the dll you need or extract it and add it to your system path.

How to use FLANN installed from synaptic

I tried to compile FLANN with cmake, but the only result was a giant headache.
So I found here this solution through PCL repository and synaptic. The installation seems gone well, but now I don't know how to use the installed package.
Quoting FLANN's documentations :
An example of the compile command that must be used will look
something like this: g++ flann_example.cpp -I $FLANN_ROOT/include -o flann_example_cpp where $FLANN ROOT
is the library main directory.
But it's not clear to me where $FLANN_ROOT is.
The $FLANN_ROOT is a path where the library was installed. This is mostly relevant when you build and install manually (especially when installing to non-standard locations).
When installed by the packaging system (Synaptic - I guess Ubuntu?) the library headers will be most likely installed in '/usr/include' or '/usr/local/include'. Normally you do not have to use the -I then as those paths are examined by default.

linking boost filesystem and boost iostream libraries in ubuntu 14.04

I downloaded boost 1.61 and extracted it at /usr/local/boost_1_61_0 and while installing i set the prefix path to /usr/local/ where all the boost libraries are installed. I am trying to install FRESCO tool for DNA data compression which is built using Boost c++ libraries (Downloaded from https://github.com/hubsw/FRESCO). They have given make utility to install FRESCO tool.
But when I try to run make, I get errors regarding BOOST:FILESYSTEM and BOOST:IOSTREAM libraries as follows
undefined reference to `boost::iostreams::detail::gzip_header::reset()'
undefined reference to boost::iostreams::detail::zlib_base::~zlib_base()'
undefined reference to `boost::filesystem::detail::create_directories(boost::filesystem::path const&, boost::system::error_code*)'
and many more related to boost iostream and filesystem.
In FRESCO they mentioned they require BOOST 1.51(later), boost filesystem,boost iostream, boost threading-mt.
Can someone please suggest me where I am going wrong? How to link the boost filesystem/iostream if i am using make utility of ubuntu to install FRESCO tool?
I'm trying to compile boost as dependency for my project and I get similar errors.
I see two issues for your case:
I don't use FRESCO, but from its makefile I see -lboost_system -lboost_filesystem -lboost_iostreams, so it expects a global Boost installation. You don't need to compile Boost for that, you can use the packaged versions of your system. In ubuntu they can be installed with sudo apt-get install libboost-dev libboost-filesystem-dev libboost-iostreams-dev.
If you really want to compile Boost, that error message is about a part of boost that needs extra configuration for compiling it (compression filters). It tries to link to an object with some definitions that are not compiled by default (It would probably link correctly if FRESCO didn't use compression filters). Assuming that you are compiling with Boost.Build, for Boost.Iostreams this issue is explained (not very well IMO) in https://www.boost.org/doc/libs/1_61_0/libs/iostreams/doc/installation.html :
To build with Boost.Build, run bjam from the directory libs/iostreams/build, or from the Boost root directory. If you want to use the compression filters, you may need to set several Boost.Build variables indicating where the source files or pre-built binaries are located.
EDIT
There are other alternatives to compile Boost.Iostreams:
If you have installed bzip and zlib in the system, Boost.Build autoconfigures the compilation of those compression filters. In ubuntu, do sudo apt-get install libbz2-dev zlib1g-dev (in xenial, I haven't checked if the names are different in other versions).
If you can't install zlib and libbgzip in the system, and you compiled them yourself, put this in a file tools/build/src/user-config.jam inside the downloaded folder of boost:
using zlib : 1.2.11 : <include>/path-to-your-compilation/zlib-1.2.11 <search>/path-to-your-compilation/zlib-1.2.11 ;
using bzip2 : 1.0.6 : <include>/path-to-your-compilation/bzip2-1.0.6 <search>/path-to-your-compilation/bzip2-1.0.6 ;
Just replace path-to-your-compilation.
Then, do ./bootstrap.sh --with-libraries=filesystem,iostreams and ./b2.
Documentation for this (notice I'm using Boost 1.65):
user-config.jam: https://www.boost.org/doc/libs/1_65_1/doc/html/bbv2/reference.html#bbv2.reference.tools.libraries.zlib
general Boost install: https://www.boost.org/doc/libs/1_65_1/more/getting_started/unix-variants.html#prepare-to-use-a-boost-library-binary

libboost_python-py27.so.1.53.o No such file or directory

I have one .so library compiled for x86 and I need to deploy and use on another computer(laso Ubuntu), but when I start I get error libboost_python-py27.so.1.53.o No such file or directory, when I ls through /usr/lib I found libboost_python-py27.so.1.49.o . What to do ?
The numbers indicate the version of boost. (See boost.org)
Your code is looking for 1.53, but you only have 1.49 deployed.
You will need to get a copy of the newer libraries and deploy them - for example by getting the relevant version of boost and building the libraries. Or copying them from the machine which has the newer libraries.