CMake: link against two precompiled libraries dependent on different versions of third library
Asked Answered
S

0

9

I'm trying to compile a project where I'm linking against precompiled versions of two libraries (PCL and Matlab), that are compiled against different versions of Boost (1.58 and 1.56).

This gives me many warnings when I build my project:

Cannot generate a safe runtime search path for target Test because 
files in some directories may conflict with libraries in implicit directories:

runtime library [libpng12.so.0] in /usr/lib/x86_64-linux-gnu may be hidden 
by files in:
  /usr/local/MATLAB/R2017b/bin/glnxa64

and so on for other libraries (libtiff, libfreetype, libexpat, libxml2, libQt5OpenGL...), but none for boost.

When I compile and run my program I get this error

*** Error in `/home/user/Test': free(): invalid pointer: 0x0000000000bf36a8 ***
======= Backtrace: =========
/lib/x86_64-linux-gnu/libc.so.6(+0x777e5)[0x7f9cf1c507e5]
/lib/x86_64-linux-gnu/libc.so.6(+0x8037a)[0x7f9cf1c5937a]
/lib/x86_64-linux-gnu/libc.so.6(cfree+0x4c)[0x7f9cf1c5d53c]
/lib/x86_64-linux-gnu/libc.so.6(__cxa_finalize+0x9a)[0x7f9cf1c1336a]
/usr/local/MATLAB/R2017b/bin/glnxa64/libboost_filesystem.so.1.56.0(+0x7646)[0x7f9ce9eda646]

I suspect it is because it adds all the libraries to the same search path and links PCL to Matlab's version of Boost which gives the error and warnings. I have spent a lot of time trying to get it to link without crashing, but to no avail.

Inspired by: link path confusion after target_link_libraries call I tried adding Matlab using add_library,

add_library(eng STATIC IMPORTED)
set_property(TARGET eng PROPERTY IMPORTED_LOCATION ${Matlab_ENG_LIBRARY})
set_property(TARGET eng PROPERTY INTERFACE_INCLUDE_DIRECTORIES /usr/local/MATLAB/R2017b/bin/glnxa64/)
target_link_libraries(${PROJECT_NAME} eng)

(and many variations of this) but I've been unable to find a combination that solved the problem, as I also run into the same problems as the asker.

It seems that another question is about a very similar problem, but it has not been answered MATLAB Libraries conflict with Existing Libraries - CMake Crash

I think I could solve the problem by compiling PCL and boost 1.56 from scratch, but I would like to avoid that.


Minimal "working" example:

CMakeLists.txt

project(Test)
cmake_minimum_required(VERSION 2.8)
add_executable(${PROJECT_NAME} main.cpp)

#PCL
find_package(PCL 1.3 REQUIRED COMPONENTS)
include_directories(${PCL_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${PCL_LIBRARIES})

#Matlab
find_package(Matlab REQUIRED ENG_LIBRARY)
include_directories(${Matlab_INCLUDE_DIRS})
target_link_libraries(${PROJECT_NAME} ${Matlab_ENG_LIBRARY})

main.cpp

#include <pcl/io/ply_io.h>
#include "engine.h"

int main() {
    pcl::PLYReader ply_reader;
    return 0;
}

void not_called_function() {
    Engine *ep;
    ep = engOpen("");
    return;
}

Anything that can help me on the way to a solution will be greatly appreciated.

Supposititious answered 27/9, 2017 at 11:58 Comment(7)
Trying to link (bits of) two versions of Boost into a single executable is always going to be problematic, brittle, and best avoided. Getting (or building) a version of the PCL lib against the same version of Boost using in the Matlab lib is indeed your best bet.Lenka
Why should it not work by linking only boost 1.58? As far as Matlab could find all of the symbols needed available in this version (backward compatibility)Mneme
@Mneme how do I do that? I tried removing the included boost libraries from the Matlab folder, but then it gave an error that it couldn't find the 1.56 libraries (which it of course could not)Supposititious
Your missing an include path in the cmake so it can find a common boost version.Avalanche
@Avalanche I tried adding include_directories(/usr/lib/x86_64-linux-gnu/) but it gives the same errors. Could you be more specific?Supposititious
I have been in this same situation and would echo what @Lenka said, your best bet is to rebuild PCL against the same version of Boost that Matlab uses. Trying to avoid rebuilding PCL could take longer than just doing it.Pseudoscope
On Linux all symbols share single global namespace, when boost 1.58 (or 1.56) is loaded into process, both libraries are going to use symbols from that version of boost, regardless of what version your library was build against. You really should just rebuild both libraries with the same boost version.Demitria

© 2022 - 2024 — McMap. All rights reserved.