4

I'm trying to get a simple test program with yaml-cpp to run that looks like this:

// main.cpp

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

int main(int argc, const char *argv[])
{
     YAML::Node config = YAML::LoadFile("config.yaml");
     std::cout << config << std::endl;
}

I'm trying to compile with this command:

g++ -lyaml-cpp -L$(HOME)/local/yaml-cpp/build -I$(HOME)/local/yaml-cpp/include -std=c++11 main.cpp

and I'm getting an error that looks like this:

/tmp/ccz0D5ol.o: In function `main':
main.cpp:(.text+0xdd): undefined reference to `YAML::LoadFile(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)'
collect2: error: ld returned 1 exit status
make: *** [all] Error 1

Here's the g++ I'm using:

$ g++ --version
g++ (GCC) 5.4.0
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

This is on a linux machine where I don't have root access. I cloned the git repo to $HOME/local/yaml-cpp, created a build directory, ran cmake -DBUILD_SHARED_LIBS=ON .., then make, which created the file libyaml-cpp.so.0.6.2 and symlinks libyaml-cpp.so.0.6 and libyaml-cpp.so. My cmake is version 3.11.2 if that matters.

Not sure if this is helpful, but I first ran this problem by the maintainer of yaml-cpp as a github issue, and he said

It's likely a configuration error; you might be able to get an answer if you ask on Stack Overflow.

I also found a similar question with pretty much the exact same problem, but her solution of rearranging the order of the compile command didn't work for me. I get the same problem whether -lyaml-cpp is towards the beginning or the end of the command.

Any help would be appreciated.

Ben Lindsay
  • 1,686
  • 4
  • 23
  • 44
  • 2
    You should put `-lyaml-cpp` at the end of the command line, after `main.cpp` – user7860670 May 26 '18 at 17:02
  • @VTT Thanks, but unfortunately that's one of the many arrangements of compile arguments that I tried. I just tried it again and got the same results. – Ben Lindsay May 26 '18 at 17:11
  • Hmm, maybe it is some sort of binary incompatibility then. Which functions does yaml library export? Is yaml-cpp compiled with `-std=c++11`? – user7860670 May 26 '18 at 17:14
  • @VTT although when `-lyaml-cpp` is before `main.cpp` there is an additional error that looks like this: `main.cpp:(.text+0x106): undefined reference to `YAML::operator<<(std::ostream&, YAML::Node const&)'`. This error goes away with the `-lyaml-cpp` at the end of the line. Not sure if that means anything – Ben Lindsay May 26 '18 at 17:17
  • @VTT I'm not sure if `-std=c++11` was used when yaml-cpp was compiled. I can't find g++ in the Makefile. How would I check? – Ben Lindsay May 26 '18 at 17:18
  • I guess you should be able to figure it out from cmake file. Or enforce this behavior by explicitly specifying standard or compilation flags (which would be a better option). If `-lyaml-cpp` is placed before `main.cpp` then it won't be used to fill the undefined symbols required by `main.cpp`. – user7860670 May 26 '18 at 17:19
  • SO suggested moving to a chatroom to avoid cluttering the comments. If you have a couple minutes and are feeling generous I'd appreciate some tips there. [chatroom link](https://chat.stackoverflow.com/rooms/171838/discussion-between-ben-lindsay-and-vtt). – Ben Lindsay May 26 '18 at 17:22
  • @VTT you were right about looking into compiler options in cmake! Thanks for your help! – Ben Lindsay May 26 '18 at 18:46

1 Answers1

1

@VTT was right to point me towards cmake and compiler stuff. When I looked at the results of the original cmake command, the first 2 lines said

-- The C compiler identification is GNU 4.8.5
-- The CXX compiler identification is GNU 4.8.5

Even though which gcc and which g++ point to version 5.4.0. I found this SO answer which points to this cmake FAQ page saying that you need to set the CC and CXX environment variables to specify a different compiler. So I changed my cmake command to this:

CC=$(which gcc) CXX=$(which g++) cmake -DBUILD_SHARED_LIBS=ON ..

and now everything works great.

Ben Lindsay
  • 1,686
  • 4
  • 23
  • 44