Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compiler error with yaml-cpp - undefined reference to `YAML::detail::node_data::convert_to_map`

Here's the complete log:

/tmp/ccCvErNZ.o: In function `YAML::detail::node& YAML::detail::node_data::get<std::string>(std::string const&, std::shared_ptr<YAML::detail::memory_holder>)':
cricket.cpp:(.text._ZN4YAML6detail9node_data3getISsEERNS0_4nodeERKT_St10shared_ptrINS0_13memory_holderEE[_ZN4YAML6detail9node_data3getISsEERNS0_4nodeERKT_St10shared_ptrINS0_13memory_holderEE]+0x94): undefined reference to `YAML::detail::node_data::convert_to_map(std::shared_ptr<YAML::detail::memory_holder>)'
collect2: error: ld returned 1 exit status

The code I'm trying to compile is simple

#include <iostream>
#include <yaml-cpp/yaml.h>

using namespace std;

int main() {
    YAML::Node test = YAML::LoadFile("test.yaml");
    if (test["date"]) {
      cout << "HELLO";
    }

    return 0;
}

The YAML I'm using is the example from http://www.yaml.org/start.html

If I just try to load the YAML, it loads fine. But if I try to access any data I get the same error. So it's not a linking problem.

EDIT: I can do things like cout << test and cout << test.type() and other functions. I think the problem is in using a string based map for accessing internal nodes.

like image 545
apoorvumang Avatar asked Apr 04 '16 12:04

apoorvumang


3 Answers

It seems that you are not properly linking the yaml-cpp library. Add the argument -lyaml-cpp when compiling. For example:

g++ -I/usr/local/include -L/usr/local/lib -lyaml-cpp -o test main.cpp

EDIT

Another option is to include this cmake to your CMakeLists.txt:

# attempt to find static library first if this is set
if(YAMLCPP_STATIC_LIBRARY)
    set(YAMLCPP_STATIC libyaml-cpp.a)
endif()

# find the yaml-cpp include directory
find_path(YAMLCPP_INCLUDE_DIR yaml-cpp/yaml.h
          PATH_SUFFIXES include
          PATHS
          ~/Library/Frameworks/yaml-cpp/include/
          /Library/Frameworks/yaml-cpp/include/
          /usr/local/include/
          /usr/include/
          /sw/yaml-cpp/         # Fink
          /opt/local/yaml-cpp/  # DarwinPorts
          /opt/csw/yaml-cpp/    # Blastwave
          /opt/yaml-cpp/
          ${YAMLCPP_DIR}/include/)

# find the yaml-cpp library
find_library(YAMLCPP_LIBRARY
             NAMES ${YAMLCPP_STATIC} yaml-cpp
             PATH_SUFFIXES lib64 lib
             PATHS ~/Library/Frameworks
                    /Library/Frameworks
                    /usr/local
                    /usr
                    /sw
                    /opt/local
                    /opt/csw
                    /opt
                    ${YAMLCPP_DIR}/lib)

# handle the QUIETLY and REQUIRED arguments and set YAMLCPP_FOUND to TRUE if all listed variables are TRUE
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(YAMLCPP DEFAULT_MSG YAMLCPP_INCLUDE_DIR YAMLCPP_LIBRARY)
mark_as_advanced(YAMLCPP_INCLUDE_DIR YAMLCPP_LIBRARY)
like image 181
Albert Pumarola Avatar answered Oct 21 '22 17:10

Albert Pumarola


I experienced something similar to this when trying to compile OpenXcom on a Debian system. It turned out that I was using a mix of testing and stable packages, the yaml package was from stable, and the combination somehow made linking fail if there were more than just a few initial functions.

If that is what you're experiencing (and you're using Debian too), try compiling a source package from stable with

apt-get --build source libyaml-cpp0.5/stable

This command will build .deb packages for libyaml, and you can then insert them with dpkg like this:

dpkg -i libyaml-cpp0.5*.deb

as root.

Compiling libyaml from source will make it link to the testing libraries you already have, instead of expecting stable libraries, and so should solve the problem above. It did for me, at least.

Even if you don't use Debian, compiling yaml-cpp from source (e.g. a tarball) might work for similar reasons.

like image 42
Lesser Cormorant Avatar answered Oct 21 '22 17:10

Lesser Cormorant


Make sure these two files exist:

/usr/local/lib/libyaml-cpp.a
/usr/local/include/yaml-cpp/yaml.h

My CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
FIND_PACKAGE(yaml-cpp REQUIRED)
ADD_EXECUTABLE(yaml_cpp_test yaml_cpp_test.cpp)
TARGET_LINK_LIBRARIES(yaml_cpp_test yaml-cpp)

The content of yaml_cpp_test.cpp is same as mentioned in the question.


I try to reappear the problem on vps (Ubuntu 14.04.1 LTS)

wget -c https://github.com/jbeder/yaml-cpp/archive/release-0.5.1.tar.gz
tar xvf release-0.5.1.tar.gz yaml-cpp-release-0.5.1/
cd yaml-cpp-release-0.5.1/
sudo apt-get install cmake
sudo apt-get install libboost-dev
cmake .
make
make install

after that, yaml-cpp install to /usr/local/lib and /usr/local/include
files in my working directory:

fqlgy@li407-86:~/yaml-cpp$ ll
total 12
-rw-r--r-- 1 fqlgy fqlgy 162 May  8 03:29 CMakeLists.txt
-rw-r--r-- 1 fqlgy fqlgy  10 May  8 03:11 test.yaml
-rw-r--r-- 1 fqlgy fqlgy 240 May  8 03:11 yaml_cpp_test.cpp

As i tried to run "cmake .", there is some error, so i delete the line CMakeFiles/CMakeOutput.log, the content of CMakeLists.txt is :

CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
ADD_EXECUTABLE(yaml_cpp_test yaml_cpp_test.cpp)
TARGET_LINK_LIBRARIES(yaml_cpp_test yaml-cpp)

The following output is as expected:

fqlgy@li407-86:~/yaml-cpp$ cmake .
-- Configuring done
-- Generating done
-- Build files have been written to: /home/fqlgy/yaml-cpp
fqlgy@li407-86:~/yaml-cpp$ make
Scanning dependencies of target yaml_cpp_test
[100%] Building CXX object CMakeFiles/yaml_cpp_test.dir/yaml_cpp_test.cpp.o
Linking CXX executable yaml_cpp_test
[100%] Built target yaml_cpp_test
fqlgy@li407-86:~/yaml-cpp$ ./yaml_cpp_test
HELLO
like image 1
sel-fish Avatar answered Oct 21 '22 18:10

sel-fish