簡體   English   中英

yaml-cpp 的編譯器錯誤 - 未定義對`YAML::detail::node_data::convert_to_map` 的引用

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

這是完整的日志:

/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()類的事情和其他功能。 我認為問題在於使用基於字符串的 map 來訪問內部節點。

您似乎沒有正確鏈接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)

在 Debian 系統上嘗試編譯 OpenXcom 時,我遇到了類似的情況。 事實證明,我混合使用了測試包和穩定包,yaml 包來自穩定包,如果有多個初始函數,這種組合會以某種方式導致鏈接失敗。

如果這是您遇到的情況(並且您也在使用 Debian),請嘗試從 stable 編譯源包

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

此命令將為 libyaml 構建 .deb 包,然后您可以使用 dpkg 插入它們,如下所示:

dpkg -i libyaml-cpp0.5*.deb

作為根。

從源代碼編譯 libyaml 將使其鏈接到您已經擁有的測試庫,而不是期望穩定的庫,因此應該可以解決上述問題。 至少對我有用。

即使您不使用 Debian,從源代碼(例如 tarball)編譯 yaml-cpp 也可能出於類似原因而工作。

確保這兩個文件存在:

/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

當我嘗試運行“cmake .”時,出現了一些錯誤,所以我刪除了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

我確認某些版本的 yaml-cpp 庫包含此問題(與不正確的鏈接無關)。 它很臟,但我已經通過在我的代碼中定義空函數來解決它,它看起來像

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

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

該方法並不完美(例如,因為如果使用另一個庫版本會導致重復)。

就我而言,我在兩台計算機上運行完全相同的代碼,但只在其中一台計算機上出現錯誤,這幾乎讓我發瘋。 這不是編譯錯誤,鏈接錯誤之類的,我認為代碼很臟或其他。

我嘗試了所有選項:

  1. 從源代碼進行常規構建並使用cmake .. => make => make install
  2. 與 1 相同, CC=$(which gcc) CXX=$(which g++) cmake -DBUILD_SHARED_LIBS=ON ..
  3. 從 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>)
{
}

這是唯一有效的解決方案

我在這里聚會遲到了,不知道我在做什么,但是對於那些使用 Windows 的人,請確保您的 IDE 喜歡您的 mingw-g++。 我的自動默認為草莓 perl(?),當我將其更改為 mingw-g++ 時,一切都開始工作了。 我想這與版本控制有關嗎?

這也困擾着我。 我在 yaml-cpp 版本為“0.7.0”時遇到過它。 我改用“0.6.0”解決了這個問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM