yaml-cpp icon indicating copy to clipboard operation
yaml-cpp copied to clipboard

Visual Studio 2019 shared library build link errors

Open jhandley opened this issue 5 years ago • 5 comments

Building for Visual Studio 2019 using shared libraries does not link.

Run cmake as follows: cmake -G "Visual Studio 16 2019" -B build -DYAML_BUILD_SHARED_LIBS=1

Open the project in Visual Studio and build. You get the following link errors:

11>emitter_test.obj : error LNK2001: unresolved external symbol "struct YAML::_Null YAML::Null" (?Null@YAML@@3U_Null@1@A)
11>node_spec_test.obj : error LNK2001: unresolved external symbol "struct YAML::_Null YAML::Null" (?Null@YAML@@3U_Null@1@A)
11>error_messages_test.obj : error LNK2001: unresolved external symbol "private: static struct std::atomic<unsigned __int64> YAML::detail::node::m_amount" (?m_amount@node@detail@YAML@@0U?$atomic@_K@std@@A)
11>node_spec_test.obj : error LNK2001: unresolved external symbol "private: static struct std::atomic<unsigned __int64> YAML::detail::node::m_amount" (?m_amount@node@detail@YAML@@0U?$atomic@_K@std@@A)
11>node_test.obj : error LNK2001: unresolved external symbol "private: static struct std::atomic<unsigned __int64> YAML::detail::node::m_amount" (?m_amount@node@detail@YAML@@0U?$atomic@_K@std@@A)
11>Y:\cspro\dev\yaml-cpp\build\test\Debug\yaml-cpp-tests.exe : fatal error LNK1120: 2 unresolved externals

Microsoft Visual Studio Community 2019 Version 16.7.5 Visual C++ 2019 00435-60000-00000-AA512

jhandley avatar Oct 24 '20 15:10 jhandley

Looks like the problem is that YAML_CPP_DLL needs to be defined in the yaml-cpp-tests project.

jhandley avatar Oct 24 '20 15:10 jhandley

@jhandley, May I ask, is it normal to add YAML_CPP_DLL macro ourselves manually? Or is it a bug required to be fixed, which means yaml-cpp should add this YAML_CPP_DLL macro automatically for us?

// After I add this macro, YAML_CPP_DLL,
// the program builds and links successfully.
#define YAML_CPP_DLL
#include <iostream>
#include <vector>
#include <yaml-cpp/yaml.h>
using namespace std;

int main()
{
    YAML::Node node = YAML::Load("{pi: 3.14159, [0, 1]: integers}");

    // this needs the conversion from Node to double
    double pi = node["pi"].as<double>();

    // this needs the conversion from double to Node
    node["e"] = 2.71828;

    // this needs the conversion from Node to std::vector<int> (*not* the other way around!)
    std::vector<int> v;
    v.push_back(0);
    v.push_back(1);
    std::string str = node[v].as<std::string>();

    cout << "str = " << str << endl;

    return 0;
}

hwhsu1231 avatar May 05 '22 03:05 hwhsu1231

@hwhsu1231 yes that is normal. I usually add it to the project properties in Visual Studio rather than in the source code. It is a common pattern when using DLLs in C++ projects on Windows.

jhandley avatar May 05 '22 07:05 jhandley

Out of curiosity, why isn't this broken in the continuous build on Windows/shared? (see, e.g., this run)

jbeder avatar May 05 '22 20:05 jbeder

you should build with:

cmake -B build_v142_x86 -A Win32 -G "Visual Studio 16 2019" -DYAML_BUILD_SHARED_LIBS=on -DYAML_CPP_BUILD_TESTS=off
cmake --build build_v142_x86 --config Debug
cmake --build build_v142_x86 --config Release

cmake -B build_v142_x64 -A x64 -G "Visual Studio 16 2019" -DYAML_BUILD_SHARED_LIBS=on -DYAML_CPP_BUILD_TESTS=off
cmake --build build_v142_x64 --config Debug
cmake --build build_v142_x64 --config Release

jsrdzhk avatar Sep 06 '22 01:09 jsrdzhk