json-schema-validator icon indicating copy to clipboard operation
json-schema-validator copied to clipboard

Linking issue ("undefined reference") when using nlohmann_json/3.9.1

Open gmclay opened this issue 4 years ago • 6 comments

Build OS: Ubuntu 18.04 Compiler: GCC (g++ 9.4.0) Using CMake and Conan

I've been using nlohmann_json 3.7.3 for 2+ years but wanted to add a schema validator. Link below says json-schema-validator has a dependency on nlohmann_json 3.9.1.

https://conan.io/center/json-schema-validator?version=2.1.0&tab=dependencies

I switched to nlohmann_json 3.9.1 and my build / unit tests passed as expected. However, once json-schema-validator/2.1.0 was added and the json_validator was called, there is an "undefined reference" error.

Note, I see nlohmann_json/3.7.3 is used in the conanfile.py (link below) so I switched back to that and the undefined reference goes away.

https://github.com/pboettch/json-schema-validator/blob/master/conanfile.py

Is this a documentation issue on conan.io? Or is json-schema-validator/2.1.0 supposed to be compatible with nlohmann_json/3.9.1?

Linker error

CMakeFiles/project.dir/JsonSchemaValidator.cpp.o: In function `JsonSchemaValidator::JsonSchemaValidator()':
JsonSchemaValidator.cpp:(.text+0x398): undefined reference to `nlohmann::json_schema::json_validator::json_validator(std::function<void (nlohmann::json_uri const&, nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> > >&)>, std::function<void (std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)>)'
JsonSchemaValidator.cpp:(.text+0x3d5): undefined reference to `nlohmann::json_schema::json_validator::set_root_schema(nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> > > const&)'
JsonSchemaValidator.cpp:(.text+0x3e9): undefined reference to `nlohmann::json_schema::json_validator::validate(nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> > > const&) const'
JsonSchemaValidator.cpp:(.text+0x40c): undefined reference to `nlohmann::json_schema::json_validator::validate(nlohmann::basic_json<std::map, std::vector, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >, bool, long, unsigned long, double, std::allocator, nlohmann::adl_serializer, std::vector<unsigned char, std::allocator<unsigned char> > > const&) const'
collect2: error: ld returned 1 exit status

JsonSchemaValidator.cpp -- essentially a copy of the sample code for json-schema-validator. Reference to JsonSchemaValidator.hpp removed for brevity.

#include <iostream>
#include <nlohmann/json-schema.hpp>
#include <nlohmann/json.hpp>

using nlohmann::json;
using nlohmann::json_schema::json_validator;

// The schema is defined based upon a string literal
static json uri_schema = R"(
{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "type": "object",
  "properties": {
    "myUri": {
      "type":"string",
      "format": "uri"
    }
  }
})"_json;

// The people are defined with brace initialization
static json good_uri = {{"myUri", "http://hostname.com/"}};
static json bad_uri = {{"myUri", "http:/hostname.com/"}};

static void uri_format_checker(const std::string& format,
                               const std::string& value)
{
    if (format == "uri")
    {
        if (value.find("://") == std::string::npos)
            throw std::invalid_argument("URI does not contain :// - invalid");
    }
    else
    {
        throw std::logic_error("Don't know how to validate " + format);
    }
}

JsonSchemaValidator::JsonSchemaValidator()
{
    json_validator validator(nullptr, uri_format_checker); // create validator

    try
    {
        validator.set_root_schema(uri_schema); // insert root-schema
    }
    catch (const std::exception& e)
    {
        std::cerr << "Validation of schema failed, here is why: " << e.what()
                  << "\n";
        // return EXIT_FAILURE;
    }

    validator.validate(good_uri);

    try
    {
        validator.validate(bad_uri);
    }
    catch (const std::exception& e)
    {
        std::cerr << "Validation expectedly failed, here is why: " << e.what()
                  << "\n";
    }
}

JsonSchemaValidator::~JsonSchemaValidator()
{
}

gmclay avatar Nov 16 '21 18:11 gmclay

I'm not using Conan so I can't really help. Is there an issue-database on their side, because I think it should be handled there.

pboettch avatar Nov 17 '21 06:11 pboettch

@gmclay Can you please show the complete cmake code that you use to: a) add the json-schema-validator package to your conan dependencies b) link json-schema-validator to your target? I use json-schema-validator 2.1.0 via conan, with the same package from conan.io that you've linked in the OP, and it works just fine.

iksemyonov avatar Nov 18 '21 11:11 iksemyonov

@pboettch thanks for the prompt response. I'm uncertain where the issue belongs but if you can confirm nlohmann_json/3.9.1 works with json-schema-validator/2.1.0 for you without conan then it is probably safe to say conan is related to the issue I'm seeing. Please confirm.

Please note that the conan file in this project (link below) references nlohmann_json/3.7.3 (old version -- works for me) and not nlohmann_json/3.9.1 (new version -- does not work for me). Is this file used in any testing? If so, you may see the issue if you use 3.9.1.

https://github.com/pboettch/json-schema-validator/blob/master/conanfile.py

@iksemyonov thanks for sharing that this is working for you. To be clear, are you using nlohmann_json/3.7.3 or nlohmann_json/3.9.1 with json-schema-validator/2.1.0?

Below are the conanfile and the src/CMakeList.txt. Note, I only included CMakeList.txt relevant lines since it is a large project with a couple CMake files. I think I included the relevant pieces but please let me know if there is a specific cmake command you'd like to see.

Could you also share how you're building / linking json-schema-validator/2.1.0 using cmake and conan?

conanfile.py

from sys import platform
from conans import ConanFile, CMake, tools

class PROJECTConan(ConanFile):
    settings = "os", "compiler", "build_type", "arch"

    requires = ["gtest/1.10.0",
                "nlohmann_json/3.7.3",
                "zlib/1.2.11",
                "boost/1.71.0",
                "b2/4.5.0",
                "json-schema-validator/2.1.0"]

    generators = "cmake"

      # gtest options
    default_options = {"gtest:no_main": True, "b2:use_cxx_env": True, "b2:toolset": "gcc"}

    def imports(self):
        self.copy("license*", dst="licenses", folder=True, ignore_case=True)
        self.copy("copying*", dst="licenses", folder=True, ignore_case=True)
        self.copy("*.dll", "bin", "bin")
        self.copy("*.dll", "bin", "lib")
        self.copy("*.so", "lib", "lib")
        self.copy("*.so.*", "lib", "lib")
        self.copy("*.a", "lib", "lib")
        self.copy("*.o", "lib", "lib")

src/CMakeList.txt

target_link_libraries(project PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${PROJECT_LINK_LIBS} ${CMAKE_DL_LIBS} ${CONAN_LIBS_JSON-SCHEMA-VALIDATOR})

include_directories(${PROJECT_INCLUDE_DIR} ${CONAN_INCLUDE_DIRS_JSON-SCHEMA-VALIDATOR})

if (UNIX)
    include_directories(SYSTEM ${CONAN_INCLUDE_DIRS_NLOHMANN_JSON} ${CONAN_INCLUDE_DIRS_BOOST} ${TASKFLOW_INCLUDE_DIR})
endif()

gmclay avatar Nov 23 '21 23:11 gmclay

Is this still a problem or did you find a solution?

pboettch avatar Jun 06 '22 08:06 pboettch

@pboettch this problem still exists but I have been using nlohmann_json/3.7.3 and json-schema-validator/2.1.0 to avoid the issue. I don't have a solution.

gmclay avatar Jun 06 '22 15:06 gmclay

When linking the final binary could you get the whole compiler/linker line? Would be interesting to see where it put the validator-lib.

Maybe compare with the working version.

pboettch avatar Jun 06 '22 20:06 pboettch