qtcmakeqtplugin

Qt OPC UA Plugin is Always Linked in Debug Configuration


I am building a Qt project with CMake, trying to link it with the Qt OPC UA plugin.

The problem is, no matter which build configuration i choose, the compiled executable always gets linked against Qt6OpcUad.dll (so, the debug version) instead of QtOpcUa.dll as expected, no matter which build configuration i choose. Both the error dialog when running the exe manually and DependencyWalker confirm this.

I am linking the plugin like given in the tutorial:

find_package(Qt6 REQUIRED COMPONENTS Core Gui OpcUa Widgets)
target_link_libraries(opcuaviewer PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::OpcUa
    Qt6::Widgets
)

The plugin was compiled as described here, and seems to work fine when running it in debug mode. I can build and run the Qt OPC UA example application 'Opc UA Viewer' just fine from withing Qt Creator. Both QtOpcUa.dll and Qt6OpcUad.dll exist in C:\Qt\6.7.1\msvc2019_64\bin.

When trying to set the MAP_IMPORTED_CONFIG variables like described here and here, CMake gives these error messages:

[cmake] CMake Error in CMakeLists.txt:
[cmake]   IMPORTED_IMPLIB not set for imported target "Qt6::OpcUa" configuration
[cmake]   "Release".
[cmake] 
[cmake] CMake Error in CMakeLists.txt:
[cmake]   IMPORTED_LOCATION not set for imported target "Qt6::OpcUa" configuration
[cmake]   "Release".
[cmake] 
[cmake] CMake Error in CMakeLists.txt:
[cmake]   IMPORTED_IMPLIB not set for imported target "Qt6::OpcUa" configuration
[cmake]   "Release".
[cmake] 
[cmake] -- Generating done (0.0s)
[cmake] CMake Generate step failed.  Build files cannot be regenerated correctly.

This is the same for both if i set the CMake value before find_package:

set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE Release)
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpcUa Widgets)

or try to set the target property after linking:

target_link_libraries(opcuaviewer PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::OpcUa
    Qt6::Widgets
)
set_target_properties(Qt6::OpcUa PROPERTIES MAP_IMPORTED_CONFIG_RELEASE Release)

Setting the same property for Qt6::Core works, though.

This is with Qt6.7.1, Windows 10, and compiled with MSVC2019 64bit.


Update:

Following @Tsyvarev's advice i added the following to the CMake file:

set_target_properties(Qt6::OpcUa PROPERTIES IMPORTED_IMPLIB_RELEASE "C:/Qt/6.7.1/msvc2019_64/lib/Qt6OpcUa.lib")
set_target_properties(Qt6::OpcUa PROPERTIES IMPORTED_LOCATION_RELEASE "C:/Qt/6.7.1/msvc2019_64/lib/Qt6OpcUa.dll")

set_target_properties(Qt6::OpcUa PROPERTIES MAP_IMPORTED_CONFIG_DEBUG Release)
set_target_properties(Qt6::OpcUa PROPERTIES MAP_IMPORTED_CONFIG_RELEASE Release)

Which build fine, but still with the debug version. I then deleted the local debug version of the plugin. CMake will now report this:

[cmake] CMake Error at C:/Qt/6.7.1/msvc2019_64/lib/cmake/Qt6OpcUa/Qt6OpcUaTargets.cmake:126 (message):
[cmake]   The imported target "Qt6::OpcUa" references the file
[cmake] 
[cmake]      "C:/Qt/6.7.1/msvc2019_64/lib/Qt6OpcUad.lib"
[cmake] 
[cmake]   but this file does not exist.  Possible reasons include:
[cmake] 
[cmake]   * The file was deleted, renamed, or moved to another location.
[cmake] 
[cmake]   * An install or uninstall procedure did not complete successfully.
[cmake] 
[cmake]   * The installation package was faulty and contained
[cmake] 
[cmake]      "C:/Qt/6.7.1/msvc2019_64/lib/cmake/Qt6OpcUa/Qt6OpcUaTargets.cmake"
[cmake] 
[cmake]   but not all the files it references.

The file does, indeed, not exists anymore. But it should not be referenced in the first place.


Here is my full CMakeLists.txt. All commands in comments will lead to the described error message:

# Copyright (C) 2022 The Qt Company Ltd.
# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause

set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)

