9

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.

Samer
  • 1,923
  • 3
  • 34
  • 54
apoorvumang
  • 169
  • 1
  • 2
  • 8
  • That's not the complete log, that's just the error messages. You have a linkage error so you need to show us the failing linkage command. It is the `g++ ...` command from which the errors follow. Post it in the body of your question. – Mike Kinghan May 04 '16 at 15:00
  • @Mike Kinghan ` In function `YAML::detail::node& YAML::detail::node_data::get(std::string const&, boost::shared_ptr)': /usr/include/yaml-cpp/node/detail/impl.h:89: undefined reference to `YAML::detail::node_data::convert_to_map(boost::shared_ptr)'` – Samer May 05 '16 at 00:22
  • @MikeKinghan unfortunately I cannot edit the post, since it is not my post, but my cmake file is in the comments at the end of this page.... – Samer May 05 '16 at 01:27

8 Answers8

8

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)
Albert Pumarola
  • 646
  • 4
  • 8
  • here is my cmake: `find_package(yaml-cpp REQUIRED) set(PCL_BUILD_TYPE Release) add_executable (extract_c src/main.cpp) target_link_libraries (extract_c yaml-cpp)` – Samer May 05 '16 at 00:44
  • 1
    Take a loot at this cmake to find `yaml-cpp` https://github.com/supercollider/supercollider/blob/master/cmake_modules/FindYamlCpp.cmake – Albert Pumarola May 05 '16 at 01:35
2

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.

  • what do you mean by _then insert it with dpkg_ – Samer May 04 '16 at 02:39
  • Use dpkg -i to install the packages the compilation process creates. I've elaborated on how to do so now. – Lesser Cormorant May 04 '16 at 15:28
  • Do I need to do dpkg remove to the current yaml-cpp? – Samer May 04 '16 at 15:30
  • If your current yaml-cpp is already 0.5, it shouldn't matter because it should just replace the old one with the new one. However, I'm not **entirely** certain, so remove the current one just to be sure if it's not too much of a hassle. – Lesser Cormorant May 04 '16 at 15:45
  • I did all of the above and till getting the same linking error! – Samer May 05 '16 at 00:42
  • Then it may not be the same error. Did you get the encoded function name and reference (e.g. .text._ZN4YAML6detail9node_data3getISsEERNS0_4nodeERKT_St10shared_ptrINS0_13memory_holderEE[_ZN4YAML6detail9node_data3getISsEERNS0_4nodeERKT_St10shared_ptrINS0_13memory_holderEE]+0x94)) in your error? – Lesser Cormorant May 05 '16 at 14:51
  • I got this `undefined reference to YAML::detail::node_data::convert_to_map(boost::shared_ptr)` – Samer May 05 '16 at 15:00
  • That could be a different error. Try copying the source code from the post (the bit after "The code I'm trying to compile is simple") into _foo.cc_, and then do `g++ foo.cc -lyaml-cpp`. Does that work or does it give the same error? – Lesser Cormorant May 05 '16 at 17:38
1

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
sel-fish
  • 4,308
  • 2
  • 20
  • 39
  • I did the exact same thing and still, I got the same error...this is crazy! – Samer May 08 '16 at 02:11
  • `In function `YAML::detail::node& YAML::detail::node_data::get(std::string const&, boost::shared_ptr)': yaml_example.cpp:(.text._ZN4YAML6detail9node_data3getISsEERNS0_4nodeERKT_N5boost10shared_ptrINS0_13memory_holderEEE[_ZN4YAML6detail9node_data3getISsEERNS0_4nodeERKT_N5boost10shared_ptrINS0_13memory_holderEEE]+0xae): undefined reference to `YAML::detail::node_data::convert_to_map(boost::shared_ptr)'` – Samer May 08 '16 at 02:12
  • may you try to run "nm /usr/local/lib/libyaml-cpp.a |grep convert_to_map" to check the symbol? – sel-fish May 08 '16 at 02:28
  • `0000000000001670 T _ZN4YAML6detail9node_data14convert_to_mapEN5boost10shared_ptrINS0_13memory_holderEEE 0000000000000060 r _ZZN4YAML6detail9node_data14convert_to_mapEN5boost10shared_ptrINS0_13memory_holderEEEE19__PRETTY_FUNCTION__` – Samer May 08 '16 at 02:35
  • not sure what the above means, please let me know, thanks – Samer May 08 '16 at 02:36
  • you can run 'man nm' to see the detail, this api shows symbol table of a library. can you give more information about your os and how you install yaml-cpp ? – sel-fish May 08 '16 at 02:41
  • I am using Ubuntu 14.04 – Samer May 08 '16 at 02:46
  • i am using yaml-cpp 0.5.1 – Samer May 08 '16 at 02:48
  • I have build it from source, should I redo it? – Samer May 08 '16 at 02:50
  • 1
    It' ok to build from source. I will try it on the same os version and give you feedback later. – sel-fish May 08 '16 at 02:51
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/111324/discussion-between-sel-fish-and-samer). – sel-fish May 08 '16 at 03:47
1

I confirm that certain versions of yaml-cpp library contain this issue (and it is not about improper linking). It is rather dirty, but I've resolved it by defining empty functions in my code, it looks like

    YAML::BadConversion::~BadConversion()
    {
    }

    void  YAML::detail::node_data::convert_to_map(std::shared_ptr<YAML::detail::memory_holder>)
    {
    }

The approach is not perfect (e.g. because it causes duplicates if another library version is used).

0

In my case, I run the exact same code on two computer which only give error on one of them and that almost make me crazy. This is not a compilation error, linking error or something, I think the code is dirty or something else.

I tried all option:

  1. regular building from source and installing using cmake .. => make => make install
  2. same as 1, with CC=$(which gcc) CXX=$(which g++) cmake -DBUILD_SHARED_LIBS=ON ..
  3. uninstalling the default package from apt (i use ubuntu 16.04)

all failed, until I find Ilya Golshtein's answer, then in my code which will use yaml-cpp I added this code jsut before YAML::LoadFIle Line

    YAML::BadConversion::~BadConversion()
{
}

void  YAML::detail::node_data::convert_to_map(std::shared_ptr<YAML::detail::memory_holder>)
{
}

This is the only solution that worked

0

I'm late to the party here and have no idea what I'm doing but for those of you on Windows, make sure your IDE likes your mingw-g++. Mine auto-defaulted to strawberry perl (?) and when I changed it to mingw-g++ everything started working. I suppose it has something to do with the versioning?

als0052
  • 388
  • 3
  • 13
0

It bothered me, too. I met it when version of yaml-cpp was "0.7.0". I solved it by using "0.6.0" instead.

0

In my case it was an issue of multiple libraries being installed. I had ROS installed already which seems to ship with yaml-cpp as well. The conflicts between the different versions triggered undefined reference errors.

Uninstalling all the yaml-cpp versions I added solved the issue.