yaml-cpp的编译器错误 - 对`YAML :: detail :: node_data :: convert_to_map`的未定义引用

时间:2016-04-04 12:54:37

标签: c++ yaml undefined-reference yaml-cpp

这是完整的日志:

/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

我尝试编译的代码很简单

#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;
}

我使用的YAML是http://www.yaml.org/start.html

中的示例

如果我只是尝试加载YAML,它会加载正常。但是,如果我尝试访问任何数据,我会得到相同的错误。所以它不是一个链接问题。

编辑:我可以执行cout << testcout << test.type()等功能。我认为问题在于使用基于字符串的映射来访问内部节点。

5 个答案:

答案 0 :(得分:3)

您似乎没有正确链接yaml-cpp库。编译时添加参数-lyaml-cpp。例如:

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

修改

另一种选择是将此cmake包含在您的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)

答案 1 :(得分:2)

在尝试在Debian系统上编译OpenXcom时,我遇到了类似的问题。事实证明,我使用的是测试和稳定包的混合,yaml包来自稳定,如果不仅仅是一些初始函数,组合以某种方式使链接失败。

如果您正在体验这一点(并且您也在使用Debian),请尝试使用

编译来自stable的源包。
apt-get --build source libyaml-cpp0.5/stable

此命令将为libyaml构建.deb包,然后您可以使用dpkg插入它们,如下所示:

dpkg -i libyaml-cpp0.5*.deb

以root身份。

从源代码编译libyaml会使它链接到您已经拥有的测试库,而不是期望稳定的库,因此应该解决上面的问题。它至少对我有用。

即使您不使用Debian,从源代码编译yaml-cpp(例如tarball)也可能出于类似的原因。

答案 2 :(得分:1)

确保存在这两个文件:

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

我的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)

yaml_cpp_test.cpp的内容与问题中提到的相同。

我尝试在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

之后,yaml-cpp安装到/ usr / local / lib和/ usr / local / include
我工作目录中的文件:

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

当我试图运行&#34; cmake。&#34;时,有一些错误,所以我删除了行CMakeFiles/CMakeOutput.log,CMakeLists.txt的内容是:

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

以下输出符合预期:

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

答案 3 :(得分:0)

我确认yaml-cpp库的某些版本包含此问题(这与不正确的链接无关)。 它很脏,但是我已经通过在代码中定义空函数来解决了它,看起来像

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

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

这种方法并不完美(例如,因为使用其他库版本会导致重复)。

答案 4 :(得分:0)

在我的情况下,我在两台计算机上运行完全相同的代码,但其中只有一台出现错误,这几乎使我发疯。这不是编译错误,链接错误等,我认为代码很脏。

我尝试了所有选项:

  1. 从源头进行常规构建并使用cmake .. => make => make install
  2. 进行安装
  3. 与1相同,CC=$(which gcc) CXX=$(which g++) cmake -DBUILD_SHARED_LIBS=ON ..
  4. 从apt卸载默认软件包(我使用ubuntu 16.04)

全部失败,直到找到Ilya Golshtein的答案,然后在将使用yaml-cpp的代码中,我在YAML::LoadFIle行之前添加了此代码jsut

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

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

这是唯一可行的解​​决方案