isl-org/Open3D

Errors occur when Open3D library is linked together with other libraries, e.g. gflags, opencv

bing-jian opened this issue ยท 20 comments

IMPORTANT: Please use the following template to report the bug.


Describe the bug
Errors occur when Open3D library is linked together with other libraries, e.g. gflags, opencv
To Reproduce

Please see
https://github.com/bing-jian/open3d_test

Expected behavior
The code should compile and work on major platforms including Windows, macOS and linux.

Environment (please complete the following information):

  • Operating system:
    OSX 10.15, Ubuntu 16.04 and 18.04, Windows 10 64-bit
  • Open3D version:
    0.10.0
  • Is this remote workstation?:
    no
  • How did you install Open3D?:
    build from source
  • Compiler version (if built from source):
    gcc 7.5, clang 11.0

Additional context
Same code also worked on Windows 10.

*** Updates: Same code (well, almost same) and CMakeLists.txt worked when using
an earlier version of Open3D (retrieved on 06/02/2019) ***

https://github.com/bing-jian/open3d_test/tree/master/open3d_0.9.0_test

Sorry, the above directory was actually for an even earlier version of Open3D, probably 0.7.0.

I have the same problem in Ubuntu 16 and 18 with libraries like boost and gtsam. I can work with Open3D v0.8.0 without any issues, but was trying to update to the latest version.

This is some of the linking errors that I am getting:

In function `xxxxxxx(int, char**, std::vector<long double, std::allocator<long double> >&, std::vector<int, std::allocator<int> >&, bool&, bool&, bool&, bool&, boost::filesystem::path&, boost::filesystem::path&, boost::filesystem::path&, boost::filesystem::path&, boost::filesystem::path&, boost::filesystem::path const&)':
main.cpp:(.text+0x2b004): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
main.cpp:(.text+0x2b669): undefined reference to `boost::program_options::abstract_variables_map::operator[](std::string const&) const'
main.cpp:(.text+0x2b9fa): undefined reference to `boost::program_options::abstract_variables_map::operator[](std::string const&) const'
main.cpp:(.text+0x2babc): undefined reference to `boost::program_options::abstract_variables_map::operator[](std::string const&) const'
main.cpp:(.text+0x2bc1c): undefined reference to `boost::program_options::abstract_variables_map::operator[](std::string const&) const'
main.cpp:(.text+0x2bcf4): undefined reference to `boost::program_options::abstract_variables_map::operator[](std::string const&) const'
CMakeFiles/.dir/src/main.cpp.o:main.cpp:(.text+0x2bd92): more undefined references to `boost::program_options::abstract_variables_map::operator[](std::string const&) const' follow
CMakeFiles/.dir/src/main.cpp.o: In function `gtsam::GenericValue<gtsam::Pose3>::print(std::string const&) const':
main.cpp:(.text._ZNK5gtsam12GenericValueINS_5Pose3EE5printERKSs[_ZNK5gtsam12GenericValueINS_5Pose3EE5printERKSs]+0x46): undefined reference to `gtsam::demangle(char const*)'
main.cpp:(.text._ZNK5gtsam12GenericValueINS_5Pose3EE5printERKSs[_ZNK5gtsam12GenericValueINS_5Pose3EE5printERKSs]+0x89): undefined reference to `gtsam::Pose3::print(std::string const&) const'
CMakeFiles/.dir/src/main.cpp.o: In function `gtsam::GenericValue<gtsam::imuBias::ConstantBias>::print(std::string const&) const':
main.cpp:(.text._ZNK5gtsam12GenericValueINS_7imuBias12ConstantBiasEE5printERKSs[_ZNK5gtsam12GenericValueINS_7imuBias12ConstantBiasEE5printERKSs]+0x46): undefined reference to `gtsam::demangle(char const*)'
main.cpp:(.text._ZNK5gtsam12GenericValueINS_7imuBias12ConstantBiasEE5printERKSs[_ZNK5gtsam12GenericValueINS_7imuBias12ConstantBiasEE5printERKSs]+0x89): undefined reference to `gtsam::imuBias::ConstantBias::print(std::string const&) const'
CMakeFiles/.dir/src/main.cpp.o: In function `boost::program_options::typed_value<bool, char>::xparse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&) const':
main.cpp:(.text._ZNK5boost15program_options11typed_valueIbcE6xparseERNS_3anyERKSt6vectorISsSaISsEE[_ZNK5boost15program_options11typed_valueIbcE6xparseERNS_3anyERKSt6vectorISsSaISsEE]+0x17): undefined reference to `boost::program_options::validate(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, bool*, int)'
CMakeFiles/.dir/src/main.cpp.o: In function `boost::program_options::typed_value<std::string, char>::xparse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&) const':
main.cpp:(.text._ZNK5boost15program_options11typed_valueISscE6xparseERNS_3anyERKSt6vectorISsSaISsEE[_ZNK5boost15program_options11typed_valueISscE6xparseERNS_3anyERKSt6vectorISsSaISsEE]+0x17): undefined reference to `boost::program_options::validate(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, std::string*, int)'
CMakeFiles/.dir/src/main.cpp.o: In function `gtsam::GenericValue<Eigen::Matrix<double, 3, 1, 0, 3, 1> >::print(std::string const&) const':

