简体   繁体   中英

Link to Qt in CMake --> cannot link to QML/QtQuick function

We are migrating a rather large codebase from Ubuntu 14.04 to 16.04. The codebase uses QML and QtQuick.

We use a Qt v5.9.1 in our dependencies (which is different than the Qt version installed in the system).

When compiling we have the following undefined references:

/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `qrand()@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to
`QAccessibleTextUpdateEvent::~QAccessibleTextUpdateEvent()@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QByteArray::mid(int, int) const@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QPainter::setOpacity(double)@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Qml.so.5.9.1:
undefined reference to `QXmlStreamReader::isCDATA() const@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QAnimationDriver::start()@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Qml.so.5.9.1:
undefined reference to `QLocale::toDate(QString const&, QString
const&) const@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QMetaType::unregisterConverterFunction(int,
int)@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QNetworkReply::finished()@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QMetaType::typeName(int)@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Qml.so.5.9.1:
undefined reference to `QXmlStreamReader::documentEncoding()
const@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QChar::toUpper(unsigned int)@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QTouchEvent::TouchPoint::state() const@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Quick.so.5.9.1:
undefined reference to `QElapsedTimer::start()@Qt_5'
/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/libQt5Qml.so.5.9.1:
undefined reference to `QDateTime::operator==(QDateTime const&)
const@Qt_5'

... and it goes on forever. The errors only occur for Qml / QtQuick functions, not other modules (eg QtCore, QtWidgets... do not output errors)

So we have checked our CMakeLists.txt and here is the way Qt is linked against:

set(CMAKE_INCLUDE_CURRENT_DIR ON) # Find includes in corresponding    build directories. set(CMAKE_AUTOMOC ON) # Instruct CMake to run moc    automatically when needed.
set(QT_DIR ../../Dependencies/Qt/v5.9.1/5.9.1/gcc_64)
set(CMAKE_PREFIX_PATH ${QT_DIR})

find_package(Qt5Widgets        REQUIRED)
find_package(Qt5Core           REQUIRED)
find_package(Qt5Gui            REQUIRED)
find_package(Qt5OpenGL         REQUIRED)
find_package(Qt5Quick          REQUIRED)
find_package(Qt5Qml            REQUIRED)
find_package(Qt5QuickControls2 REQUIRED)

target_link_libraries(${PROJECT_NAME}
     ...
     Qt5::Widgets
     Qt5::Core
     Qt5::Gui
     Qt5::OpenGL
     Qt5::Quick
     Qt5::Qml
     Qt5::QuickControls2 )

When having a close look at the CMake output we get:

   Cannot generate a safe runtime search path for target ToolKitApp
because    files in some directories may conflict with libraries in
implicit    directories:

     runtime library [libQt5Sql.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
       /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib
     runtime library [libQt5OpenGL.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
       /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib
     runtime library [libQt5Widgets.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
       /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib
     runtime library [libQt5Gui.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
       /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib
     runtime library [libQt5Network.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
       /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib
     runtime library [libQt5Core.so.5] in /usr/lib/x86_64-linux-gnu may be hidden by files in:
       /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib

   Some of these libraries may not be found correctly.

So it seems there is a mismatch between the system version of Qt and the version we use in our dependencies - Which we believe is the culprit.

So we have modified our CMakeLists.txt, adding set(Qt5_DIR) ...):

set(CMAKE_PREFIX_PATH ${QT_DIR}) set(Qt5Widgets_DIR       
../../Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake/Qt5Widgets)
set(Qt5Core_DIR          
../../Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake/Qt5Core)
set(Qt5Gui_DIR           
../../Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake/Qt5Gui)
set(Qt5OpenGL_DIR        
../../Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake/Qt5OpenGL)
set(Qt5Quick_DIR         
../../Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake/Qt5Quick)
set(Qt5Qml_DIR           
../../Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake/Qt5Qml)
set(Qt5QuickControls2_DIR
../../Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake/Qt5QuickControls2)
find_package(Qt5Widgets        REQUIRED NO_DEFAULT_PATH)
find_package(Qt5Core           REQUIRED NO_DEFAULT_PATH)
find_package(Qt5Gui            REQUIRED NO_DEFAULT_PATH)
find_package(Qt5OpenGL         REQUIRED NO_DEFAULT_PATH)
find_package(Qt5Quick          REQUIRED NO_DEFAULT_PATH)
find_package(Qt5Qml            REQUIRED NO_DEFAULT_PATH)
find_package(Qt5QuickControls2 REQUIRED NO_DEFAULT_PATH)

But this did not improve things.

Any idea of what is going on?

------------------EDIT------------------

We have made the following modification to CMakeLists.txt

set(CMAKE_PREFIX_PATH   /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64)
find_package(Qt5 COMPONENTS Core Gui OpenGL Quick QmlQuickControls2)

message("Qt5               : " Qt5_DIR)
message("Qt5Core           : " Qt5Core_DIR)
message("Qt5Widgets        : " Qt5Widgets_DIR)
message("Qt5Gui            : " Qt5Gui_DIR)
message("Qt5OpenGL         : " Qt5OpenGL_DIR)
message("Qt5Quick          : " Qt5Quick_DIR)
message("Qt5Qml            : " Qt5Qml_DIR)
message("Qt5QuickControls2 : " Qt5QuickControls2_DIR)

which did not change the behavior, but outputs

Qt5               : /usr/lib/x86_64-linux-gnu/cmake
Qt5Core           : /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake
Qt5Widgets        : /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake
Qt5Gui            : /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake
Qt5OpenGL         : /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64/lib/cmake
Qt5Quick          : /usr/lib/x86_64-linux-gnu/cmake
Qt5Qml            : /usr/lib/x86_64-linux-gnu/cmake
Qt5QuickControls2 : /usr/lib/x86_64-linux-gnu/cmake

which confirms there is a mismatch between the system/package version of Qt and the custom/dependencies version but does not offer a solution.

From your output, I guess you have the following setup:

  • You have some (but not all) Qt 5 libraries (including development files) installed via your package manager.
  • However, you probably don't have the QtQuick (development) libraries installed.
  • In addition, you have a Qt installation in /home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/ (I guess installed via the official Qt installer).
  • I would guess you try to compile and link against the Qt version in your home.

I think there is something wrong in the way you configure the project (ie the way you call cmake ), because CMake seems to search for Qt in your system location first and - as you set some variables inside your CMakeLists.txt file which forces it to also consider the installation in your home directory - selectively links against the Quick library from the other Qt installation. This definitely might lead to such linker errors, in particular if the system Qt version is older than the one you installed in your home.

Long story short: Have you tried to invoke CMake passing it the CMAKE_PREFIX_PATH variable on the command line? In your example, I guess it should look like this:

cmake \
    -DCMAKE_PREFIX_PATH=/home/onilsson/DevRoot/Dependencies/Qt/v5.9.1/5.9.1/gcc_64 \
    ..

Setting Qt5Core_DIR and the like should definitely not be necessary. From my experience with Qt and CMake, when you need to set these there's something wrong with your setup.

As Martin said, it seems CMake is linking to the libraries in your new system instead of the ones ported from your old system. In addition, your new system has the Qt libraries installed via the Ubuntu/Debian Aptitude package manager and is missing the qtdeclarative5-dev and the qml modules packages (you can install them on Ubuntu using sudo apt install qtdeclarative5-dev qtquick*). My guess for the reason why CMake isn't linking to your ported libraries is probably because of ownership issues. Did you try to check the ownership using "ls -lah" command in the parent directory. The ownership might be assigned to the root now, you can change it using the "sudo chown -R username:group Directory" command.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM