I'm using Qt and CMake to develop C applications. On linux there my qt application runs fine, however on windows i have to copy the folders C:\Qt\5.15.8\msvc2019_64\bin and C:\Qt\5.15.8\msvc2019_64\plugins to the binary folder.
If I do not copy these files to the binary folder I'm getting Qt5xxx.dll missing at application startup. However (especially when using CMake Multi Config generators) this is a pretty waste of HDD space (and time). Is there any way to avoid this (this issue seams to be windows only) I'm running the example taken from https://doc.qt.io/archives/qt-5.12/cmake-manual.html
I also did try to set the CMAKE_PREFIX_PATH before find_package()
list(APPEND CMAKE_PREFIX_PATH "C:/Qt/5.15.8/msvc2019_64/bin")
find_package(Qt5 COMPONENTS ${ACTIVE_QT_MODULES} REQUIRED)
but this does not seam to work. Is there any other way to get this to work?
Thx for your help :)
Edit To clarify: I'm looking for a solution for a developer PC. All developer PCs already have multiple Qt versions installed at C:/Qt. Therefore in my opinion the copying on developer PCs is not necessary. Of course, when deploying the application to a non developer PC we use the deployqt tool to copy all the necessary stuff
CodePudding user response:
This post is just for summarising the comments section. After lots of input from @vre it turns out that there are 2 ways to solve this issue
add C:/Qt/5.15.8/msvc2019_64/bin to your PATH. =>Problem here: It is not easy to select a specific QT Version across different projects depending on a project configuration
add
set_property(DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} PROPERTY VS_STARTUP_PROJECT <executbale_target>)
and
set_property(TARGET <executable_target> PROPERTY VS_DEBUGGER_ENVIRONMENT "PATH=C:/Qt/5.15.8/msvc2019_64/bin")
=>Problem here: You select different Qt Versions for different projects. However the executable only starts when the (generated) solution file is used to run the executable
CodePudding user response:
Use CMake to find the necessary directories (dynamically), and generate two outputs. The first is, as recommended by @vre, VS_DEBUGGER_ENVIRONMENT for execution from the debugger and via the IDE. The second is a batch file that sets the environment variables, then invokes the process.
# Get location of Qt DLLS from the bin dir
get_filename_component(QT_BIN_DIR ${QT_MOC_EXECUTABLE} DIRECTORY)
# Also find the location of the Qt plugins, using a random plugin
get_target_property(qsqlite_loc Qt5::QSQLiteDriverPlugin LOCATION_Release)
get_filename_component(Qt5SqlDriver_PLUGIN_DIR ${qsqlite_loc} DIRECTORY)
get_filename_component(Qt5_PLUGINS_DIR ${Qt5SqlDriver_PLUGIN_DIR} DIRECTORY)
# Tell VSCode about these paths so the debugger can launch the app
string( CONCAT debugger_environment
"PATH=${QT_BIN_DIR};%PATH%\n"
"QT_QPA_PLATFORM_PLUGIN_PATH=${Qt5_PLUGINS_DIR}/platforms\n"
"QT_PLUGIN_PATH=${Qt5_PLUGINS_DIR}\n"
)
set_property(TARGET mytarget PROPERTY VS_DEBUGGER_ENVIRONMENT ${USERFILE_ENVIRONMENT})
# Also make a batch file
string( CONCAT batch_contents
"set PATH=${QT_BIN_DIR};%PATH%\n"
"set QT_QPA_PLATFORM_PLUGIN_PATH=${Qt5_PLUGINS_DIR}/platforms\n"
"set QT_PLUGIN_PATH=${Qt5_PLUGINS_DIR}\n"
"$<TARGET_FILE_NAME:${mytarget}>"
)
file( GENERATE OUTPUT "$<TARGET_FILE_DIR:mytarget>/$<TARGET_FILE_BASE_NAME:${mytarget}>.bat"
CONTENT "${batch_contents}" )
Variation: Omit the call to the target executable, and instead allow the .bat file to be called from a terminal to set up future runs from that terminal.
Future improvements: handle UNIX shell syntax for non-Windows builds