I have a similar problem using Open3D and GFlags with the following message form linker:
undefined reference to google::FlagRegisterer::FlagRegisterer<std::string>(char const*, char const*, char const*, std::string*, std::string*)
The error only seems to arise when defining a string flag using "DEFINE_string", however "DEFINE_bool", "DEFINE_double" and "DEFINE_int32" work without any problems.

Environment:
Ubuntu 18.04
Open3d 0.10.1.0
GFlags 2.2
g++ 7.5
cmake 3.17

Do we have any update for this bug???
I have tried with the new version of Open3D 0.11, but I still have the same linking problems

No, didn't manage to solve it.

Ubuntu 20.04
Open3D 0.11.0
OpenCV 4.3.0

also met the undefined references issue with linker

hos-b commented

Ubuntu 20.04
Open3D 0.11.1
In my project i get undefined reference for the following libraries:

  • OpenCV 4.2
  • ROS Noetic
  • CARLA simulator 0.9.9
  • yaml-cpp

EDIT:
I managed to successfully link Open3D by explicitly linking the main library and the 3rd party json-cpp.

target_link_libraries(${PROJECT_NAME}
	${CARLA_LIBRARIES}
	${OpenCV_LIBS}
	hdf5_dataset
	yaml-cpp
	# instead of Open3D::Open3D or ${Open3D_LIBRARIES}
	Open3D
	Open3D_3rdparty_jsoncpp
	pthread
)

I haven't used Open3D in any reasonable capacity yet. I just used the following line as a test:

auto tax = open3d::camera::PinholeCameraIntrinsic();

this is not a fix by any means but it might help while waiting for an official patch.

I tried to do that, but unfortunately got a building error now:

/usr/local/include/open3d/utility/Console.h:40:10: fatal error: fmt/format.h: No such file or directory
#include <fmt/format.h>
^~~~~~~~~~~~~~
compilation terminated.

really don't know what is the problem here, but puts me off to use this library.
There is also a compilation error in Line3D.h that can't believe how they haven't fixed it yet.

Anyway, if someone knows how to fix this problem, please leave a comment here

hos-b commented

I tried to do that, but unfortunately got a building error now:

/usr/local/include/open3d/utility/Console.h:40:10: fatal error: fmt/format.h: No such file or directory
#include <fmt/format.h>
^~~~~~~~~~~~~~
compilation terminated.

really don't know what is the problem here, but puts me off to use this library.
There is also a compilation error in Line3D.h that can't believe how they haven't fixed it yet.

Anyway, if someone knows how to fix this problem, please leave a comment here

that's most likely because you don't have fmtlib. you should still get an error after building/installing it but an undefined reference not the one you got.

hos-b commented

I suspect that this is due to conflicts between any library that Open3D builds as a dependency (sort of invisibly) and anything else that uses those libraries. e.g. Open3D builds and uses libfmt and libqhull. A full ROS installation includes libqhull and therefor ${catkin_LIBRARIES} might contain it. Maybe OpenCV fails because of Eigen dependencies. I hope the issue is solved in a future release. I had to move on to pcl for now.

