1

Attempting to link in libyaml (0.2.5) using Visual Studio 2019 Enterprise and CMake, as I have a cross-platform (Linux/Windows) project that uses this library. According to the documentation, this library should work in Windows 10. It links in just fine on Linux (64-bit machine).

I'm compiling it as a static lib, and it has no issue generating the .lib file. I've copied it to the appropriate location that I'm linking in from my CMakelists.txt, as well as the header.

When I link it in from my project on Windows:

ts.lib(yamlparser.cxx.obj) : error LNK2019: unresolved external symbol __imp_yaml_parser_initialize referenced in function "public: bool __cdecl YAMLParser::parse_cfg(void)" (?parse_cfg@YAMLParser@@QEAA_NXZ)
ts.lib(yamlparser.cxx.obj) : error LNK2019: unresolved external symbol __imp_yaml_parser_set_input_file referenced in function "public: bool __cdecl YAMLParser::parse_cfg(void)" (?parse_cfg@YAMLParser@@QEAA_NXZ)
ts.lib(yamlparser.cxx.obj) : error LNK2019: unresolved external symbol __imp_yaml_parser_scan referenced in function "public: bool __cdecl YAMLParser::parse_cfg(void)" (?parse_cfg@YAMLParser@@QEAA_NXZ)

This is what I'm doing on the CMake side - the very same thing I'm doing to link in my GoogleTest libraries on both Linux and Windows:

if (UNIX)
...
...
else()
  set (MY_LIB_DIR "C:/mylib/lib")
  set (MY_INCLUDE "C:/mylib/include")

  set (YAML_LIB "${MY_LIB_DIR}/yaml.lib")
  set (VCPKG_LIBRARY_LINKAGE static) 
endif()

include_directories(${MY_INCLUDE})

add_library(ts
    ...
    ...
)

add_executable(myexec main.cxx)
target_link_libraries(myexec ts ${YAML_LIB})

VS isn't giving me many clues here except that there's a linkage problem that I can't quite figure out.

Any advice on how I can debug this or what the problem may be?

noisebloom
  • 65
  • 5
  • It seems your `yaml.lib` contains C++ library for YAML, but this library depends from C library. So you need to link your executable with C library for YAML as well. (You are aware that a **static** library doesn't carry dependencies, aren't you?). – Tsyvarev Jan 23 '21 at 09:34
  • libyaml looks to be a C library with no C++ components. I'm linking in just the single static library file on Linux issues and can link and run with no issues. – noisebloom Jan 23 '21 at 17:15
  • Hm, actually it is `ts` library which requires symbols libyaml (this is why error message contains `ts.lib(yamlparser.cxx.obj)`). And it seems that your libyaml doesn't contain that symbols. How do you build `libyaml`? Did you use Visual Studio 2019 Enterprise for that? – Tsyvarev Jan 23 '21 at 17:27
  • Yes, ts is a library I've created to easily accommodate my CMake dir structure (helps when you have separate src/ and tests/ dirs). I did build libyaml using Visual Studio 2019 Enterprise using the default settings + what is generated from my CMakelist files. – noisebloom Jan 23 '21 at 17:45
  • Hm, so **when** you got the error? Do you got this error you build the `ts` library or when you build `myexec` executable? – Tsyvarev Jan 23 '21 at 18:17
  • It seems to be when ts, the library of my src/ tree, is linking (the error calls out ts.lib). Hmm... – noisebloom Jan 24 '21 at 14:56
  • You don't link `ts` library with `yaml.lib` one. The only `target_link_libraries` call you have links `myexec` executable (the first argument) with `ts` library and with `yaml.lib` (the rest arguments). You need to call `target_link_libraries(ts ${YAML_LIB})` for link `ts` library with `yaml.lib`. – Tsyvarev Jan 24 '21 at 15:01
  • Yeah, that does sound right and what I'm missing... Strange how it all links up properly in Linux. Will give this a shot! – noisebloom Jan 24 '21 at 19:28
  • I take that back: ts is a static lib and so is yaml.lib, so there's no way of actually *linking* them together. I believe my target_link_libraries() call should be able to link both of them in, but I'm still getting linker errors on Windows. – noisebloom Jan 26 '21 at 19:47
  • I've removed ts.lib to simply have myexec link in all source files and yaml.lib, and I still get this linker error, so something is funky with the linkage here. I've validated that extern "C" is in the lib header... My best guess is that there's something in VS that is screwing up the linkage, but I haven't found it yet. – noisebloom Jan 26 '21 at 20:38
  • Figured it out! The __imp was the clue that my code was trying to include the library dynamically... Opening up yaml.h, I noticed that it tries to export from DLL unless YAML_DECLARE_STATIC is defined. Defined this in CMake and my issue is resolved. – noisebloom Jan 26 '21 at 21:37

1 Answers1

1

The __imp was the clue that my code was trying to include the library dynamically... Opening up yaml.h, I noticed that it tries to export from DLL unless YAML_DECLARE_STATIC is defined. Defined this in CMake and my issue is resolved.

noisebloom
  • 65
  • 5