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
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.