Undefined reference in app which includes library
-
What exact linker error do you get? Please post the error output. If you use functions from a library you have to link against it.
-
What exact linker error do you get? Please post the error output. If you use functions from a library you have to link against it.
wrote on 18 Jul 2022, 15:55 last edited by@Christian-Ehrlicher Sorry for the late reply, I'm off work atm.
This is taken directly from the output I'm getting from QT creator

vBact::Test(int)Is a function I have defined in my library, in its definition I callERR_load_crypto_stringsfunction from OpenSSL. That's where the linker(?) tells me there's a problem. Here's the weird part, if I call the same (OpenSSL) function from my app it builds fine.If you use functions from a library you have to link against it.
How can I be sure I'm linking correctly? I just used QT's library wizard to add my library to my app.
-
ERR_load_crypto_strings is a (deprecated) function from libcrypto so you must link against the crypto lib
How can I be sure I'm linking correctly?
By reading the docs of the function you use and hope that you find a notice on which library the function is in.
-
wrote on 18 Jul 2022, 17:03 last edited by
ERR_load_crypto_strings is a (deprecated) function from libcrypto so you must link against the crypto lib
Maybe the terminology is lost on me, but when you say linking you mean "including" the library in the ".pro" file, right?
If so that's what I'm doing here, no?# Add OpenSSL lib LIBS += -lcryptoThe problem is not
ERR_load_crypto_stringsitself, it happens with every function from OpenSSL.For example, I've uncocumented some code I commented for testing purposes, it uses even more OpenSSL functions, this is the output I'm getting