I was having a similar issue trying to link with Open3D v0.11.2. I found that setting -DGLIBCXX_USE_CXX11_ABI=ON when building Open3D fixed the linker errors for me.

I suspect that this is due to conflicts between any library that Open3D builds as a dependency (sort of invisibly) and anything else that uses those libraries. e.g. Open3D builds and uses libfmt and libqhull. A full ROS installation includes libqhull and therefor ${catkin_LIBRARIES} might contain it. Maybe OpenCV fails because of Eigen dependencies. I hope the issue is solved in a future release. I had to move on to pcl for now.

I'm basically stuck with the same issue and I'd really like to move on (past the PCL era)
Do you have any updates on the linking problem? @hos-b

hos-b commented

I'm basically stuck with the same issue and I'd really like to move on (past the PCL era)
Do you have any updates on the linking problem? @hos-b

Unfortunately not @lwohlhart . I haven't tried SoulProtagonist's solution either. I got what I wanted out of PCL to some extent and moved on. I got as far as this stackoverflow question before giving up. It kinda describes our problem and the comments allegedly lead to a solution. What we're looking for is "pre-linking" Open3D with its dependencies, and then linking against our own. If you succeed, let me know.

I guess I just got it to link properly by compiling Open3D as suggest in
https://github.com/ntnu-arl/open3d_ros#open3d

basically extended version of SoulProtagonists suggestion

git clone --recursive https://github.com/intel-isl/Open3D
cd Open3D && source util/scripts/install-deps-ubuntu.sh
mkdir build && cd build
cmake -DBUILD_EIGEN3=ON -DBUILD_GLEW=ON -DBUILD_GLFW=ON -DBUILD_JSONCPP=ON -DBUILD_PNG=ON -DGLIBCXX_USE_CXX11_ABI=ON -DPYTHON_EXECUTABLE=/usr/bin/python -DBUILD_UNIT_TESTS=ON ..
make -j4
sudo make install
hos-b commented

I guess I just got it to link properly by compiling Open3D as suggest in
https://github.com/ntnu-arl/open3d_ros#open3d
basically extended version of SoulProtagonists suggestion

the flag seems to resolve the issue. I didn't really test the library but it linked just fine with Eigen, OpenCV, ROS, yaml-cpp and CARLA.

can canform linking issue exists without specific cmake options
proposals from @SoulProtagonist and @lwohlhart work with versions 0.11.2 and 0.12.0
cmake -DGLIBCXX_USE_CXX11_ABI=ON ..

In my case the linker issues appeared when I linked one of my own libraries internally using opencv

I met the same linker problem(undefined reference) when I tried to use Open3D with Boost_options.
If I build them seperatelly, they can be build successfully.

Environment:
You can use the Dokcerfile in the gist below to produce the same environment that I am using.
https://gist.github.com/HTLife/f19617ad0cd4e3c1248f946982d66400

Here I provide the minimal example to reproduce this issue.

Build Boost only

#CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(Open3DCMakeFindPackage LANGUAGES C CXX)
find_package(Boost REQUIRED COMPONENTS program_options)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
add_executable (Draw Draw.cpp)
target_link_libraries(Draw ${Boost_LIBRARIES})
//Draw.cpp
#include <string>
#include <boost/program_options.hpp>
namespace BPO = boost::program_options;
int main(int argc, char *argv[]) {
  BPO::options_description bOptions( "Test Options" );
  bOptions.add_options()
      ( "help", "Produce help message" )
      ( "vint",    BPO::value<int>(), "int value" );
    return 0;
}

cmake -DGLIBCXX_USE_CXX11_ABI=ON .. -DOpen3D_ROOT=${HOME}/open3d_install ..
make

Build Open3D only

#CMakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(Open3DCMakeFindPackage LANGUAGES C CXX)
find_package(Open3D REQUIRED)
add_executable (Draw Draw.cpp)
target_link_libraries(Draw Open3D::Open3D)
//Draw.cpp
#include <string>
#include "open3d/Open3D.h"
using namespace open3d;

