Uploaded image for project: 'Qbs ("Cubes")'
  1. Qbs ("Cubes")
  2. QBS-1516

Qbs puts -Wl options after object files in linker command, resulting in linker errors

    XMLWordPrintable

    Details

      Description

      This file

      lib.qbs
      import qbs
      import qbs.Environment
      import qbs.FileInfo
      
      import "images/isle-images.qbs" as IsleImages
      import "js/isle-js.qbs" as IsleJs
      import "qml/isle-qml.qbs" as IsleQml
      
      Product {
          id: root
          targetName: "isle"
          type: Qt.core.staticBuild ? "staticlibrary" : "dynamiclibrary"
      
          Depends { name: "cpp" }
          Depends { name: "Qt"; submodules: ["core", "gui", "quick", "widgets"]; versionAtLeast: "5.12" }
          // For version info.
          Depends { name: "vcs" }
          Depends { name: "bundle" }
          Depends { name: "libtiled" }
      
          readonly property bool linux: qbs.targetOS.contains("linux")
      
          readonly property string tiledIncludeDir: FileInfo.cleanPath(sourceDirectory + "/../3rdparty/tiled/src")
          readonly property string fmodRootDir: Environment.getEnv("FMOD_DIR")
          readonly property string fmodIncludeDir: fmodRootDir + "/api/lowlevel/inc"
          readonly property string fmodLibDir: fmodRootDir + "/api/lowlevel/lib" + (linux ? "/x86_64" : "")
      
          cpp.cxxLanguageVersion: "c++11"
          cpp.includePaths: [
              FileInfo.cleanPath(product.sourceDirectory + "/../3rdparty/tiled/src"),
              fmodIncludeDir
          ]
          // https://bugreports.qt.io/browse/QBS-1434
          cpp.minimumMacosVersion: "10.7"
          cpp.visibility: "minimal"
          cpp.defines: [
              "ISLE_LIBRARY"
          ]
          cpp.linkerFlags: [
              "-L" + fmodLibDir, "-lfmod"
          ]
          cpp.rpaths: [
              fmodLibDir
          ]
      
          bundle.isBundle: false
          cpp.sonamePrefix: qbs.targetOS.contains("darwin") ? "@rpath" : undefined
      
          Export {
              Depends { name: "cpp" }
              Depends {
                  name: "Qt"
                  submodules: ["core", "gui", "quick", "widgets"]
              }
              Depends { name: "libtiled" }
      
              cpp.includePaths: [
                  product.sourceDirectory,
                  root.tiledIncludeDir,
                  root.fmodIncludeDir
              ]
              cpp.linkerFlags: root.cpp.linkerFlags
              cpp.rpaths: root.cpp.rpaths
          }
      
          Group {
              qbs.install: true
              qbs.installDir: {
                  if (qbs.targetOS.contains("windows"))
                      return ""
                  else if (qbs.targetOS.contains("darwin"))
                      return "tshnm-iso.app/Contents/Frameworks"
              }
              fileTagsFilter: "dynamiclibrary"
          }
      
          IsleImages {}
          IsleJs {}
          IsleQml {}
      
          files: [
              // ...
          ]
      }
      

      results in this linker command when building the application that uses the library

      /usr/bin/g++ '-Wl,-m,elf_x86_64,-rpath,$ORIGIN/lib,-rpath,/home/mitch/dev/qt5.13-debug/qtbase/lib,-rpath,/home/mitch/dev/FMOD/api/lowlevel/lib/x86_64,-rpath,/home/mitch/dev/qt5.13-debug/qtbase/lib,-L/home/mitch/dev/FMOD/api/lowlevel/lib/x86_64,-lfmod' -L/home/mitch/dev/qt5.13-debug/qtbase/lib -m64 -o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/tshnm-iso /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/TshnmApplication.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/main.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_audio.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_gui.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_levels.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_qtquickcontrols2.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_scripts.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_sprites.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_tiles.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_tshnm-iso.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/73489b871e127538/moc_TshnmApplication.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Widgets.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Quick.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Qml.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Network.so.5.13.2 /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/libtiled.080f31f8/libtiled.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Core.so.5.13.2 -lpthread /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Core.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Network.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Qml.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so
      

      which results in these error messages

      14:55:02: Running steps for project tshnm-iso...
      linking tshnm-iso [app]
      /usr/bin/g++ '-Wl,-m,elf_x86_64,-rpath,$ORIGIN/lib,-rpath,/home/mitch/dev/qt5.13-debug/qtbase/lib,-rpath,/home/mitch/dev/FMOD/api/lowlevel/lib/x86_64,-rpath,/home/mitch/dev/qt5.13-debug/qtbase/lib,-L/home/mitch/dev/FMOD/api/lowlevel/lib/x86_64,-lfmod' -L/home/mitch/dev/qt5.13-debug/qtbase/lib -m64 -o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/tshnm-iso /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/TshnmApplication.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/main.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_audio.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_gui.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_levels.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_qtquickcontrols2.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_scripts.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_sprites.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_tiles.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_tshnm-iso.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/73489b871e127538/moc_TshnmApplication.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Widgets.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Quick.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Qml.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Network.so.5.13.2 /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/libtiled.080f31f8/libtiled.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Core.so.5.13.2 -lpthread /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Core.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Network.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Qml.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so
      //usr/lib/x86_64-linux-gnu/libasan.so.4: warning: the use of `tmpnam' is dangerous, better use `mkstemp'
      //usr/lib/x86_64-linux-gnu/libasan.so.4: warning: the use of `tempnam' is dangerous, better use `mkstemp'
      //usr/lib/x86_64-linux-gnu/libasan.so.4: warning: the use of `tmpnam_r' is dangerous, better use `mkstemp'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::Sound::getLength(unsigned int*, unsigned int)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::ChannelControl::stop()'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::System::update()'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::ChannelControl::setCallback(FMOD_RESULT (*)(FMOD_CHANNELCONTROL*, FMOD_CHANNELCONTROL_TYPE, FMOD_CHANNELCONTROL_CALLBACK_TYPE, void*, void*))'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::Sound::setLoopCount(int)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::System::createChannelGroup(char const*, FMOD::ChannelGroup**)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::Channel::setChannelGroup(FMOD::ChannelGroup*)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::System::createSound(char const*, unsigned int, FMOD_CREATESOUNDEXINFO*, FMOD::Sound**)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::System::playSound(FMOD::Sound*, FMOD::ChannelGroup*, bool, FMOD::Channel**)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::ChannelGroup::release()'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD_System_Create'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::Channel::getCurrentSound(FMOD::Sound**)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::System::init(int, unsigned int, void*)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::ChannelControl::setPaused(bool)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::ChannelControl::setVolume(float)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::ChannelControl::setUserData(void*)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::System::release()'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::ChannelControl::getUserData(void**)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::Channel::getPosition(unsigned int*, unsigned int)'
      /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so: undefined reference to `FMOD::Sound::release()'
      collect2: error: ld returned 1 exit status
      Process failed with exit code 1.
      The following products could not be built for configuration Debug:
      app
      Error while building/deploying project tshnm-iso (kit: qt5.13-debug)
      When executing step "Qbs Build"
      14:55:03: Elapsed time: 00:01.
      

      After a bit of searching, I found this answer:

      https://stackoverflow.com/a/30559538

      I tried it out on the command line by moving the -Wl arguments to the end of the command, and it linked fine after that:

      /usr/bin/g++ -L/home/mitch/dev/qt5.13-debug/qtbase/lib -m64 -o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/tshnm-iso /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/TshnmApplication.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/main.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_audio.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_gui.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_levels.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_qtquickcontrols2.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_scripts.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_sprites.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_tiles.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/3a52ce780950d4d9/qrc_tshnm-iso.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/app.7d104347/73489b871e127538/moc_TshnmApplication.cpp.o /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/lib.9d062baf/libisle.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Widgets.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Quick.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Qml.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Network.so.5.13.2 /home/mitch/dev/tshnm-iso-qbs-qt5_13_debug-Debug/Debug/libtiled.080f31f8/libtiled.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so.5.13.2 /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Core.so.5.13.2 -lpthread /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Core.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Network.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Qml.so /home/mitch/dev/qt5.13-debug/qtbase/lib/libQt5Gui.so '-Wl,-m,elf_x86_64,-rpath,$ORIGIN/lib,-rpath,/home/mitch/dev/qt5.13-debug/qtbase/lib,-rpath,/home/mitch/dev/FMOD/api/lowlevel/lib/x86_64,-rpath,/home/mitch/dev/qt5.13-debug/qtbase/lib,-L/home/mitch/dev/FMOD/api/lowlevel/lib/x86_64,-lfmod'
      

      The answer that that answer links to also says:

      Linking to dynamic libraries

      $ export LD_LIBRARY_PATH=. # not needed if libs go to /usr/lib etc
      $ g++ -fpic -shared d.cpp -o libd.so
      $ g++ -fpic -shared b.cpp -L. -ld -o libb.so # specifies its dependency!
      
      $ g++ -L. -lb a.cpp # wrong order (works on some distributions)
      $ g++ -Wl,--as-needed -L. -lb a.cpp # wrong order
      $ g++ -Wl,--as-needed a.cpp -L. -lb # right order
      

      It's the same here - the libraries must follow the object files of the program. The difference here compared with static libraries is that you need not care about the dependencies of the libraries against each other, because dynamic libraries sort out their dependencies themselves.

      Some recent distributions apparently default to using the --as-needed linker flag, which enforces that the program's object files come before the dynamic libraries. If that flag is passed, the linker will not link to libraries that are not actually needed by the executable (and it detects this from left to right). My recent archlinux distribution doesn't use this flag by default, so it didn't give an error for not following the correct order.

      If the --as-needed flag would have given an error here, it sounds like it's worth having, though I'm not sure how to use it.

        Attachments

        For Gerrit Dashboard: QBS-1516
        # Subject Branch Project Status CR V

          Activity

            People

            Assignee:
            kandeler Christian Kandeler
            Reporter:
            mitch_curtis Mitch Curtis
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Dates

              Created:
              Updated:
              Resolved:

                Gerrit Reviews

                There are no open Gerrit changes