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. Linking internal libraries

Linking internal libraries

Scheduled Pinned Locked Moved Unsolved General and Desktop
24 Posts 6 Posters 7.0k 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.
  • P Offline
    P Offline
    Paul Thexton
    wrote on 3 Dec 2017, 22:22 last edited by
    #1

    Thanks @vivaladav & @aha_1980 - I'll definitely go down that route.

    As an aside I have a different issue at the moment whereby suddenly the compiled binary of one of my Qt Unit Tests isn't linked properly to my .so which I'm attempting to unit test. The structure is similar to this (If this is not an appropriate thread for this question, please let me know and I'll find the relevant forum here to post a new thread in!)

    Top Level (template = subdirs)
    --> LibOne (template = lib)
    --> LibTwo (template == lib)
    --> UnitTests (template = subdirs)
    --.--> LibOneTests (template = app, config += testcase)
    --.--> LibTwoTests (template = app, config += testcase)

    The tests projects link against the output from the relevant lib by specifying -L$$absolute_path(../../Lib[One|Two]) and also specify -Wl,-rpath,$$absolute_path(x)

    Unfortunately the Qt internals also specify the rpath to the Qt libs which I think means my rpath definition is invalid.

    I either need to be able to compile the binary with multiple rpaths (which googling around many claim should work, but it doesn't seem to for me) or specify that the generated platform_wrapper.sh to add an extra folder to LD_LIBRARY_PATH

    Unfortunately I can't figure out the best way around either :( I'm not really keen on setting up my project to copy around the generated .so files in to the folder where the test binaries live, that seems a bit of a cheat!

    A V 2 Replies Last reply 4 Dec 2017, 07:13
    0
    • P Paul Thexton
      3 Dec 2017, 22:22

      Thanks @vivaladav & @aha_1980 - I'll definitely go down that route.

      As an aside I have a different issue at the moment whereby suddenly the compiled binary of one of my Qt Unit Tests isn't linked properly to my .so which I'm attempting to unit test. The structure is similar to this (If this is not an appropriate thread for this question, please let me know and I'll find the relevant forum here to post a new thread in!)

      Top Level (template = subdirs)
      --> LibOne (template = lib)
      --> LibTwo (template == lib)
      --> UnitTests (template = subdirs)
      --.--> LibOneTests (template = app, config += testcase)
      --.--> LibTwoTests (template = app, config += testcase)

      The tests projects link against the output from the relevant lib by specifying -L$$absolute_path(../../Lib[One|Two]) and also specify -Wl,-rpath,$$absolute_path(x)

      Unfortunately the Qt internals also specify the rpath to the Qt libs which I think means my rpath definition is invalid.

      I either need to be able to compile the binary with multiple rpaths (which googling around many claim should work, but it doesn't seem to for me) or specify that the generated platform_wrapper.sh to add an extra folder to LD_LIBRARY_PATH

      Unfortunately I can't figure out the best way around either :( I'm not really keen on setting up my project to copy around the generated .so files in to the folder where the test binaries live, that seems a bit of a cheat!

      A Offline
      A Offline
      aha_1980
      Lifetime Qt Champion
      wrote on 4 Dec 2017, 07:13 last edited by
      #2

      @Paul-Thexton Yes, this discussion should better be in a separate thread.

      @Moderators: Can you move this please?

      Regarding your question: If I get it correctly, you want your tests to find the libraries at runtime, right? If you run from QtCreator, everything should already be fine as it sets up a run environment based on your project structure. If you want to run outside of Creator, I'd just recommend a shell script setting up the paths for you.

      But maybe someone else has a better solution.

      Qt has to stay free or it will die.

      1 Reply Last reply
      0
      • P Offline
        P Offline
        Paul Thexton
        wrote on 4 Dec 2017, 09:52 last edited by
        #3

        Thank you @aha_1980

        Yes I want the tests to find the libraries at runtime. On the macOS platform this is simple to achieve as I can use the install_name_tool to change where the linked library should be found, but on Linux I need to use either rpath or LD_LIBRARY_PATH

        The reason for this is that I want to be able to build the projects on a build server and have it execute "make check" (with relevant additional logging arguments supplied) as a build step.

        The test project described is just a sample I put together to test the layout I want to use in a real project.

        1 Reply Last reply
        0
        • V Offline
          V Offline
          VRonin
          wrote on 4 Dec 2017, 10:08 last edited by
          #4

          in Top Level, UnitTests should require LibOne and LibTwo. does it?
          Could you post "TopLevel.pro"?

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          1 Reply Last reply
          0
          • P Offline
            P Offline
            Paul Thexton
            wrote on 4 Dec 2017, 10:50 last edited by
            #5

            Top level .pro file is very simple

            TEMPLATE = subdirs
            
            CONFIG += ordered
            
            SUBDIRS += LibOne \
                LibTwo \
                UnitTests
            
            UnitTests.depends = LibOne LibTwo
            
            A 1 Reply Last reply 4 Dec 2017, 12:58
            1
            • V Offline
              V Offline
              VRonin
              wrote on 4 Dec 2017, 12:01 last edited by
              #6

              Last question, what is DESTDIR of each of those projects?

              "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
              ~Napoleon Bonaparte

              On a crusade to banish setIndexWidget() from the holy land of Qt

              P 1 Reply Last reply 4 Dec 2017, 13:14
              0
              • P Paul Thexton
                4 Dec 2017, 10:50

                Top level .pro file is very simple

                TEMPLATE = subdirs
                
                CONFIG += ordered
                
                SUBDIRS += LibOne \
                    LibTwo \
                    UnitTests
                
                UnitTests.depends = LibOne LibTwo
                
                A Offline
                A Offline
                aha_1980
                Lifetime Qt Champion
                wrote on 4 Dec 2017, 12:58 last edited by
                #7

                @Paul-Thexton

                Why do you use CONFIG += ordered? You already specify the dependencies.

                Please see here why this is not recommended: https://blog.rburchell.com/2013/10/every-time-you-configordered-kitten-dies.html

                Qt has to stay free or it will die.

                1 Reply Last reply
                2
                • V VRonin
                  4 Dec 2017, 12:01

                  Last question, what is DESTDIR of each of those projects?

                  P Offline
                  P Offline
                  Paul Thexton
                  wrote on 4 Dec 2017, 13:14 last edited by
                  #8

                  @VRonin I haven't specified a DESTDIR for this sample project, the outputs are generated in to the current project folder.

                  @aha_1980 I think it was supplied by the template when I created the project, you're right that it's superfluous :)

                  1 Reply Last reply
                  0
                  • P Paul Thexton
                    3 Dec 2017, 22:22

                    Thanks @vivaladav & @aha_1980 - I'll definitely go down that route.

                    As an aside I have a different issue at the moment whereby suddenly the compiled binary of one of my Qt Unit Tests isn't linked properly to my .so which I'm attempting to unit test. The structure is similar to this (If this is not an appropriate thread for this question, please let me know and I'll find the relevant forum here to post a new thread in!)

                    Top Level (template = subdirs)
                    --> LibOne (template = lib)
                    --> LibTwo (template == lib)
                    --> UnitTests (template = subdirs)
                    --.--> LibOneTests (template = app, config += testcase)
                    --.--> LibTwoTests (template = app, config += testcase)

                    The tests projects link against the output from the relevant lib by specifying -L$$absolute_path(../../Lib[One|Two]) and also specify -Wl,-rpath,$$absolute_path(x)

                    Unfortunately the Qt internals also specify the rpath to the Qt libs which I think means my rpath definition is invalid.

                    I either need to be able to compile the binary with multiple rpaths (which googling around many claim should work, but it doesn't seem to for me) or specify that the generated platform_wrapper.sh to add an extra folder to LD_LIBRARY_PATH

                    Unfortunately I can't figure out the best way around either :( I'm not really keen on setting up my project to copy around the generated .so files in to the folder where the test binaries live, that seems a bit of a cheat!

                    V Offline
                    V Offline
                    vivaladav
                    wrote on 5 Dec 2017, 01:25 last edited by vivaladav 12 Jun 2017, 00:15
                    #9

                    @Paul-Thexton no need to play around with rpath.

                    I created an example project that does what you are trying to do:

                    |TestingLib (TEMPLATE = subdirs)
                    |-->SimpleMath (TEMPLATE = lib)
                    |--> UnitTest (TEMPLATE = app)

                    This is the UnitTest .pro

                    QT += testlib
                    QT -= gui
                    
                    CONFIG += qt console warn_on depend_includepath testcase
                    CONFIG -= app_bundle
                    
                    TEMPLATE = app
                    
                    SOURCES += \
                        TestSimpleMath.cpp
                    
                    HEADERS += \
                        TestSimpleMath.h
                    
                    DEPENDPATH += \
                        ../SimpleMath
                    
                    INCLUDEPATH += \
                        ../SimpleMath
                    
                    CONFIG(release, debug|release) {
                        LIBS += -L../SimpleMath -lSimpleMath
                    
                        !build_pass:message(Release build!)
                        !build_pass:message($$LIBS)
                    }
                    
                    CONFIG(debug, debug|release) {
                            LIBS += -L../SimpleMath -lSimpleMath
                    
                            !build_pass:message(Debug build!)
                            !build_pass:message($$LIBS)
                        }
                    }
                    

                    The idea is to use LIBS to point to where the shared lib is.

                    Davide Coppola
                    blog | Linkedin | Twitter

                    1 Reply Last reply
                    2
                    • P Offline
                      P Offline
                      Paul Thexton
                      wrote on 5 Dec 2017, 11:12 last edited by
                      #10

                      Hi,

                      Thanks for your input on this.

                      That's pretty close to what I have in my unit test pro file, certainly the end result of adding "-L{path} -l{lib}" to LIBS is what I am already doing.

                      I've created the same structure you just described, and I still get the same issue. When attempting to run the successfully compiled and linked unit test from a console, it cannot find libSimpleMath.so

                      When running the unit tests directly from QtCreator these work, printing out the value of $LD_LIBRARY_PATH to stderr from the slot shows that QtCreator determined it needed to add $$absolute_path(../SimpleMath) to LD_LIBRARY_PATH before executing the test, but the produced target_wrapper.sh file only contains

                      LD_LIBRARY_PATH=/usr/local/digia/Qt5.8.0/5.8/gcc_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
                      export LD_LIBRARY_PATH
                      

                      What I am trying to achieve is to gather the results of unit tests when run on a headless build server when I have executed

                      make check TESTARGS="-o result.xml,xml"
                      

                      Running make check on a terminal fails because LD_LIBRARY_PATH is not correctly set at any location.

                      I have put a zip of the project structure matching what you created in your example on filebin

                      A V 2 Replies Last reply 5 Dec 2017, 13:17
                      0
                      • P Paul Thexton
                        5 Dec 2017, 11:12

                        Hi,

                        Thanks for your input on this.

                        That's pretty close to what I have in my unit test pro file, certainly the end result of adding "-L{path} -l{lib}" to LIBS is what I am already doing.

                        I've created the same structure you just described, and I still get the same issue. When attempting to run the successfully compiled and linked unit test from a console, it cannot find libSimpleMath.so

                        When running the unit tests directly from QtCreator these work, printing out the value of $LD_LIBRARY_PATH to stderr from the slot shows that QtCreator determined it needed to add $$absolute_path(../SimpleMath) to LD_LIBRARY_PATH before executing the test, but the produced target_wrapper.sh file only contains

                        LD_LIBRARY_PATH=/usr/local/digia/Qt5.8.0/5.8/gcc_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
                        export LD_LIBRARY_PATH
                        

                        What I am trying to achieve is to gather the results of unit tests when run on a headless build server when I have executed

                        make check TESTARGS="-o result.xml,xml"
                        

                        Running make check on a terminal fails because LD_LIBRARY_PATH is not correctly set at any location.

                        I have put a zip of the project structure matching what you created in your example on filebin

                        A Offline
                        A Offline
                        aha_1980
                        Lifetime Qt Champion
                        wrote on 5 Dec 2017, 13:17 last edited by
                        #11

                        @Paul-Thexton said in Linking internal libraries:

                        When running the unit tests directly from QtCreator these work, printing out the value of $LD_LIBRARY_PATH to stderr from the slot shows that QtCreator determined it needed to add $$absolute_path(../SimpleMath) to LD_LIBRARY_PATH before executing the test

                        Yes, that's correct. Creator parses the LIBS += -L lines and adds everything after -L to LD_LIBRARY_PATH.

                        I'm not sure where target_wrapper.sh comes from. Is that created by qmake?

                        Anyhow, if your structure is somewhat statically, I'd just create my own script to setup the environment as needed.

                        Qt has to stay free or it will die.

                        1 Reply Last reply
                        0
                        • P Offline
                          P Offline
                          Paul Thexton
                          wrote on 5 Dec 2017, 13:46 last edited by
                          #12

                          target_wrapper.sh is created by qmake yes. There are various "solutions" to this problem around on stackoverflow and so on where people have the exact same problem, but none of the solutions provided actually work (probably due to the internals of the Qt mkspecs changing over the years that breaks those workarounds).

                          I've got a way of making it work which I'd prefer not to do (it's one more thing to maintain in a codebase which potentially could get very large over time), but really it feels like there's something missing in qmake as the target_wrapper.sh already accommodates the change required to point to the Qt libs, it feels like it should also have been pointing at any other dependency locations.

                          A 1 Reply Last reply 5 Dec 2017, 14:20
                          0
                          • P Paul Thexton
                            5 Dec 2017, 13:46

                            target_wrapper.sh is created by qmake yes. There are various "solutions" to this problem around on stackoverflow and so on where people have the exact same problem, but none of the solutions provided actually work (probably due to the internals of the Qt mkspecs changing over the years that breaks those workarounds).

                            I've got a way of making it work which I'd prefer not to do (it's one more thing to maintain in a codebase which potentially could get very large over time), but really it feels like there's something missing in qmake as the target_wrapper.sh already accommodates the change required to point to the Qt libs, it feels like it should also have been pointing at any other dependency locations.

                            A Offline
                            A Offline
                            aha_1980
                            Lifetime Qt Champion
                            wrote on 5 Dec 2017, 14:20 last edited by
                            #13

                            @Paul-Thexton: Well, you can search on bugreports.qt.io if there is already a report for this, if not you can create your own report.

                            But if you really want to have this function, you should modify qmake yourself and submit your patch to Gerrit. If that's worth the work, you have to decide yourself.

                            Qt has to stay free or it will die.

                            1 Reply Last reply
                            1
                            • P Paul Thexton
                              5 Dec 2017, 11:12

                              Hi,

                              Thanks for your input on this.

                              That's pretty close to what I have in my unit test pro file, certainly the end result of adding "-L{path} -l{lib}" to LIBS is what I am already doing.

                              I've created the same structure you just described, and I still get the same issue. When attempting to run the successfully compiled and linked unit test from a console, it cannot find libSimpleMath.so

                              When running the unit tests directly from QtCreator these work, printing out the value of $LD_LIBRARY_PATH to stderr from the slot shows that QtCreator determined it needed to add $$absolute_path(../SimpleMath) to LD_LIBRARY_PATH before executing the test, but the produced target_wrapper.sh file only contains

                              LD_LIBRARY_PATH=/usr/local/digia/Qt5.8.0/5.8/gcc_64/lib${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}
                              export LD_LIBRARY_PATH
                              

                              What I am trying to achieve is to gather the results of unit tests when run on a headless build server when I have executed

                              make check TESTARGS="-o result.xml,xml"
                              

                              Running make check on a terminal fails because LD_LIBRARY_PATH is not correctly set at any location.

                              I have put a zip of the project structure matching what you created in your example on filebin

                              V Offline
                              V Offline
                              vivaladav
                              wrote on 6 Dec 2017, 10:20 last edited by
                              #14

                              @Paul-Thexton sorry, when I wrote you last time it was pretty late and I missed testing the executable from the command line.

                              You are right, it does't work and target_wrapper.sh is completely useless.

                              I will look into this as I need to sort it out too, but let us know if you manage to find a proper solution :)

                              Davide Coppola
                              blog | Linkedin | Twitter

                              P 1 Reply Last reply 6 Dec 2017, 11:50
                              0
                              • V vivaladav
                                6 Dec 2017, 10:20

                                @Paul-Thexton sorry, when I wrote you last time it was pretty late and I missed testing the executable from the command line.

                                You are right, it does't work and target_wrapper.sh is completely useless.

                                I will look into this as I need to sort it out too, but let us know if you manage to find a proper solution :)

                                P Offline
                                P Offline
                                Paul Thexton
                                wrote on 6 Dec 2017, 11:50 last edited by
                                #15

                                Thanks @vivaladav - the way I've worked around this for the time being (on Linux platform) is to explicitly build a LD_LIBRARY_PATH environment to force in to the make system.

                                Obviously this is dependent on the following

                                • All folders required for inclusion are at the same level
                                • There are no name clashes with libraries (there never should be of course, but it's not impossible with poorly structured projects)

                                If anybody finds this post who has similar problems, this is what I do to force LD_LIBRARY_PATH to contain all folders at the project top level so that "make check" works.

                                export LD_LIBRARY_PATH=`find . -mindepth 1 -maxdepth 1 \! -name ".*" -type d | xargs realpath | awk '{if(NR != 1){printf ":"}printf "%s", $0} END{print ""}'`
                                export TESTARGS="-o TEST.xml,xml"
                                make check
                                
                                V 1 Reply Last reply 6 Dec 2017, 12:03
                                2
                                • P Paul Thexton
                                  6 Dec 2017, 11:50

                                  Thanks @vivaladav - the way I've worked around this for the time being (on Linux platform) is to explicitly build a LD_LIBRARY_PATH environment to force in to the make system.

                                  Obviously this is dependent on the following

                                  • All folders required for inclusion are at the same level
                                  • There are no name clashes with libraries (there never should be of course, but it's not impossible with poorly structured projects)

                                  If anybody finds this post who has similar problems, this is what I do to force LD_LIBRARY_PATH to contain all folders at the project top level so that "make check" works.

                                  export LD_LIBRARY_PATH=`find . -mindepth 1 -maxdepth 1 \! -name ".*" -type d | xargs realpath | awk '{if(NR != 1){printf ":"}printf "%s", $0} END{print ""}'`
                                  export TESTARGS="-o TEST.xml,xml"
                                  make check
                                  
                                  V Offline
                                  V Offline
                                  vivaladav
                                  wrote on 6 Dec 2017, 12:03 last edited by
                                  #16

                                  @Paul-Thexton nice one, even if I would recommend you to fill a bug report as things should be handled better by qmake.

                                  An alternative and simpler solution would be to build and link the library as static. I appreciate this might not be always what wanted, but it can be ok in many cases.

                                  Davide Coppola
                                  blog | Linkedin | Twitter

                                  1 Reply Last reply
                                  1
                                  • V Offline
                                    V Offline
                                    vivaladav
                                    wrote on 19 Dec 2017, 01:04 last edited by
                                    #17

                                    hey @Paul-Thexton, I just noticed that Qt Creator 4.5 is not creating target_wrapper.sh any more. Can you confirm this?

                                    Davide Coppola
                                    blog | Linkedin | Twitter

                                    P 1 Reply Last reply 21 Dec 2017, 13:18
                                    0
                                    • V vivaladav
                                      19 Dec 2017, 01:04

                                      hey @Paul-Thexton, I just noticed that Qt Creator 4.5 is not creating target_wrapper.sh any more. Can you confirm this?

                                      P Offline
                                      P Offline
                                      Paul Thexton
                                      wrote on 21 Dec 2017, 13:18 last edited by
                                      #18

                                      @vivaladav I've just tried with Creator 4.5 and the file is still created, however I've installed it as a standalone and still using the Qt5.8.0 Kit

                                      I will download Qt5.10.0 later and confirm what happens, and whether my solution above is still valid - I suspect it'll be something in qmake for 5.10 that has changed.

                                      V 1 Reply Last reply 2 Jan 2018, 12:43
                                      0
                                      • K Offline
                                        K Offline
                                        karlheinzreichel
                                        wrote on 21 Dec 2017, 13:33 last edited by
                                        #19

                                        Did you set your rpath dependencies with QMAKE_LFLAGS ?

                                        e.g.

                                        QMAKE_LFLAGS += '-Wl,-rpath,\'\$$ORIGIN/libs\''
                                        QMAKE_LFLAGS += '-Wl,-rpath,\'$${QMAKE_LIBDIR_QT}\''
                                        
                                        P 1 Reply Last reply 21 Dec 2017, 14:49
                                        0
                                        • K karlheinzreichel
                                          21 Dec 2017, 13:33

                                          Did you set your rpath dependencies with QMAKE_LFLAGS ?

                                          e.g.

                                          QMAKE_LFLAGS += '-Wl,-rpath,\'\$$ORIGIN/libs\''
                                          QMAKE_LFLAGS += '-Wl,-rpath,\'$${QMAKE_LIBDIR_QT}\''
                                          
                                          P Offline
                                          P Offline
                                          Paul Thexton
                                          wrote on 21 Dec 2017, 14:49 last edited by
                                          #20

                                          @karlheinzreichel yes. The problem is that qmake internally also sets the rpath for the location of the Qt libs (which can be seen in the compile output) and compilers don't seem to like two rpaths being set, I don't know the internals of linux Elf format well enough to say for certain, but it could well be that only one rpath is supported.

                                          1 Reply Last reply
                                          0

                                          • Login

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