Strange problem when using qt_add_qml_module in module being brought in via FetchContent

Going thru a CMake restructure. As part of this many internal dependencies, some of which are QML modules, are being brought in via FetchContent. With Qt6, these QML modules use qt_add_qml_module(). These modules had no issues configuring and building prior to being added thru FetchContent, but now give a CMake configuration warning as shown below:

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. Prior to bringing BCControls in using FetchContent, there was no error.

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.

I’m pasting the relevant sections of the CMakeLists.txt from BCControls followed by that from BatchExecutor. I realize this is as much a Qt CMake integration problem as it is a pure CMake problem, but I know gurus like Craig Scott are here often and he is a domain expert in both as well as being the author of FetchContent, IIRC.

BCControls/CMakeLists.txt (qml module):

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
)

I’ll cross-post this on the Qt forums.

There’s something happening with finalization of the executable that appends the PRIVATE Qt6::Svg dependency of BCControls to the dependency list for BatchExecutor. I don’t understand what this finalization process is, though.

Finalization is a Qt-specific thing. It’s been a while since I was involved with Qt directly, but if I had to guess, I’d say something is adding Qt6::Svg as a requirement, but it is assuming you’ve listed that as a component in your find_package(Qt6 ...) call instead of doing that itself. I can’t comment on whether that’s a bug in Qt or the project(s) you’re using though.

@alcroito or @jobor might be better placed to comment further.

1 Like

Hi.

Regarding the warning, it 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, so feel free to file an issue in the Qt bug tracker.

2 Likes

Thank you @craig.scott and @alcroito for your responses. I’ll mark this as answered since the workaround is known. I’ll try to get a bug generated for Qt’s backlog.