Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-108286

Guard against a non-visible Svg target when find_package is done in a nested subdirectory

    XMLWordPrintable

Details

    • 82601c120 (dev)

    Description

      For full description, please see the forum post at:
      https://discourse.cmake.org/t/strange-problem-when-using-qt-add-qml-module-in-module-being-brought-in-via-fetchcontent/6781

      Slightly shorter version:
      In Qt 6 when using CMake build system, QML modules use qt_add_qml_module(). In following situation:

      BCControls/CMakeLists.txt
      project(BCControls)
      find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Svg Qml LinguistTools REQUIRED)
      
      set(QML_FILES
          BCInfoScreen.qml
          # omitting many files here
         )   
      set(RESOURCE_FILES 
          # omitting
      )
      qt_add_library(BCControls STATIC)
      file(GLOB TS_FILES translations/*.ts)
      qt_add_translations(BCControls
          TS_FILES ${TS_FILES}
          QM_FILES_OUTPUT_VARIABLE qmfiles
          )
      qt_add_qml_module(BCControls
          URI "BCControls"
          VERSION 1.0
          QML_FILES ${QML_FILES}
          RESOURCES ${RESOURCE_FILES}
          )
      qt_add_resources(BCControls "BCControlsTranslations" PREFIX "/translations" FILES ${qmfiles})
      
      # Images in SVG format exist in bccontrols.qrc.  Need to
      # load Qt${QT_VERSION_MAJOR}::Svg shared library at runtime.
      target_link_libraries(BCControls
          PRIVATE
          Qt${QT_VERSION_MAJOR}::Svg
          Qt${QT_VERSION_MAJOR}::Qml
          )
      
      BatchExecutor/CMakeLists.txt (app)
      find_package(Qt${QT_VERSION_MAJOR} COMPONENTS Core Gui Qml REQUIRED)
      
      set(RESOURCE_FILES
          # omitting
      )
      set(QML_FILES
          # omitting many files here
         )   
      set(CPP_FILES 
          # omitting
      )
      qt_add_executable(BatchExecutor  ${CPP_FILES})
      qt_add_qml_module(BatchExecutor
          VERSION 1.0
          URI "BatchExecutor"
          QML_FILES ${QML_FILES}
          RESOURCES ${RESOURCE_FILES}
      )
      
      FetchContent_Declare(BCControls SOURCE_DIR ${BCControls_LOC})
      FetchContent_MakeAvailable(BCControls)
      
      target_include_directories(BatchExecutor PRIVATE .)
      
      target_link_libraries(BatchExecutor
          PRIVATE
          Qt${QT_VERSION_MAJOR}::Core
          Qt${QT_VERSION_MAJOR}::Gui
          Qt${QT_VERSION_MAJOR}::Qml
          BCControls
      )
      

      In the case above following CMake configuration warning is output:

      CMake Warning at C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:698 (message):
        The BCControls target is a QML module with target path BCControls.  It uses
        an OUTPUT_DIRECTORY of
        C:/Projects/build-AEPP-Desktop_Qt_6_2_4_MSVC2019_32bit-Release/_deps/bccontrols-build,
        which should end in the same target path, but doesn't.  Tooling such as
        qmllint may not work correctly.
      Call Stack (most recent call first):
        C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:1458 (_qt_internal_target_enable_qmllint)
        C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:564 (qt6_target_qml_sources)
        C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Qml/Qt6QmlMacros.cmake:615 (qt6_add_qml_module)
        eSW/Qt/QtCommon/BCControls/CMakeLists.txt:282 (qt_add_qml_module)
      

      In addition, the application that is Fetching dependencies with this warning exhibits a CMake configuration error. In this example BatchExecutor, the executable wanting to link against BCControls, is complaining about a non-existent Qt6::Svg, but BatchExecutor is not itself dependent on that component.

      BatchExecutor error:

      CMake Error at C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Core/Qt6CoreMacros.cmake:592 (get_target_property):
        get_target_property() called with non-existent target "Qt6::Svg".
      Call Stack (most recent call first):
        C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Core/Qt6CoreMacros.cmake:681 (_qt_internal_finalize_executable)
        C:/Qt/6.2.4/install-dtop32-deb-and-rel/lib/cmake/Qt6Core/Qt6CoreMacros.cmake:661:EVAL:1 (qt6_finalize_target)
        eSW/Qt/Apps/BatchExecutor/CMakeLists.txt:DEFERRED
      This error goes away if I add Qt6::Svg on the list of REQUIRED COMPONENTS in the find_package() call.
      

      According to Alexandru's answer in the forum this happens:

      ...because the qml cmake api expects BCControls to be placed in a nested BCControls/CMakeLists.txt folder, so that the build folder where the .dll file is placed looks like
      /_deps/bccontrols-build/BCControls/BCControls.dll.
      This is due to some specifics how the QML engine expects dlls to be placed, so that they can be loaded at runtime (as well as for tooling like qmllint).

      Regarding the error.
      BCControls is a static library, that links to Svg, as can be seen in target_link_libraries.
      BatchExecutor then links against that static library.
      Qt has some code in the executable finalizer that walks over all transitive dependencies of the executable to detect if it needs to do certain things.
      It naturally encounters BatchExecutor → Svg and tries to get a property from the Svg target, but the target is not globally visible (because the find_package is done in a nested subdirectory, not where the executable is added, and the Svg target is local to that subdirectory scope) and that leads to an error.
      The workaround is indeed to move the find_package(Svg) to the root CMakeLists.txt

      I do think it’s a bug in Qt, which should guard against a non-visible Svg target and probably show a warning....

      Attachments

        Issue Links

          No reviews matched the request. Check your Options in the drop-down menu of this sections header.

          Activity

            People

              jbornema Joerg Bornemann
              foxxx Tuukka Kettunen
              Votes:
              0 Vote for this issue
              Watchers:
              3 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:

                Gerrit Reviews

                  There are no open Gerrit changes