Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. Undefined reference in app which includes library
QtWS25 Last Chance

Undefined reference in app which includes library

Scheduled Pinned Locked Moved Solved General and Desktop
16 Posts 4 Posters 2.1k Views
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • J Offline
    J Offline
    Josef Lintz
    wrote on 18 Jul 2022, 10:25 last edited by
    #1

    As the title suggests, I'm dealing with a odd issue, where I have a library which includes OpenSSL, and an app which uses the library. The library builds without problems.

    The problem comes when I include the library in my application, I get an undefined reference error in my app whenever I use any OpenSSL functions in my library.

    This is my library's ".pro" file

    # ...
    # Some lines were removed for brevity
    # ...
    
    # Default rules for deployment.
    unix {
        target.path = $$[QT_INSTALL_PLUGINS]/generic
    }
    !isEmpty(target.path): INSTALLS += target
    
    # Add OpenSSL lib
    LIBS += -lcrypto 
    

    This the ".pro" file for my app.

    # ...
    # Some lines were removed for brevity
    # ...
    
    # Default rules for deployment.
    qnx: target.path = /tmp/$${TARGET}/bin
    else: unix:!android: target.path = /opt/$${TARGET}/bin
    !isEmpty(target.path): INSTALLS += target
    
    unix:!macx: LIBS +=  [libs path]/Crypto/Build/Release/ -lCrypto
    
    INCLUDEPATH +=  [libs path]/Crypto/Build/Release
    DEPENDPATH +=  [libs path]/Crypto/Build/Release
    
    unix:!macx: PRE_TARGETDEPS += [libs path]/Crypto/Build/Release/libCrypto.a
    
    

    Couple of notes:
    Some of the errors say that it's missing the source file(?), and the object file(?) ,even though it's only a ".a" file, and a header.

    If I move the definition of one of the functions (Which use OpenSSL) to the declaration, the app still specifies that it's an undefined reference for the OpenSSL function.

    Removing the library include lines from the app's ".pro" file doesn't do anything.

    This only happens with functions that use OpenSSL (Or probably any non system libraries).

    I don't have much experience building libraries for Linux, so I might be missing something obvious. Any help is appreciated.

    1 Reply Last reply
    0
    • J Josef Lintz
      19 Jul 2022, 07:38

      Update, maybe?

      I've been trying to manually build the library with

      g++ -c Crypto.cpp -lcrypto -lssl
      ar r libCrypto.a Crypto.o
      

      This works, it creates a libCrypto.a file without problems.

      Next, I created a small test app with only a single main function, which uses the function vBact::Encrypt() from my library. To build it I'm using

      g++ main.cpp -L./ -lCrypto
      

      This 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 status
      

      Where am I going wrong?

      J Offline
      J Offline
      JonB
      wrote on 19 Jul 2022, 07:53 last edited by JonB
      #11

      @Josef-Lintz

      @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.a it contains the crypto/ssl you specified while building it. It does not!. The -lcrypto -lssl you specified tells it these are external libraries it can use. You must re-specify them whenever you link against your -lCrypto. (And the corresponding .so files must be findable at runtime.) Follow now?

      BTW, I find it incredibly confusing that you are building a libCrypto.a linking with a libcrypto.a (Linux case-sensitive distinguishes). Please name your library differently from the libraries it links against!

      J 1 Reply Last reply 19 Jul 2022, 08:00
      1
      • S Offline
        S Offline
        sierdzio
        Moderators
        wrote on 18 Jul 2022, 12:35 last edited by
        #2

        Your app probably needs to link to OpenSSL, too.

        (Z(:^

        1 Reply Last reply
        1
        • J Offline
          J Offline
          Josef Lintz
          wrote on 18 Jul 2022, 12:52 last edited by
          #3

          Why? Isn't the point of using libraries to not have to include multiples of the same library?
          Also, I tried that, it didn't work.
          However, here's the really weird part, if I call the same (OpenSSL) function the compiler is telling me is undefined, the app builds successfully. I genuinely have no idea what's happening

          1 Reply Last reply
          0
          • C Offline
            C Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on 18 Jul 2022, 14:55 last edited by
            #4

            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.

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            J 1 Reply Last reply 18 Jul 2022, 15:55
            0
            • C Christian Ehrlicher
              18 Jul 2022, 14:55

              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.

              J Offline
              J Offline
              Josef Lintz
              wrote on 18 Jul 2022, 15:55 last edited by
              #5

              @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
              1228e4dc-71bd-4ac8-a757-d22a877d4ba7-image.png

              vBact::Test(int) Is a function I have defined in my library, in its definition I call ERR_load_crypto_strings function 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.

              1 Reply Last reply
              0
              • C Offline
                C Offline
                Christian Ehrlicher
                Lifetime Qt Champion
                wrote on 18 Jul 2022, 16:47 last edited by
                #6

                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.

                Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                Visit the Qt Academy at https://academy.qt.io/catalog

                1 Reply Last reply
                1
                • J Offline
                  J Offline
                  Josef Lintz
                  wrote on 18 Jul 2022, 17:03 last edited by
                  #7

                  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 += -lcrypto 
                  

                  The problem is not ERR_load_crypto_strings itself, 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
                  33961c66-7c33-4139-a90b-bad90d3c4276-image.png

                  1 Reply Last reply
                  0
                  • C Offline
                    C Offline
                    Christian Ehrlicher
                    Lifetime Qt Champion
                    wrote on 18 Jul 2022, 17:37 last edited by
                    #8

                    ERR_get_error is in libssl.

                    Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                    Visit the Qt Academy at https://academy.qt.io/catalog

                    1 Reply Last reply
                    3
                    • J Offline
                      J Offline
                      Josef Lintz
                      wrote on 19 Jul 2022, 04:47 last edited by
                      #9

                      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?

                      1 Reply Last reply
                      0
                      • J Offline
                        J Offline
                        Josef Lintz
                        wrote on 19 Jul 2022, 07:38 last edited by
                        #10

                        Update, maybe?

                        I've been trying to manually build the library with

                        g++ -c Crypto.cpp -lcrypto -lssl
                        ar r libCrypto.a Crypto.o
                        

                        This works, it creates a libCrypto.a file without problems.

                        Next, I created a small test app with only a single main function, which uses the function vBact::Encrypt() from my library. To build it I'm using

                        g++ main.cpp -L./ -lCrypto
                        

                        This 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 status
                        

                        Where am I going wrong?

                        J 1 Reply Last reply 19 Jul 2022, 07:53
                        0
                        • J Josef Lintz
                          19 Jul 2022, 07:38

                          Update, maybe?

                          I've been trying to manually build the library with

                          g++ -c Crypto.cpp -lcrypto -lssl
                          ar r libCrypto.a Crypto.o
                          

                          This works, it creates a libCrypto.a file without problems.

                          Next, I created a small test app with only a single main function, which uses the function vBact::Encrypt() from my library. To build it I'm using

                          g++ main.cpp -L./ -lCrypto
                          

                          This 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 status
                          

                          Where am I going wrong?

                          J Offline
                          J Offline
                          JonB
                          wrote on 19 Jul 2022, 07:53 last edited by JonB
                          #11

                          @Josef-Lintz

                          @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.a it contains the crypto/ssl you specified while building it. It does not!. The -lcrypto -lssl you specified tells it these are external libraries it can use. You must re-specify them whenever you link against your -lCrypto. (And the corresponding .so files must be findable at runtime.) Follow now?

                          BTW, I find it incredibly confusing that you are building a libCrypto.a linking with a libcrypto.a (Linux case-sensitive distinguishes). Please name your library differently from the libraries it links against!

                          J 1 Reply Last reply 19 Jul 2022, 08:00
                          1
                          • J JonB
                            19 Jul 2022, 07:53

                            @Josef-Lintz

                            @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.a it contains the crypto/ssl you specified while building it. It does not!. The -lcrypto -lssl you specified tells it these are external libraries it can use. You must re-specify them whenever you link against your -lCrypto. (And the corresponding .so files must be findable at runtime.) Follow now?

                            BTW, I find it incredibly confusing that you are building a libCrypto.a linking with a libcrypto.a (Linux case-sensitive distinguishes). Please name your library differently from the libraries it links against!

                            J Offline
                            J Offline
                            Josef Lintz
                            wrote on 19 Jul 2022, 08:00 last edited by
                            #12

                            @JonB
                            I changed g++ main.cpp -L./ -lCrypto to

                            g++ main.cpp -L./-lMyCrypto -lssl -lcrypto
                            

                            And 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?

                            J 1 Reply Last reply 19 Jul 2022, 08:15
                            0
                            • J Josef Lintz
                              19 Jul 2022, 08:00

                              @JonB
                              I changed g++ main.cpp -L./ -lCrypto to

                              g++ main.cpp -L./-lMyCrypto -lssl -lcrypto
                              

                              And 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?

                              J Offline
                              J Offline
                              JonB
                              wrote on 19 Jul 2022, 08:15 last edited by JonB
                              #13

                              @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 ar commands include the other libraries too? Maybe there is an option to the ld linker where you tell it to mark the .a file being generated with references to the other libraries it will need?

                              You could use e.g. nm to examine the symbols etc. in each library file to understand what is there and how that differs between your cases.

                              J 1 Reply Last reply 19 Jul 2022, 08:43
                              0
                              • J JonB
                                19 Jul 2022, 08:15

                                @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 ar commands include the other libraries too? Maybe there is an option to the ld linker where you tell it to mark the .a file being generated with references to the other libraries it will need?

                                You could use e.g. nm to examine the symbols etc. in each library file to understand what is there and how that differs between your cases.

                                J Offline
                                J Offline
                                Josef Lintz
                                wrote on 19 Jul 2022, 08:43 last edited by
                                #14

                                @JonB Well, at least you pointed me in the right direction, thank you.

                                1 Reply Last reply
                                0
                                • J Offline
                                  J Offline
                                  Josef Lintz
                                  wrote on 19 Jul 2022, 09:44 last edited by
                                  #15

                                  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 -lcrypto
                                  

                                  But 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 build directory, and it runs fine.

                                  Does QT embed ".so" files in the executable?

                                  J 1 Reply Last reply 19 Jul 2022, 09:54
                                  1
                                  • J Josef Lintz
                                    19 Jul 2022, 09:44

                                    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 -lcrypto
                                    

                                    But 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 build directory, and it runs fine.

                                    Does QT embed ".so" files in the executable?

                                    J Offline
                                    J Offline
                                    JonB
                                    wrote on 19 Jul 2022, 09:54 last edited by JonB
                                    #16

                                    @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_PATH environment 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 make etc., anything to do with that is external to Qt.

                                    1 Reply Last reply
                                    1

                                    2/16

                                    18 Jul 2022, 12:35

                                    14 unread
                                    • Login

                                    • Login or register to search.
                                    2 out of 16
                                    • First post
                                      2/16
                                      Last post
                                    0
                                    • Categories
                                    • Recent
                                    • Tags
                                    • Popular
                                    • Users
                                    • Groups
                                    • Search
                                    • Get Qt Extensions
                                    • Unsolved