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. Howto use an external shared lib?
Forum Updated to NodeBB v4.3 + New Features

Howto use an external shared lib?

Scheduled Pinned Locked Moved Unsolved General and Desktop
8 Posts 3 Posters 426 Views 1 Watching
  • 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.
  • D Offline
    D Offline
    django.Reinhard
    wrote on 4 Sept 2021, 03:23 last edited by
    #1

    Hi,

    I actually have the problem, that I don't know how to add a shared library from an external project to my qt application.
    From the external project I have the shared library only. No static lib to link to.

    So adding -L<lib-location> and l<libname> does not work. Linker says, that it can't find "libname". Guess this works for static libs only.

    So I tried to add the shared library to the OBJECTS var, which seemed to work at first sight. But on full rebuild the shared lib was removed :(

    So I'm looking for the right way to add that shared lib.
    I digged into qmake manuals, but wasn't successful.
    I would like to do something similar than qt module configuration, where I finally only have to write something like CONFIG += extProject

    but it seems, as if I'm to stupid to understand qmake manual. I then searched for prf-files of qt - but what I found is so complicated - no chance to follow.

    So how can I get into that config stuff using small steps?

    1 Reply Last reply
    0
    • C Offline
      C Offline
      ChrisW67
      wrote on 4 Sept 2021, 07:33 last edited by
      #2

      You do it with qmake by adding the relevant linker switches to the LIBS variable in your PRO file:

      LIBS += -L<lib-location> -l<libname>
      e.g.
      LIBS += -L/usr/local/lib -lopencv
      

      Notice that the lib name is without the lib prefix on UNIX-like systems: this would be a common mistake.

      If that is not the issue then, in all likelihood your problem is not qmake but the absence of the pieces needed for the linker to do its work.

      I am assuming you are on a Windows platform. On this platform that there are two components to a dynamically loaded library: a run-time DLL file and matching import (link-time) library that documents the entry points to the run-time library for the linker. The exact naming of the components is dependent on compiler: MSVC .dll and .lib, MingW .dll and .a (I think).

      On a Linux platform the .so file fills both roles.

      1 Reply Last reply
      1
      • D Offline
        D Offline
        django.Reinhard
        wrote on 4 Sept 2021, 07:42 last edited by
        #3

        Thank you for your attention.

        I wasn't precise with my first post, but of cause, I added -L and -l options to the LIBS variable.

        So in my case it does not work.

        When I list the files from the provided path, the shared lib is there. But the linker shouts, that he could not find the given lib.

        C 1 Reply Last reply 5 Sept 2021, 00:16
        0
        • M Offline
          M Offline
          mchinand
          wrote on 4 Sept 2021, 21:36 last edited by
          #4

          Can you show your .pro project file and the error you are getting?

          1 Reply Last reply
          0
          • D django.Reinhard
            4 Sept 2021, 07:42

            Thank you for your attention.

            I wasn't precise with my first post, but of cause, I added -L and -l options to the LIBS variable.

            So in my case it does not work.

            When I list the files from the provided path, the shared lib is there. But the linker shouts, that he could not find the given lib.

            C Offline
            C Offline
            ChrisW67
            wrote on 5 Sept 2021, 00:16 last edited by
            #5

            @django-Reinhard The (compile-time) linker does not use the shared library on Windows. The linker uses the import library, which has the same extension as a static library but contains only enough information to ensure that the resulting binary can link the dynamic library at run time. Parties providing a binary DLL (e.g. a MSVC runtime) and expecting developers to use it will generally have to provide a matching import library (often in a related SDK). If you do not have the import library then you are in for some difficulty. In some cases, very dependent on the library, you can reverse engineer the import library.

            Please confirm you are on Windows and what libraries are involved.

            1 Reply Last reply
            0
            • D Offline
              D Offline
              django.Reinhard
              wrote on 5 Sept 2021, 03:31 last edited by
              #6

              @ChrisW67 said in Howto use an external shared lib?:

              Please confirm you are on Windows and what libraries are involved.

              No, I'm NOT at windows.

              I use linux, precisely debian 11 (bullseye).

              @mchinand said in Howto use an external shared lib?:

              Can you show your .pro project file and the error you are getting?

              my project

              error message:

              /usr/bin/ld: cannot find -lnml
              collect2: error: ld returned 1 exit status
              

              I added a link to the external project to my projects root, so the shared library is located at ./lc/lib/libnml.so
              Together with the statements from pro-file:

              LIBS += -Llc/lib -lnml
              

              this should be as recommended.

              @ChrisW67 said in Howto use an external shared lib?:

              You do it with qmake by adding the relevant linker switches to the LIBS variable in your PRO file:

              Looks like that's not working.
              AFAIK shared libs should be added to the OBJECTS list.

              If you look at the linker statement (some o-files removed):

              g++ -Wl,-rpath,/opt/qt5.15/5.15.2/gcc_64/lib
                  -Wl,-rpath-link,/opt/qt5.15/5.15.2/gcc_64/lib
               -o QtUi
               main.o
               ...
               moc_toolinfodockable.o
               -Wl,-rpath=$ORIGIN/libs
               -Llc/lib -lm -lnml
               /opt/qt5.15/5.15.2/gcc_64/lib/libQt5UiTools.a
               -L/home/qt/openssl-1.1.1g/lib
               /opt/qt5.15/5.15.2/gcc_64/lib/libQt5Widgets.so
               /opt/qt5.15/5.15.2/gcc_64/lib/libQt5Gui.so
               /opt/qt5.15/5.15.2/gcc_64/lib/libQt5Test.so
               /opt/qt5.15/5.15.2/gcc_64/lib/libQt5Core.so
               -lGL -lpthread
              
              

              you can see, that shared libs from qt are NOT added like libraries, but added after the project objects as if they where just object files.
              Don't remember, where I got this tip from (it was in this forum so) - but looks like the recommended addition

              unix:!mac {
                LIBS += -Wl,-rpath=\$$ORIGIN/libs
              }
              

              does not work and will not be recognized/expanded.

              On another project using external shared libs I wrote the Makefile manually like this:

              LC_FLAGS = -DLOCALE_DIR=\"/usr/share/locale\" \
               -DPACKAGE=\"linuxcnc\" \
               $(TOOL_NML_FLAG) \
               -L$(abspath lc/lib) \
               -Wl,-rpath,$(abspath lc/lib) \
               -Xlinker -Map=libLinuxCNC.map \
               -L/usr/X11R6/lib -lm -lGL
              
              NML_OBJS = $(abspath lc/src/objects/libnml/nml/nml.o) \
               $(abspath lc/src/objects/libnml/nml/cmd_msg.o) \
               $(abspath lc/src/objects/libnml/nml/nml_mod.o) \
               $(abspath lc/src/objects/libnml/nml/nml_oi.o) \
               $(abspath lc/src/objects/libnml/nml/nml_srv.o) \
               $(abspath lc/src/objects/libnml/nml/nmldiag.o) \
               $(abspath lc/src/objects/libnml/nml/nmlmsg.o) \
               $(abspath lc/src/objects/libnml/nml/stat_msg.o)
              
              ifeq ($(TOOL_NML),yes)
              LC_OBJS = $(abspath lc/src/objects/emc/nml_intf/emc.o) \
               $(abspath lc/src/objects/emc/nml_intf/emcops.o) \
               $(abspath lc/src/objects/emc/rs274ngc/modal_state.o) \
               $(abspath lc/src/objects/emc/tooldata/tooldata_common.o) \
               $(abspath lc/src/objects/emc/tooldata/tooldata_nml.o) \
               $(abspath lc/src/objects/emc/tooldata/tooldata_db.o)
              else
              LC_OBJS = $(abspath lc/src/objects/emc/nml_intf/emc.o) \
               $(abspath lc/src/objects/emc/nml_intf/emcops.o) \
               $(abspath lc/src/objects/emc/rs274ngc/modal_state.o) \
               $(abspath lc/src/objects/emc/tooldata/tooldata_common.o) \
               $(abspath lc/src/objects/emc/tooldata/tooldata_mmap.o) \
               $(abspath lc/src/objects/emc/tooldata/tooldata_db.o)
              endif
              
              %.o : %.cc
              	$(GCC) -c $(CC_FLAGS) -o $@ $<
              
              TestNML:	TestNML.o $(LC_OBJS) $(NML_OBJS)
              	$(GCC) $(LC_FLAGS) -o $@ $^
              
              

              building that app works without issue.

              So I'd like to ask again:

              Is there a way to add files to qmake object list, that don't get removed at running clean command?

              1 Reply Last reply
              0
              • D Offline
                D Offline
                django.Reinhard
                wrote on 5 Sept 2021, 04:39 last edited by
                #7

                Hi,

                I found the solution by myself.

                @ChrisW67 said in Howto use an external shared lib?:

                You do it with qmake by adding the relevant linker switches to the LIBS variable in your PRO file:

                You where right.
                The point of evil is - this works for absolute paths only!
                ... and I didn't want to hardcode the location of external projects.

                so - qmake variable "_PRO_FILE_PWD_" was the key :)

                ... and that leaded to these statements in pro file:

                unix:!mac {
                  LIBS += -Wl,-rpath=$${_PRO_FILE_PWD_}/lc/lib
                }
                LIBS += \
                  -L$${_PRO_FILE_PWD_}/lc/lib \
                  -lnml
                
                

                Thanks!

                1 Reply Last reply
                2
                • C Offline
                  C Offline
                  ChrisW67
                  wrote on 6 Sept 2021, 01:30 last edited by
                  #8

                  Glad you found it. Relative paths are fragile beasts. Qt Creator, for example, will default to a shadow build which means that a library in a location relative to the source is not in the same location relative to the build area. Building in-source, from the command line would possibly have worked (though not recommended).

                  In your manual Makefile from the other project you had gone out of your way to determine the abspath of the library directory.

                  1 Reply Last reply
                  0

                  1/8

                  4 Sept 2021, 03:23

                  • Login

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