Installing Qt libraries on Linux

Is there a way of using install(TARGETS… to install the Qt libraries, together with their namelinks, on Linux?

I’d expect the following to work, but it does not, and I don’t understand why:

# First locate the Qt installation
find_package(Qt5 COMPONENTS Core Gui Widgets Designer Test REQUIRED PATHS "${CMAKE_PREFIX_PATH}/lib/cmake/Qt5" NO_DEFAULT_PATH)

# Verify that Qt5::Core is recognised as a target,
# and print out the location where its files were found
get_property(QT_CORE_INCLUDE_DIRS TARGET Qt5::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
list(GET QT_CORE_INCLUDE_DIRS 0 QT_CORE_MAIN_INCLUDE_DIR)
get_filename_component(QT_MAIN_DIR ${QT_CORE_MAIN_INCLUDE_DIR}/.. ABSOLUTE)
message("-- Qt version ${Qt5Core_VERSION_STRING} was located at ${QT_MAIN_DIR}")

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

install(TARGETS Qt5::Core Qt5::Gui Qt5::Widgets
        LIBRARY
        DESTINATION myInstallDirectory)

When I run CMake on this script, the output is:

-- Qt version 5.12.5 was located at [ ...exactly where I expected to find it...]

CMake Error at configureQT5.cmake::[line no.] (install):
install TARGETS given target "Qt5::Core" which does not exist.

I’ve successfully used Qt5::Core as a target just a few lines previously in the file, so why does it suddenly not exist?

find_package() provides you with imported targets. Those can be used for dependency propagation, linking, etc. but cannot be installed.

Thank you; but in that case, how can I install them? I need to do so since my application depends on them.

‘install(FILES’ works all right, but doesn’t copy the namelinks over, and it seems I need these as well because the physical file is libQt5Core.so.5.12.5 but my application looks for libQt5Core.so.5.

https://cmake.org/cmake/help/v3.18/command/file.html?highlight=file#get-runtime-dependencies

But when deploying it like that you should really look into snap or flatpak.

Additionally, copying Qt libraries is really only part of the job. You also need plug-ins, resources, etc. There is a tool for Qt Linux deployment, if you don’t want to do it all yourself.

I’ll have a go; but my concern is that I already know what the dependency is and I can install the library itself easily enough, it’s just that my application wants to link to the namelink and complains that it can’t find the library itself.

I either need to install the namelink, or figure out how to get the application to link to the library directly.

The plugins are easy to do, and I have CMake generate a custom qt.conf file to tell my application where to find them.

I know about windeployqt, but I thought that the Linux version was still ‘unofficial’ and not supported.

You should be able to use file(GET_RUNTIME_DEPENDENCIES) to find the runtime libraries used by your targets. You can then install these (though the namelinks would need some extra work today).

The FOLLOW_SYMLINK_CHAIN keyword of the file(COPY) or file(INSTALL) subcommands may help (keyword available since CMake 3.15), but you’d have to be installing your imported libraries with a custom install script to use it, which is perhaps more convoluted.

What I actually did was this… First, I worked backwards from the Qt5::Core target to find the directory where the Qt installation had been found:

get_property(QT_CORE_INCLUDE_DIRS TARGET Qt5::Core PROPERTY INTERFACE_INCLUDE_DIRECTORIES)
list(GET QT_CORE_INCLUDE_DIRS 0 QT_CORE_MAIN_INCLUDE_DIR)
get_filename_component(QT_MAIN_DIR ${QT_CORE_MAIN_INCLUDE_DIR}/.. ABSOLUTE)	

Then in the first instance I did what’s described here.

That didn’t quite get me out of the woods, though, because especially once I’d installed PySide2 as well and realised that people could now write scripts using any components of Qt, not just the ones I was using in my C++ application, I decided I’d better just go for it and install the whole Qt directory:

    install(DIRECTORY   ${QT_MAIN_DIR}/lib/
            DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}
            USE_SOURCE_PERMISSIONS)    
    install(DIRECTORY   ${QT_MAIN_DIR}/plugins/imageformats/
            DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/qt/plugins/imageformats
            USE_SOURCE_PERMISSIONS) 
    install(DIRECTORY   ${QT_MAIN_DIR}/plugins/platforms/
            DESTINATION ${CMAKE_INSTALL_FULL_LIBDIR}/qt/plugins/platforms
            USE_SOURCE_PERMISSIONS) 

This works nicely now.