-
ERR_get_error is in libssl.
-
wrote on 19 Jul 2022, 04:47 last edited by
But I include libcrypto in my library, there it builds fine, even without libssl.
The problem comes when compiling my app with my library. I can copy the code from my library into my app, and compile with libcrypto, and it'll work fine.Why doesn't it work when I build with my library?
-
wrote on 19 Jul 2022, 07:38 last edited by
Update, maybe?
I've been trying to manually build the library with
g++ -c Crypto.cpp -lcrypto -lssl ar r libCrypto.a Crypto.oThis works, it creates a
libCrypto.afile without problems.Next, I created a small test app with only a single
mainfunction, which uses the functionvBact::Encrypt()from my library. To build it I'm usingg++ main.cpp -L./ -lCryptoThis produces the following output
.//libCrypto.a(Crypto.o): In function `vBact::HandleSSL(int)': Crypto.cpp:(.text+0x36): undefined reference to `ERR_load_crypto_strings' Crypto.cpp:(.text+0x42): undefined reference to `ERR_get_error' Crypto.cpp:(.text+0x55): undefined reference to `ERR_error_string' .//libCrypto.a(Crypto.o): In function `vBact::Encrypt(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&, unsigned int)': Crypto.cpp:(.text+0x122): undefined reference to `EVP_CIPHER_CTX_free' Crypto.cpp:(.text+0x127): undefined reference to `EVP_CIPHER_CTX_new' Crypto.cpp:(.text+0x2a6): undefined reference to `EVP_aes_256_cbc' Crypto.cpp:(.text+0x2d1): undefined reference to `EVP_EncryptInit_ex' Crypto.cpp:(.text+0x395): undefined reference to `EVP_EncryptUpdate' Crypto.cpp:(.text+0x3eb): undefined reference to `EVP_EncryptFinal_ex' .//libCrypto.a(Crypto.o): In function `vBact::Test(int)': Crypto.cpp:(.text+0x52a): undefined reference to `ERR_load_crypto_strings' collect2: error: ld returned 1 exit statusWhere am I going wrong?
-
Update, maybe?
I've been trying to manually build the library with
g++ -c Crypto.cpp -lcrypto -lssl ar r libCrypto.a Crypto.oThis works, it creates a
libCrypto.afile without problems.Next, I created a small test app with only a single
mainfunction, which uses the functionvBact::Encrypt()from my library. To build it I'm usingg++ main.cpp -L./ -lCryptoThis produces the following output
.//libCrypto.a(Crypto.o): In function `vBact::HandleSSL(int)': Crypto.cpp:(.text+0x36): undefined reference to `ERR_load_crypto_strings' Crypto.cpp:(.text+0x42): undefined reference to `ERR_get_error' Crypto.cpp:(.text+0x55): undefined reference to `ERR_error_string' .//libCrypto.a(Crypto.o): In function `vBact::Encrypt(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&, unsigned int)': Crypto.cpp:(.text+0x122): undefined reference to `EVP_CIPHER_CTX_free' Crypto.cpp:(.text+0x127): undefined reference to `EVP_CIPHER_CTX_new' Crypto.cpp:(.text+0x2a6): undefined reference to `EVP_aes_256_cbc' Crypto.cpp:(.text+0x2d1): undefined reference to `EVP_EncryptInit_ex' Crypto.cpp:(.text+0x395): undefined reference to `EVP_EncryptUpdate' Crypto.cpp:(.text+0x3eb): undefined reference to `EVP_EncryptFinal_ex' .//libCrypto.a(Crypto.o): In function `vBact::Test(int)': Crypto.cpp:(.text+0x52a): undefined reference to `ERR_load_crypto_strings' collect2: error: ld returned 1 exit statusWhere am I going wrong?
wrote on 19 Jul 2022, 07:53 last edited by JonB@Christian-Ehrlicher said in Undefined reference in app which includes library:
ERR_get_error is in libssl.
All these are in libssl. But while you link against that in your first case (
-lssl) you do not do so in your second case, you only go-lCrypto. hence the undefined references!I think you are thinking that once you have created your
libCrypto.ait contains thecrypto/sslyou specified while building it. It does not!. The-lcrypto -lsslyou specified tells it these are external libraries it can use. You must re-specify them whenever you link against your-lCrypto. (And the corresponding.sofiles must be findable at runtime.) Follow now?BTW, I find it incredibly confusing that you are building a
libCrypto.alinking with alibcrypto.a(Linux case-sensitive distinguishes). Please name your library differently from the libraries it links against! -
@Christian-Ehrlicher said in Undefined reference in app which includes library:
ERR_get_error is in libssl.
All these are in libssl. But while you link against that in your first case (
-lssl) you do not do so in your second case, you only go-lCrypto. hence the undefined references!I think you are thinking that once you have created your
libCrypto.ait contains thecrypto/sslyou specified while building it. It does not!. The-lcrypto -lsslyou specified tells it these are external libraries it can use. You must re-specify them whenever you link against your-lCrypto. (And the corresponding.sofiles must be findable at runtime.) Follow now?BTW, I find it incredibly confusing that you are building a
libCrypto.alinking with alibcrypto.a(Linux case-sensitive distinguishes). Please name your library differently from the libraries it links against!wrote on 19 Jul 2022, 08:00 last edited by@JonB
I changedg++ main.cpp -L./ -lCryptotog++ main.cpp -L./-lMyCrypto -lssl -lcryptoAnd it worked? But this doesn't really make sense to me.
We're using other libraries, which I'm sure use other libraries, and yet we don't have to go through the entire dependency chain every time we want to build a project, why is this the case here? -
@JonB
I changedg++ main.cpp -L./ -lCryptotog++ main.cpp -L./-lMyCrypto -lssl -lcryptoAnd it worked? But this doesn't really make sense to me.
We're using other libraries, which I'm sure use other libraries, and yet we don't have to go through the entire dependency chain every time we want to build a project, why is this the case here?wrote on 19 Jul 2022, 08:15 last edited by JonB@Josef-Lintz
There seems to be no peace for the wicked :) I tell you how to make what you showed work, and now you ask me why something else of which I have no knowledge does/does not work!Maybe the other cases are static libraries which do actually include other libraries? Maybe the
arcommands include the other libraries too? Maybe there is an option to theldlinker where you tell it to mark the.afile being generated with references to the other libraries it will need?You could use e.g.
nmto examine the symbols etc. in each library file to understand what is there and how that differs between your cases. -
@Josef-Lintz
There seems to be no peace for the wicked :) I tell you how to make what you showed work, and now you ask me why something else of which I have no knowledge does/does not work!Maybe the other cases are static libraries which do actually include other libraries? Maybe the
arcommands include the other libraries too? Maybe there is an option to theldlinker where you tell it to mark the.afile being generated with references to the other libraries it will need?You could use e.g.
nmto examine the symbols etc. in each library file to understand what is there and how that differs between your cases.wrote on 19 Jul 2022, 08:43 last edited by@JonB Well, at least you pointed me in the right direction, thank you.
-
wrote on 19 Jul 2022, 09:44 last edited by
So I figured out my problem. I incorrectly assumed that static libraries in Linux behave similarly to ".lib" files in Windows. According to this answer, you cannot "embed" dependencies in static libraries. So I recompiled my library as a shared object and now it works.
g++ -c -fPIC Crypto.cpp g++ -shared Crypto.o -o libMyCrypto.so -lcryptoBut there's one last thing that bugs me. If I manually create a shared object and link it with my app, and rename my library to something else, I can't run my app anymore because the app can't find its dependency.
If I build the app using QT creator, there's no ".so" file in the
builddirectory, and it runs fine.Does QT embed ".so" files in the executable?
-
So I figured out my problem. I incorrectly assumed that static libraries in Linux behave similarly to ".lib" files in Windows. According to this answer, you cannot "embed" dependencies in static libraries. So I recompiled my library as a shared object and now it works.
g++ -c -fPIC Crypto.cpp g++ -shared Crypto.o -o libMyCrypto.so -lcryptoBut there's one last thing that bugs me. If I manually create a shared object and link it with my app, and rename my library to something else, I can't run my app anymore because the app can't find its dependency.
If I build the app using QT creator, there's no ".so" file in the
builddirectory, and it runs fine.Does QT embed ".so" files in the executable?
wrote on 19 Jul 2022, 09:54 last edited by JonB@Josef-Lintz said in Undefined reference in app which includes library:
and rename my library to something else, I can't run my app anymore because the app can't find its dependency.
Correct.
If I build the app using QT creator, there's no ".so" file in the build directory, and it runs fine.
Then it finds it somewhere else, perhaps in your project or whatever. There is
LD_LIBRARY_PATHenvironment variable, that might be relevant.Does QT embed ".so" files in the executable?
No. And Qt does not "do anything" anyway. Creator is just building using
makeetc., anything to do with that is external to Qt.
13/16