我是CMake的新手,我正在尝试使用它来构建一个小的KDE应用程序。我要使用QTXml模块,我的程序编译没有问题,但在链接阶段,ld无法找到QXml组件......
的main.cpp
#include "test.h"
int main(int argc, char **argv)
{
return 0;
}
test.h
#ifndef TEST_H
#define TEST_H
#include <QXmlResultItems>
#include <QString>
#include <QBuffer>
#include <QXmlQuery>
class test {
public:
test(){}
~test(){}
QXmlResultItems* find ( const QString& node, const QString& xpath );
private:
QBuffer device_;
};
#endif // TEST_H
TEST.CPP
#include "test.h"
QXmlResultItems* test::find ( const QString& node, const QString& xpath )
{
QXmlResultItems* result = new QXmlResultItems;
QXmlQuery query;
query.bindVariable ( "device",&device_ );
query.setQuery ( "doc($device)/"+node+"/"+xpath );
query.evaluateTo ( result );
return result;
}
CMakeLists.cmake
project(qtcmakepb)
find_package(KDE4 REQUIRED)
include (KDE4Defaults)
include_directories( ${KDE4_INCLUDES} ${QT_INCLUDES} )
#Supposed to be useless because of KDE4 REQUIRED and ${QT_INCLUDES}
find_package(Qt4 COMPONENTS QtCore QtXml REQUIRED )
# In this CMakeLists.txt we define which files
# are used to compile the application
set(qtcmakepb_SRCS main.cpp test.cpp)
# Set the name of the application
kde4_add_executable(qtcmakepb ${qtcmakepb_SRCS})
# Select which libraries we need to link to
target_link_libraries(qtcmakepb ${KDE4_KDEUI_LIBS})
target_link_libraries(qtcmakepb ${QT_QTCORE_LIBS})
target_link_libraries(qtcmakepb ${QT_QTXML_LIBS})
# Tell cmake to install the application binary
install(TARGETS qtcmakepb ${INSTALL_TARGETS_DEFAULT_ARGS})
# Install the .desktop file
install( PROGRAMS qtcmakepb.desktop DESTINATION ${XDG_APPS_INSTALL_DIR} )
make的输出:
Linking CXX executable qtcmakepb
CMakeFiles/qtcmakepb.dir/test.o: In function `test::find(QString const&, QString const&)':
/home/zelwina/projects/QtCmakePb/src/test.cpp:5: undefined reference to `QXmlResultItems::QXmlResultItems()'
/home/zelwina/projects/QtCmakePb/src/test.cpp:6: undefined reference to `QXmlQuery::QXmlQuery()'
/home/zelwina/projects/QtCmakePb/src/test.cpp:7: undefined reference to `QXmlQuery::bindVariable(QString const&, QIODevice*)'
/home/zelwina/projects/QtCmakePb/src/test.cpp:8: undefined reference to `QXmlQuery::setQuery(QString const&, QUrl const&)'
/home/zelwina/projects/QtCmakePb/src/test.cpp:9: undefined reference to `QXmlQuery::evaluateTo(QXmlResultItems*) const'
/home/zelwina/projects/QtCmakePb/src/test.cpp:10: undefined reference to `QXmlQuery::~QXmlQuery()'
collect2: erreur: ld a retourné 1 code d'état d'exécution
make[2]: *** [src/qtcmakepb] Erreur 1
make[1]: *** [src/CMakeFiles/qtcmakepb.dir/all] Erreur 2
make: *** [all] Erreur 2
我做错了什么?
答案 0 :(得分:2)
要使用CMake的FindQt4 module,请执行以下操作:
find_package(Qt4 COMPONENTS QtCore QtXml REQUIRED)
include(${QT_USE_FILE})
include_directories(${KDE4_INCLUDES} ${QT_INCLUDES})
target_link_libraries(qtcmakepb ${KDE4_KDEUI_LIBS} ${QT_LIBRARIES})
如果要指定单独的包含目录和库,请将上面的最后2行替换为:
include_directories(${KDE4_INCLUDES}
${QT_QTCORE_INCLUDE_DIR}
${QT_QTXML_INCLUDE_DIR})
target_link_libraries(qtcmakepb
${KDE4_KDEUI_LIBS}
${QT_QTCORE_LIBRARY}
${QT_QTXML_LIBRARY})
您的问题是您没有打电话给include(${QT_USE_FILE})
,而QT_QTCORE_LIBS
应该是QT_QTCORE_LIBRARY
(对于QtXml库也是如此)。此外,您需要在调用FindQt4模块后调用include_directories
,并include
调用QT_USE_FILE
。
有关随您的CMake版本提供的FindQt4模块的完整信息,请运行:
cmake --help-module FindQt4
的修改
事实证明,根本原因实际上是未定义的函数是QtXmlPatterns库的一部分,因此find_package
调用应该在列表中包含QtXmlPatterns
。
完成此操作后,变量${QT_QTXMLPATTERNS_INCLUDE_DIR}
和${QT_QTXMLPATTERNS_LIBRARY}
由通话include(${QT_USE_FILE})
设置,并可根据需要添加。
如果您正在使用QT5
使用Qt5,使用CMake变得更简单。
为了包含和链接QtXml和QtXmlPatterns,您只需要这些行:
find_package(Qt5Xml REQUIRED)
find_package(Qt5XmlPatterns REQUIRED)
并链接如下:
target_link_libraries(qtcmakepb Qt5::Xml Qt5::XmlPatterns)
答案 1 :(得分:0)
您是否启用了QT_USE_QTXML?
尝试:set(QT_USE_QTXML TRUE)
答案 2 :(得分:0)
不知道这是否有帮助,但是:
target_link_libraries(qtcmakepb ${QT_QTCORE_LIBS})
target_link_libraries(qtcmakepb ${QT_QTXML_LIBS})
你应该使用它:
target_link_libraries(qtcmakepb ${QT_LIBRARIES})
这会将您选择的所有内容与COMPONENTS
中的find_package(Qt4)
子句相关联。陷阱:如果您使用不同的Qt组件链接多个目标,这将无效。