简体   繁体   English

使用外部库进行编译

[英]Compiling with external libraries

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. 我有一个问题,从github项目编译基于C ++的jwt库的一个示例(示例代码): jwt-cpp我克隆它并使用README文件中提供的步骤编译它,这似乎是成功的。

After that I did a ldconfig . 之后我做了一个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. 我已经阅读了这些问题以了解我可能做错了什么: 如何使用库使用Linux终端的外部库编译C文件 ,虽然第二个问题是针对C而不是C ++,但问题和解决方案适用于C ++也是如此。

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. 我很熟悉当我执行-lfoo时链接器尝试在-L选项提供的位置找到libfoo.a。

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 对于-I选项:我可以在/usr/local/include看到jwtopenssl目录
For -L options: I can see libjwt.a , libssl.a , libcrypto.a , libssl.so , etc at /usr/local/lib/ 对于-L选项:我可以在/usr/local/lib/看到libjwt.alibssl.alibcrypto.alibssl.so

Question: What am I doing wrong to compile this example? 问题:编译此示例我做错了什么?

You're gonna kick yourself when I tell you the issue. 当我告诉你这个问题时,你会踢自己。

Put the source file, sign.cpp before the library declarations in your program: 将源文件sign.cpp放在程序中的库声明之前

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. 原因是unix链接器在命令行中不向后看以解决依赖关系。 There's a few command line switches (eg --start-group and --end-group ) that will adjust this behavior, but the above will get you unblocked for now. 有一些命令行开关(例如--start-group--end-group )可以调整这种行为,但是上面的内容会让你现在解锁。 More details here . 更多细节在这里

In the above example, I took the liberty of removing the duplicated INCLUDE path arguments. 在上面的例子中,我冒昧地删除了重复的INCLUDE路径参数。 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. 您可能甚至不需要-I/usr/local/include-L/usr/local/lib部分,因为它通常已经在标准编译器路径中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM