1

I am having an issue with compiling one of the sample (example codes) for a C++ based jwt library from a github project: jwt-cpp I cloned it and compiled it using the steps provided in the README file, which seemed successful.

After that I did a ldconfig.

Now, I am trying to build the example code.

#include <iostream> #include "jwt/jwt_all.h" using json = nlohmann::json; int main() { // Setup a signer HS256Validator signer("secret!"); // Create the json payload that expires 01/01/2017 @ 12:00am (UTC) json payload = {{"sub", "subject"}, {"exp", 1483228800}}; // Let's encode the token to a string auto token = JWT::Encode(signer, payload); std::cout << token << std::endl; } 

I compile this with a command on terminal, which says:

g++ -std=c++11 \ -I/usr/local/include \ -I/usr/local/include \ /usr/local/lib/libjwt.a \ /usr/local/lib/libcrypto.a \ sign.cpp -o sign 

And it results in following error:

/tmp/ccX4ghoR.o: In function `main': sign.cpp:(.text+0x24e): undefined reference to JWT::Encode(MessageSigner 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> 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>)' /tmp/ccX4ghoR.o: In function `HS256Validator::HS256Validator(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)': sign.cpp:(.text._ZN14HS256ValidatorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN14HS256ValidatorC5ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x21): undefined reference to `EVP_sha256' sign.cpp:(.text._ZN14HS256ValidatorC2ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE[_ZN14HS256ValidatorC5ERKNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE]+0x5f): undefined reference to `HMACValidator::HMACValidator(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&, evp_md_st const*, std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> > const&)' /tmp/ccX4ghoR.o: (.rodata._ZTV14HS256Validator[_ZTV14HS256Validator]+0x20): undefined reference to `HMACValidator::Verify(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> const&, unsigned char const*, unsigned long, unsigned char const*, unsigned long) const' /tmp/ccX4ghoR.o: (.rodata._ZTV14HS256Validator[_ZTV14HS256Validator]+0x28): undefined reference to `HMACValidator::toJson[abi:cxx11]() const' /tmp/ccX4ghoR.o: (.rodata._ZTV14HS256Validator[_ZTV14HS256Validator]+0x38): undefined reference to `MessageValidator::Accepts(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> const&) const' /tmp/ccX4ghoR.o: (.rodata._ZTV14HS256Validator[_ZTV14HS256Validator]+0x40): undefined reference to `HMACValidator::Sign(unsigned char const*, unsigned long, unsigned char*, unsigned long*) const' /tmp/ccX4ghoR.o: In function `HS256Validator::~HS256Validator()': sign.cpp: (.text._ZN14HS256ValidatorD2Ev[_ZN14HS256ValidatorD5Ev]+0x20): undefined reference to `HMACValidator::~HMACValidator()' /tmp/ccX4ghoR.o: (.rodata._ZTI14HS256Validator[_ZTI14HS256Validator]+0x10): undefined reference to `typeinfo for HMACValidator' collect2: error: ld returned 1 exit status 

What have I tried:

I have read through these questions to know what I might be doing wrong: How to use libraries and compile C file using external library from linux terminal, Although second question is specifically for C and not C++, the problem there and the solution is applicable to C++ as well.

I have also tried variants of command line compilation such as,

g++ -std=c++11 \ -I/usr/local/include \ -I/usr/local/include \ -L/usr/local/lib/ \ -lcrypto -ljwt \ sign.cpp -o sign 

I am familiar with the fact that when I do a -lfoo, the linker tries to find a libfoo.a at the location provided with -L option.

I have confirmed that the options that are used for compilation contains what they should.
For -I options: I can see jwt and openssl directories in /usr/local/include
For -L options: I can see libjwt.a, libssl.a, libcrypto.a, libssl.so, etc at /usr/local/lib/

Question: What am I doing wrong to compile this example?

1 Answer 1

4

You're gonna kick yourself when I tell you the issue.

Put the source file, sign.cpp before the library declarations in your program:

g++ -std=c++11 -I/usr/local/include -L/usr/local/lib sign.cpp -lcrypto -ljwt -o sign 

The reason being is that the unix linker doesn't look backwards in the command line to resolve dependencies. There's a few command line switches (e.g. --start-group and --end-group) that will adjust this behavior, but the above will get you unblocked for now. More details here.

In the above example, I took the liberty of removing the duplicated INCLUDE path arguments. You probably don't even need the -I/usr/local/include or -L/usr/local/lib part because that's typically already in the standard compiler path.

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

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.