0

I am trying to incorporate yaml-cpp into my project. I have a "Demes" class where I need to parse a YAML file.

This is the relevant method in Demes.cpp:

#include "Demes.hpp"

void Demes::parse(const std::string& fileName)
{
    YAML::Node test = YAML::LoadFile(fileName);
}

where Demes.hpp includes the yaml-cpp headers and declares the 'parse' method. Building with make -VERBOSE=1 (as suggested by @Tsyvarev) gives:

[100%] Linking CXX executable momentspp cd /home/gvbarroso/Devel/momentspp/build/src && /usr/bin/cmake -E cmake_link_script CMakeFiles/momentspp.dir/link.txt --verbose=1 /usr/bin/c++ -std=c++20 -Weffc++ -Wshadow -Wall -Wextra -ffast-math -O3 -march=native CMakeFiles/momentspp.dir/Log.cpp.o CMakeFiles/momentspp.dir/PolymorphismData.cpp.o CMakeFiles/momentspp.dir/SumStatsLibrary.cpp.o CMakeFiles/momentspp.dir/Drift.cpp.o CMakeFiles/momentspp.dir/Migration.cpp.o CMakeFiles/momentspp.dir/Mutation.cpp.o CMakeFiles/momentspp.dir/Recombination.cpp.o CMakeFiles/momentspp.dir/Epoch.cpp.o CMakeFiles/momentspp.dir/Model.cpp.o CMakeFiles/momentspp.dir/OptimizationWrapper.cpp.o CMakeFiles/momentspp.dir/Demes.cpp.o CMakeFiles/momentspp.dir/main.cpp.o -o momentspp -Wl,-rpath,/home/gvbarroso/.local/lib: /home/gvbarroso/.local/lib/libbpp-phyl3.so.1.0.0 /usr/lib/x86_64-linux-gnu/libboost_iostreams.so.1.74.0 /home/gvbarroso/.local/lib/libbpp-seq3.so.1.0.0 /home/gvbarroso/.local/lib/libbpp-core3.so.1.0.0 /usr/bin/ld: CMakeFiles/momentspp.dir/Demes.cpp.o: in function Demes::parse(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': Demes.cpp:(.text+0x4c): undefined reference to YAML::LoadFile(std::__cxx11::basic_string<char, std::char_traits, std::allocator > const&)' /usr/bin/ld: Demes.cpp:(.text+0x12c): undefined reference to `YAML::operator<<(std::ostream&, YAML::Node const&)' collect2: error: ld returned 1 exit status make[2]: *** [src/CMakeFiles/momentspp.dir/build.make:277: src/momentspp] Error 1 make[2]: Leaving directory '/home/gvbarroso/Devel/momentspp/build' make[1]: *** [CMakeFiles/Makefile2:125: src/CMakeFiles/momentspp.dir/all] Error 2 make[1]: Leaving directory '/home/gvbarroso/Devel/momentspp/build' make: *** [Makefile:156: all] Error 2

I am using CMake to build my project, but I am still fairly unfamiliar with it.

EDIT: I forgot to mention that I have two CMakeLists.txt files, one inside src and the other inside the external build.

The start of my CMakeLists.txt file in the external build is:

cmake_minimum_required (VERSION 3.5.0)
project (momentspp CXX)

SET(CMAKE_CXX_FLAGS "-std=c++20 -Weffc++ -Wshadow -Wall -Wextra -ffast-math -O3 -march=native")

And the part of it where I look for yaml-cpp is:

FIND_PACKAGE(yaml-cpp REQUIRED)
IF(yaml-cpp_FOUND)
    INCLUDE_DIRECTORIES(${yaml-cpp_INCLUDE_DIRS})
    SET(LIBS {yaml-cpp_LIBRARIES})
    MESSAGE("-- yaml-cpp libraries found here:")
    MESSAGE(" includes: ${yaml-cpp_INCLUDE_DIRS}")
ENDIF()

My full CMakeLists.txt file inside src is:

 SET(momentspp_CPP
  Log.cpp
  PolymorphismData.cpp
  SumStatsLibrary.cpp
  Drift.cpp
  Migration.cpp
  Mutation.cpp
  Recombination.cpp
  Epoch.cpp
  Model.cpp
  OptimizationWrapper.cpp
  Demes.cpp
  main.cpp
)

ADD_EXECUTABLE (momentspp ${momentspp_CPP})

SET(momentspp-targets momentspp)

FOREACH (target ${momentspp-targets})
    TARGET_LINK_LIBRARIES(${target} ${BPP_LIBS_SHARED} ${BOOST_LIBS_SHARED} ${EIGEN3_LIBS_SHARED} ${yaml-cpp_LIBS_SHARED})
   TARGET_LINK_LIBRARIES (${target} ${LIBS})
ENDFOREACH (target)

INSTALL(TARGETS ${momentspp-targets} DESTINATION ${CMAKE_INSTALL_BINDIR})

and this was working prior to the inclusion of yaml-cpp.

This feels like a rather complicated CMake set-up, but I am copying and editing it from a previous project where someone else helped me with it.

How can I fix the linking issue? I tried looking similar questions around here, but couldn't get their solutions to work for me (apparently those people where not using CMake to build their projects).

Thank you, Gustavo

5
  • You include directories with yaml-cpp headers using include_directories command, but seems to forgot to link with the library. In CMake linking is performed using target_link_libraries command. Commented Nov 1, 2022 at 0:14
  • thanks! In fact, I had forgotten to mention that I have two CMakeLists.txt files, and I do use target_link_libraries in the other... Commented Nov 1, 2022 at 15:34
  • If you use make for build the project, then you could run make VERBOSE=1 and inspect the exact command line used for linking. Check that given command line contains linkage with yaml-cpp library. If the linkage exists, but the error remains, then check that question about possible reasons why __cxx11 symbols cannot be found during the link. Commented Nov 1, 2022 at 15:54
  • thanks again! the command doesn't seem to contain the yaml-cpp library, but also, it doesn't seem to contain Eigen3 either (which I can use and work with...) Commented Nov 1, 2022 at 16:12
  • "it doesn't seem to contain Eigen3 either" - Eigen3 is a header only library, so it doesn't have a library file for link with. As for absence of linkage with yaml-cpp library, you need to debug your code for why it doesn't issue that linkage. You could perform debugging by inserting message() calls and printing values of used variables. If you completed debugging the code and the error remains, then make sure to paste into the question post the minimal reproducible example. Currently you code is far from complete as it contains only parts of your scripts. Commented Nov 1, 2022 at 16:27

1 Answer 1

0

Add the following preprocessor definition where you include yamp-cpp.

#define YAML_CPP_STATIC_DEFINE

I encountered a similar issue and found the original answer from here. It seems to be a specific issue for Windows. At least from my own experience, the build passes smoothly on Linux and macOS. A possible remedy was also proposed on GitHub and marked as addressed. However, it seems that the same issue still persists on Windows.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.