message("CMAKE_AUTOUIC is '" ${CMAKE_AUTOUIC} "'")
message("CMAKE_AUTOMOC is '" ${CMAKE_AUTOMOC} "'")
message("CMAKE_AUTORCC is '" ${CMAKE_AUTORCC} "'")
message("CMAKE_BUILD_TYPE is '" ${CMAKE_BUILD_TYPE} "'")

cmake_minimum_required(VERSION 3.16)
project(opcuaviewer LANGUAGES CXX)

if(NOT DEFINED INSTALL_EXAMPLESDIR)
    set(INSTALL_EXAMPLESDIR "examples")
endif()

set(INSTALL_EXAMPLEDIR "${INSTALL_EXAMPLESDIR}/opcua/opcuaviewer")

# set(CMAKE_MAP_IMPORTED_CONFIG_RELEASE Release)
find_package(Qt6 REQUIRED COMPONENTS Core Gui OpcUa Widgets)


qt_standard_project_setup()

qt_add_executable(opcuaviewer
    certificatedialog.cpp certificatedialog.h certificatedialog.ui
    main.cpp
    mainwindow.cpp mainwindow.h mainwindow.ui
    opcuamodel.cpp opcuamodel.h
    treeitem.cpp treeitem.h
)

qt_add_resources(opcuaviewer "pki"
    PREFIX /
    FILES
        pki/own/certs/opcuaviewer.der
        pki/own/private/opcuaviewer.pem
        pki/trusted/certs/3d8ec65c47524d6ad67bed912c19a895.der
        pki/trusted/certs/ca.der
        pki/trusted/certs/open62541-testserver.der
        pki/trusted/crl/ca.crl.pem
)
#set_target_properties(Qt6::OpcUa PROPERTIES IMPORTED_LOCATION_RELEASE "C:/Qt/6.7.1/msvc2019_64/lib/Qt6OpcUa.lib")

set_target_properties(opcuaviewer PROPERTIES
    WIN32_EXECUTABLE TRUE
    MACOSX_BUNDLE TRUE
)
target_link_libraries(opcuaviewer PRIVATE
    Qt6::Core
    Qt6::Gui
    Qt6::OpcUa
    Qt6::Widgets
)
# set_target_properties(Qt6::Core PROPERTIES MAP_IMPORTED_CONFIG_DEBUG Release)


install(TARGETS opcuaviewer
    RUNTIME DESTINATION "${INSTALL_EXAMPLEDIR}"
    BUNDLE DESTINATION "${INSTALL_EXAMPLEDIR}"
    LIBRARY DESTINATION "${INSTALL_EXAMPLEDIR}"
)

Update II: There seems to be something wrong with how i installed the plugin, as C:\Qt\6.7.1\msvc2019_64\lib\cmake\Qt6OpcUa\Qt6OpcUaTargets-release.cmake is missing. Here is the full Batch script i used:

set msvcSetEnvScript="C:\Program Files\Microsoft Visual Studio\2022\Professional\VC\Auxiliary\Build\vcvars64.bat"
set qtVersion=6.7.1
set qtSetEnvScript="C:\Qt\%qtVersion%\msvc2019_64\bin\qtenv2.bat"
set buildDir=

pushd "C:\"
call %qtSetEnvScript%
call %msvcSetEnvScript%
popd

git clone https://code.qt.io/qt/qtopcua.git 
cd qtopcua 
git checkout %qtVersion% 

REM Build Release.
mkdir build 
cd build 
call qt-cmake -G "NMake Makefiles" .. -DQT_BUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Release
nmake 
nmake install 

REM Build Debug.
cd ..
mkdir build_debug
cd build_debug
call qt-cmake -G "NMake Makefiles" .. -DQT_BUILD_EXAMPLES=ON -DCMAKE_BUILD_TYPE=Debug
nmake 
nmake install 

popd


Solution

  • Just wanted to close the loop on this.

    I am not sure at which point exactly things go wrong, but the cause is apparently a bug in the installation routine of the plugins CMake script.

    I was able to get my project to link with the release build of the plugin by uninstalling everything, and then installing only the the release build. The downside to this is, that now for both build configurations (release and debug), my project will only link to release. This is good enough for me for the moment.

    Many thanks again to @Tsyvarev for helping me to debug this. I was not able to fix the plugins behavior through any of the CMake settings mentioned, unfortunately.