int main(int argc, char *argv[]) {
    geometry::PointCloud pc2;
    if (!open3d::io::ReadPointCloud(argv[1], pc2,
                        {"auto", false, false})) {
        // utility::LogError("Failed to read from {}", argv[1]);
    }
    double voxel_size = 0.5;
    auto pcd_down = pc2.VoxelDownSample(voxel_size);

    bool write_ascii = true;
    bool write_compressed = false;

    std::string output_file_path = "down.pcd";
    open3d::io::WritePointCloud(
        output_file_path, 
        *pcd_down,
        open3d::io::WritePointCloudOption(write_ascii, write_compressed,
                                            false, {}));
    return 0;
}

cmake -DGLIBCXX_USE_CXX11_ABI=ON .. -DOpen3D_ROOT=${HOME}/open3d_install ..
make

Build Open3D with Boost

#CmakeLists.txt
cmake_minimum_required(VERSION 3.18)
project(Open3DCMakeFindPackage LANGUAGES C CXX)
find_package(Open3D REQUIRED)
find_package(Boost REQUIRED COMPONENTS program_options)
INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIRS})
add_executable (Draw Draw.cpp)
target_link_libraries(Draw Open3D::Open3D ${Boost_LIBRARIES})
//Draw.cpp
#include <string>
#include "open3d/Open3D.h"
#include <boost/program_options.hpp>
namespace BPO = boost::program_options;

using namespace open3d;

int main(int argc, char *argv[]) {
    
     // setup program options description
  BPO::options_description bOptions( "Test Options" );
  bOptions.add_options()
      ( "help", "Produce help message" )
      ( "vint",    BPO::value<int>(), "int value" );

    geometry::PointCloud pc2;
    if (!open3d::io::ReadPointCloud(argv[1], pc2,
                        {"auto", false, false})) {
        // utility::LogError("Failed to read from {}", argv[1]);
    }
    double voxel_size = 0.5;
    auto pcd_down = pc2.VoxelDownSample(voxel_size);

    bool write_ascii = true;
    bool write_compressed = false;

    std::string output_file_path = "down.pcd";
    open3d::io::WritePointCloud(
        output_file_path, 
        *pcd_down,
        open3d::io::WritePointCloudOption(write_ascii, write_compressed,
                                            false, {}));

    return 0;
}

cmake -DGLIBCXX_USE_CXX11_ABI=ON .. -DOpen3D_ROOT=${HOME}/open3d_install ..

Here I tried with the cmake option that @SoulProtagonist suggested, but I still met the same problem.

