Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. Installation and Deployment
  4. Build non-QT C++ static library using QT
QtWS25 Last Chance

Build non-QT C++ static library using QT

Scheduled Pinned Locked Moved Unsolved Installation and Deployment
static librarydeployiosandroid
11 Posts 3 Posters 7.9k 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
    julianoes
    wrote on 25 Aug 2016, 20:45 last edited by
    #1

    Hi,

    I've been trying to create a C++ library using QT. Optimally, the library should be deployed as a static library (one .a file) without any dependencies.

    The reason to use QT is to make use of the platform independent implementations of QUdpSocket, QThread, QMutex, QEventLoop for iOS, Android, Linux, Mac, Windows.

    It should be possible to use the library as a plain C++ library in iOS and Android without having to worry about QT dependencies.

    What have I tried until now:

    • Compiled QT5.7 as static
    • Compile the library as staticlib using qmake from the static build. This creates mylib.a.
    • Try to make a separate non-QT application which links to mylib.a, this fails because there are numerous undefined references to QT symbols.

    One way to fix this is to link the C++ app to libQt5Core.a, libQt5Network.a as well as mylib.a, however I would prefer not having this additional dependency.

    Another way to fix it is to copy libQt5Core.a and libQt5Network.a into the build folder of the library and do the following after building:

    ar -x libQt5Core.a
    ar -x libQt5Network.a
    ar cg mylib.a *.o
    

    This creates a huge (over 200MB) library and includes a lot more than needed. Once you link an application to it, the filesize reduces to around 50MB, however, the linking to it still requires a lot of dependencies on Linux such as:

    pthread
    z
    icuio
    icuuc
    icutu
    icule
    iculx
    icudata
    icutest
    icui18n
    dl
    glib-2.0
    pcre16
    proxy
    

    This makes deployment on other platforms very hard again.

    I've been wondering and reading if it was possible to either:

    1. Use linking to get Core/Network into mylib but only the needed symbols.
    2. Or stripping the file containing mylib, Core, Network to just the mylib functions and it's dependencies.

    From what I've found that's not easily possible, but I keep hoping that somebody must have had (and solved) this problem before.

    Thanks in advance for any pointers or ideas.
    Julian

    R 1 Reply Last reply 26 Aug 2016, 13:47
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 25 Aug 2016, 21:29 last edited by
      #2

      Hi and welcome to devnet,

      Are you sure you linked your library to your custom static build of Qt ?

      In any case, if you don't want any dependencies, then you have to get the static version of all of them.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      1 Reply Last reply
      0
      • J Offline
        J Offline
        julianoes
        wrote on 26 Aug 2016, 05:03 last edited by
        #3

        So, I'm definitely using qmake from the static build, so that should pull in the static libraries. However, building a static library does not involve linking but only an 'ar' at the end which does not include core and network.

        1 Reply Last reply
        0
        • J Offline
          J Offline
          julianoes
          wrote on 26 Aug 2016, 13:34 last edited by
          #4

          Thanks @SGaist for your response.
          I'll add a minimal example to make this more concrete. I basically created a C++ static library in QtCreator:

          TestLib.pro:

          QT       -= gui
          QT       += network
          
          TARGET = TestLib
          TEMPLATE = lib
          CONFIG += staticlib
          
          SOURCES += testlib.cpp
          
          HEADERS += testlib.h
          unix {
              target.path = /usr/lib
              INSTALLS += target
          }
          

          testlib.h:

          #ifndef TESTLIB_H
          #define TESTLIB_H
          
          class TestLib
          {
          
          public:
              TestLib();
          };
          
          #endif // TESTLIB_H
          

          testlib.cpp:

          #include "testlib.h"
          #include <QUdpSocket>
          
          TestLib::TestLib()
          {
              QUdpSocket *socket = new QUdpSocket();
              (void)socket;
          }
          

          Compile output (using the Kit which is qt5.7 statically compiled):

          15:29:30: Starting: "/usr/bin/make" 
          g++ -c -pipe -O2 -fPIC -std=gnu++11 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_NETWORK_LIB -DQT_CORE_LIB -I../TestLib -I. -I../qt5/qtbase/include -I../qt5/qtbase/include/QtNetwork -I../qt5/qtbase/include/QtCore -I. -I../qt5/qtbase/mkspecs/linux-g++ -o testlib.o ../TestLib/testlib.cpp
          rm -f libTestLib.a
          ar cqs libTestLib.a testlib.o
          15:29:31: The process "/usr/bin/make" exited normally.
          

          And the result library:

          nm libTestLib.a | c++filt
          
          testlib.o:
          0000000000000000 V DW.ref.__gxx_personality_v0
                           U _GLOBAL_OFFSET_TABLE_
                           U __gxx_personality_v0
                           U qt_version_tag
                           U _Unwind_Resume
                           U operator delete(void*)
                           U QUdpSocket::QUdpSocket(QObject*)
          0000000000000000 T TestLib::TestLib()
          0000000000000000 T TestLib::TestLib()
                           U operator new(unsigned long)
          

          You can see that the QT symbols are undefined, and not pulled in. Is this how it's supposed to be? How should this static library be deployed without the developer having to worry about QT dependencies?

          1 Reply Last reply
          0
          • J julianoes
            25 Aug 2016, 20:45

            Hi,

            I've been trying to create a C++ library using QT. Optimally, the library should be deployed as a static library (one .a file) without any dependencies.

            The reason to use QT is to make use of the platform independent implementations of QUdpSocket, QThread, QMutex, QEventLoop for iOS, Android, Linux, Mac, Windows.

            It should be possible to use the library as a plain C++ library in iOS and Android without having to worry about QT dependencies.

            What have I tried until now:

            • Compiled QT5.7 as static
            • Compile the library as staticlib using qmake from the static build. This creates mylib.a.
            • Try to make a separate non-QT application which links to mylib.a, this fails because there are numerous undefined references to QT symbols.

            One way to fix this is to link the C++ app to libQt5Core.a, libQt5Network.a as well as mylib.a, however I would prefer not having this additional dependency.

            Another way to fix it is to copy libQt5Core.a and libQt5Network.a into the build folder of the library and do the following after building:

            ar -x libQt5Core.a
            ar -x libQt5Network.a
            ar cg mylib.a *.o
            

            This creates a huge (over 200MB) library and includes a lot more than needed. Once you link an application to it, the filesize reduces to around 50MB, however, the linking to it still requires a lot of dependencies on Linux such as:

            pthread
            z
            icuio
            icuuc
            icutu
            icule
            iculx
            icudata
            icutest
            icui18n
            dl
            glib-2.0
            pcre16
            proxy
            

            This makes deployment on other platforms very hard again.

            I've been wondering and reading if it was possible to either:

            1. Use linking to get Core/Network into mylib but only the needed symbols.
            2. Or stripping the file containing mylib, Core, Network to just the mylib functions and it's dependencies.

            From what I've found that's not easily possible, but I keep hoping that somebody must have had (and solved) this problem before.

            Thanks in advance for any pointers or ideas.
            Julian

            R Offline
            R Offline
            raven-worx
            Moderators
            wrote on 26 Aug 2016, 13:47 last edited by raven-worx
            #5

            @julianoes said in Build non-QT C++ static library using QT:

            • Try to make a separate non-QT application which links to mylib.a, this fails because there are numerous undefined references to QT symbols.

            because the static lib only contains your symbols. The target binary has to be linked against It's dependencies.

            This creates a huge (over 200MB) library and includes a lot more than needed. Once you link an application to it, the filesize reduces to around 50MB,

            but this what you actually want. It contains all the infos needed. And as you already noticed the size reduces dramatically when linked into the final binary.

            however, the linking to it still requires a lot of dependencies on Linux such as:

            pthread
            z
            icuio
            icuuc
            icutu
            icule
            iculx
            icudata
            icutest
            icui18n
            dl
            glib-2.0
            pcre16
            proxy
            

            again just because Qt itself is compiled statically it doesn't mean it has no dependencies. You would need to link against those also statically and "combine" them again.

            Actually this is all normal "behavior" of static libs. If you want an all-in-solution you would have to go with one big static lib. But i doubt that it will be possible and able to use it successfully with all Qt dependencies included statically.
            There are some Qt macros available to disable unneeded features though to reduce the file size though.

            Also note that some Qt stuff requires an event loop running!

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            J 1 Reply Last reply 26 Aug 2016, 14:03
            1
            • R raven-worx
              26 Aug 2016, 13:47

              @julianoes said in Build non-QT C++ static library using QT:

              • Try to make a separate non-QT application which links to mylib.a, this fails because there are numerous undefined references to QT symbols.

              because the static lib only contains your symbols. The target binary has to be linked against It's dependencies.

              This creates a huge (over 200MB) library and includes a lot more than needed. Once you link an application to it, the filesize reduces to around 50MB,

              but this what you actually want. It contains all the infos needed. And as you already noticed the size reduces dramatically when linked into the final binary.

              however, the linking to it still requires a lot of dependencies on Linux such as:

              pthread
              z
              icuio
              icuuc
              icutu
              icule
              iculx
              icudata
              icutest
              icui18n
              dl
              glib-2.0
              pcre16
              proxy
              

              again just because Qt itself is compiled statically it doesn't mean it has no dependencies. You would need to link against those also statically and "combine" them again.

              Actually this is all normal "behavior" of static libs. If you want an all-in-solution you would have to go with one big static lib. But i doubt that it will be possible and able to use it successfully with all Qt dependencies included statically.
              There are some Qt macros available to disable unneeded features though to reduce the file size though.

              Also note that some Qt stuff requires an event loop running!

              J Offline
              J Offline
              julianoes
              wrote on 26 Aug 2016, 14:03 last edited by
              #6

              Thanks @raven-worx.

              @raven-worx said in Build non-QT C++ static library using QT:

              again just because Qt itself is compiled statically it doesn't mean it has no dependencies.

              Right I understand that but I really don't want that users of my library need to worry about all dependencies like pcre16 or proxy that I doubt are needed for the functions that I use.

              @raven-worx said in Build non-QT C++ static library using QT:

              There are some Qt macros available to disable unneeded features though to reduce the file size though.

              Can you give me a pointer to these? What am I looking for?

              @raven-worx said in Build non-QT C++ static library using QT:

              Also note that some Qt stuff requires an event loop running!

              My library starts a QThread and uses exec in there which seems to work for the things I'm trying to do.

              1 Reply Last reply
              0
              • S Offline
                S Offline
                SGaist
                Lifetime Qt Champion
                wrote on 26 Aug 2016, 20:51 last edited by
                #7

                Then I suggested before, you'll have to get all dependencies of Qt also statically linked.

                But before looking to do that, what exactly do you need for your application ?

                You're looking for the Qt Lite project. More information here. Note that you can already build a feature reduced version of Qt but the Qt Lite project offers an easier alternative to do it.

                Interested in AI ? www.idiap.ch
                Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                J 1 Reply Last reply 26 Aug 2016, 21:03
                0
                • S SGaist
                  26 Aug 2016, 20:51

                  Then I suggested before, you'll have to get all dependencies of Qt also statically linked.

                  But before looking to do that, what exactly do you need for your application ?

                  You're looking for the Qt Lite project. More information here. Note that you can already build a feature reduced version of Qt but the Qt Lite project offers an easier alternative to do it.

                  J Offline
                  J Offline
                  julianoes
                  wrote on 26 Aug 2016, 21:03 last edited by
                  #8

                  @SGaist said in Build non-QT C++ static library using QT:

                  Then I suggested before, you'll have to get all dependencies of Qt also statically linked.

                  I don't understand how I would do that. There is no linking happing if you look at my minimal example.

                  @SGaist said in Build non-QT C++ static library using QT:

                  But before looking to do that, what exactly do you need for your application ?

                  I only really need: QUdpSocket, QThread, QMutex, QEventLoop (and in the future serial support and QTcpSocket).

                  Thanks for the link to Qt Lite. I have heard of this before and it's definitely exciting. Does it make these static linking issues easier? Or does it just make things leaner with less baggage?

                  1 Reply Last reply
                  0
                  • S Offline
                    S Offline
                    SGaist
                    Lifetime Qt Champion
                    wrote on 28 Aug 2016, 12:59 last edited by
                    #9

                    It will limit the number of Qt dependencies.

                    AFAIK, when you link to a static library, you should only get the symbols you are currently using pulled in your application/library. You shouldn't have to pack everything as you do now.

                    Interested in AI ? www.idiap.ch
                    Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                    J 1 Reply Last reply 28 Aug 2016, 13:06
                    0
                    • S SGaist
                      28 Aug 2016, 12:59

                      It will limit the number of Qt dependencies.

                      AFAIK, when you link to a static library, you should only get the symbols you are currently using pulled in your application/library. You shouldn't have to pack everything as you do now.

                      J Offline
                      J Offline
                      julianoes
                      wrote on 28 Aug 2016, 13:06 last edited by
                      #10

                      @SGaist said in Build non-QT C++ static library using QT:

                      AFAIK, when you link to a static library, you should only get the symbols you are currently using pulled in your application/library. You shouldn't have to pack everything as you do now.

                      I think they get pulled in an application but it seems not into a library. There is no linking taking place as far as I can tell. It's just an ar call that merges the objects but without core and network.
                      Presumably, the linking itself happens later when you use the library for an application.

                      If anyone knows an easy way like a script or tool to determine which .o files that I need from Qt5Core.a to resolve all dependencies, that would be great.

                      1 Reply Last reply
                      0
                      • S Offline
                        S Offline
                        SGaist
                        Lifetime Qt Champion
                        wrote on 28 Aug 2016, 15:11 last edited by
                        #11

                        Then there might be something I'm missing about your current setup.

                        In any case, take a look at this excellent blog article about that subject. That should give you the clues needed to solve your situation.

                        Interested in AI ? www.idiap.ch
                        Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                        1 Reply Last reply
                        0

                        1/11

                        25 Aug 2016, 20:45

                        • Login

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