# make
[ 50%] Building CXX object CMakeFiles/Draw.dir/Draw.cpp.o
[100%] Linking CXX executable Draw
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o: in function `main':
Draw.cpp:(.text+0x82): undefined reference to `boost::program_options::options_description::options_description(std::string const&, unsigned int, unsigned int)'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o: in function `boost::program_options::validation_error::validation_error(boost::program_options::validation_error::kind_t, std::string const&, std::string const&, int)':
Draw.cpp:(.text._ZN5boost15program_options16validation_errorC2ENS1_6kind_tERKSsS4_i[_ZN5boost15program_options16validation_errorC5ENS1_6kind_tERKSsS4_i]+0x45): undefined reference to `boost::program_options::validation_error::get_template(boost::program_options::validation_error::kind_t)'
/usr/bin/ld: Draw.cpp:(.text._ZN5boost15program_options16validation_errorC2ENS1_6kind_tERKSsS4_i[_ZN5boost15program_options16validation_errorC5ENS1_6kind_tERKSsS4_i]+0x62): undefined reference to `boost::program_options::error_with_option_name::error_with_option_name(std::string const&, std::string const&, std::string const&, int)'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTVN5boost15program_options11typed_valueIicEE[_ZTVN5boost15program_options11typed_valueIicEE]+0x38): undefined reference to `boost::program_options::value_semantic_codecvt_helper<char>::parse(boost::any&, std::vector<std::string, std::allocator<std::string> > const&, bool) const'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTVN5boost15program_options20invalid_option_valueE[_ZTVN5boost15program_options20invalid_option_valueE]+0x30): undefined reference to `boost::program_options::error_with_option_name::substitute_placeholders(std::string const&) const'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTVN5boost15program_options16validation_errorE[_ZTVN5boost15program_options16validation_errorE]+0x30): undefined reference to `boost::program_options::error_with_option_name::substitute_placeholders(std::string const&) const'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o: in function `boost::program_options::typed_value<int, char>::name() const':
Draw.cpp:(.text._ZNK5boost15program_options11typed_valueIicE4nameEv[_ZNK5boost15program_options11typed_valueIicE4nameEv]+0x3b): undefined reference to `boost::program_options::arg'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o: in function `void boost::program_options::validate<int, char>(boost::any&, std::vector<std::basic_string<char, std::char_traits<char>, std::allocator<char> >, std::allocator<std::basic_string<char, std::char_traits<char>, std::allocator<char> > > > const&, int*, long)':
Draw.cpp:(.text._ZN5boost15program_options8validateIicEEvRNS_3anyERKSt6vectorISbIT0_St11char_traitsIS5_ESaIS5_EESaIS9_EEPT_l[_ZN5boost15program_options8validateIicEEvRNS_3anyERKSt6vectorISbIT0_St11char_traitsIS5_ESaIS5_EESaIS9_EEPT_l]+0x12b): undefined reference to `boost::program_options::invalid_option_value::invalid_option_value(std::string const&)'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTVN5boost10wrapexceptINS_15program_options16validation_errorEEE[_ZTVN5boost10wrapexceptINS_15program_options16validation_errorEEE]+0x38): undefined reference to `boost::program_options::error_with_option_name::substitute_placeholders(std::string const&) const'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTCN5boost10wrapexceptINS_15program_options16validation_errorEEE0_NS_16exception_detail10clone_implINS4_19error_info_injectorIS2_EEEE[_ZTVN5boost10wrapexceptINS_15program_options16validation_errorEEE]+0x38): undefined reference to `boost::program_options::error_with_option_name::substitute_placeholders(std::string const&) const'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTVN5boost16exception_detail10clone_implINS0_19error_info_injectorINS_15program_options16validation_errorEEEEE[_ZTVN5boost16exception_detail10clone_implINS0_19error_info_injectorINS_15program_options16validation_errorEEEEE]+0x38): undefined reference to `boost::program_options::error_with_option_name::substitute_placeholders(std::string const&) const'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTVN5boost16exception_detail19error_info_injectorINS_15program_options16validation_errorEEE[_ZTVN5boost16exception_detail19error_info_injectorINS_15program_options16validation_errorEEE]+0x30): undefined reference to `boost::program_options::error_with_option_name::substitute_placeholders(std::string const&) const'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTVN5boost10wrapexceptINS_15program_options20invalid_option_valueEEE[_ZTVN5boost10wrapexceptINS_15program_options20invalid_option_valueEEE]+0x38): undefined reference to `boost::program_options::error_with_option_name::substitute_placeholders(std::string const&) const'
/usr/bin/ld: CMakeFiles/Draw.dir/Draw.cpp.o:(.data.rel.ro._ZTCN5boost10wrapexceptINS_15program_options20invalid_option_valueEEE0_NS_16exception_detail10clone_implINS4_19error_info_injectorIS2_EEEE[_ZTVN5boost10wrapexceptINS_15program_options20invalid_option_valueEEE]+0x38): more undefined references to `boost::program_options::error_with_option_name::substitute_placeholders(std::string const&) const' follow
collect2: error: ld returned 1 exit status
make[2]: *** [CMakeFiles/Draw.dir/build.make:99: Draw] Error 1
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Draw.dir/all] Error 2
make: *** [Makefile:91: all] Error 2

Anyone already found the solution?

I found the solution that if we also build the Open3D with -DGLIBCXX_USE_CXX11_ABI=ON, then all the error can be solved.

cmake -DBUILD_SHARED_LIBS=ON -DGLIBCXX_USE_CXX11_ABI=ON -DCMAKE_BUILD_TYPE=Release ..

Thanks @bing-jian, @SoulProtagonist and other reporters. We have made the new CXX11_ABI as the default option so you should not need to explicitly specify this any more.

For anyone having this error again, the default behavior regressed with this PR

Default behavior now sets BUILD_SYCL_MODULE=OFF and GLIBCXX_USE_CXX11_ABI=OFF. I don't immediately see a reason that the default GLIBCXX_USE_CXX11_ABI value couldn't remain ON

@ssheorey this issue should probably be re-opened