简体   繁体   中英

Error while building custom Qt 4.8.3 library with CMake 2.8.11 on Windows

I am trying to migrate my Qt project from QMake to CMake but I am getting some errors when trying to build my library on Windows 7 with MSVC10. My CMakeLists.txt files is as follows:

cmake_minimum_required( VERSION 2.8.11 )

project( MyLibrary )
find_package(Qt4 REQUIRED)

set( CMAKE_AUTOMOC ON )
set( QT_USE_QTSCRIPT TRUE )

include( ${QT_USE_FILE} )
include_directories( ${CMAKE_CURRENT_BINARY_DIR}/include ${QT_INCLUDES} )

set( MyLibrary_SOURCES
    src/connection.cpp
    src/mylibrary.cpp
    src/node.cpp
    src/socket.cpp
    include/connection.h
    include/mylibrary.h
    include/node.h
    include/socket.h
    include/MyLibrary_global.h
)

add_library(MyLibrary SHARED ${MyLibrary_SOURCES})

target_link_libraries(MyLibrary ${QT_LIBRARIES} )

When I run I try to build with the generated nmake Makefile I get the following errors:

C2491:'Connection::staticMetaObjectExtraData' : definition of dllimport static data member not allowed
C2491: 'Connection::staticMetaObject' : definition of dllimport static data member not allowed

I'm new to CMake so I'm not sure if I'm missing something in the CMakeLists.txt file or if there are more tricks to using it with Qt. I should mention that the files that are getting the errors are the MOC generated ones.

Edit: So the output of

message(${QT_INCLUDES})

is as follows (formatting is for readability):

C:/Qt/4.8.3/include/QtDesigner
C:/Qt/4.8.3/include/QtDeclarative
C:/Qt/4.8.3/include/QtScriptTools
C:/Qt/4.8.3/include/QtDBus
C:/Qt/4.8.3/include/QtDesigner
C:/Qt/4.8.3/include/QtXml
C:/Qt/4.8.3/include/QtSql
C:/Qt/4.8.3/include/QtOpenGL
C:/Qt/4.8.3/include/QtMultimedia
C:/Qt/4.8.3/include/QtNetwork
C:/Qt/4.8.3/include/phonon
C:/Qt/4.8.3/include/QtXmlPatterns
C:/Qt/4.8.3/include/QtWebKit
C:/Qt/4.8.3/include/QtHelp
C:/Qt/4.8.3/include/QtUiTools
C:/Qt/4.8.3/include/QtTest
C:/Qt/4.8.3/include/QtScript
C:/Qt/4.8.3/include/QtSvg
C:/Qt/4.8.3/include/Qt3Support
C:/Qt/4.8.3/include/QtGui
C:/Qt/4.8.3/include/QtCore
C:/Qt/4.8.3/mkspecs/default
C:/Qt/4.8.3/include
C:/Qt/4.8.3/include/QtCore

I made tried not using auto-moc but I still get the same result and errors.

Reading this: Export QObject-based class to DLL I found what's wrong:

In .pro file I had the following: DEFINES +=APPLETTUTORIAL1_LIBRARY

Then in applet-tutorial1_global.h I have:

#if defined(APPLETTUTORIAL1_LIBRARY)
#  define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_EXPORT
#else
#  define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_IMPORT
#endif

#endif // APPLETTUTORIAL1_GLOBAL_H

Since I didn't have the equivalent in CMakeLists.txt the compiler goes to the

#  define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_IMPORT

line rather than the expected one:

#  define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_EXPORT

So my solution was to leave only this line and my shared library built well!

#  define APPLETTUTORIAL1SHARED_EXPORT Q_DECL_EXPORT

I tried the folllowing in CMakeLists.txt after reading this: http://www.cmake.org/Wiki/CMake:ConvertFromQmake but I did it wrong I think, thus the solution above.

SET(DEFINES "APPLETTUTORIAL1_LIBRARY")

Most of

http://www.cmake.org/cmake/help/v3.0/manual/cmake-qt.7.html

applies to CMake 2.8.11 too. Use imported targets, not the Use file.

Ok, I have 3 Ideas, not sure if they lead to a solution, but it could work.

First of all, what is in ${QT_INCLUDES} ? Add some message(${QT_INCLUDES}) please and share the output.

The second Idea would be to mock manually, as the error orrurs in the mock. For this try to remove the set( CMAKE_AUTOMOC ON ) and add:

set(QT_USE_QTUITOOLS true)

QT4_WRAP_UI(UI     UiFiles.ui)

QT4_WRAP_CPP(MOC3  QObjectFiles.h)

add_library(..........
                      ${UI} 
                      ${MOC3})

My third idea is to remove the SHARED , maybe this causes the error, but I am not sure on that one.

Please share what you get and I'll try to help :)

I don't have enough reputation to add a comment so I have to write an answer... Same problem but Qt4.8.5 here.

Keep using CMAKE_AUTOMOC because QT4_WRAP_CPP is the old way of doing... I found this : http://plagatux.es/2012/12/qt-automoc-with-cmake/

When I used old way, I got the same linkage error you had. With AUTOMOC I get other linkage /compilation errors but think I can go further:

applettutorial1.cpp.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) const tutorial1::AppletTutorial1::`vftable'{for `XAppletPlugin'}" (__imp_??_7AppletTutorial1@tutorial1@@6BXAppletPlugin@@@) referenced in function "public: __cdecl tutorial1::AppletTutorial1::AppletTutorial1(void)" (??0AppletTutorial1@tutorial1@@QEAA@XZ)

You might add this to your includes:

 ${QT_QTCORE_INCLUDE_DIR}
 ${QT_INCLUDE_DIR}

Hoping you solved and could give us feedback so this helps other people.

EDIT : in my case I solved the following errors to get a successful build:

  • correctly check CMAKE_BUILD_TYPE against "Debug" string, not "DEBUG" as I read here and there. RTFM.
  • build my lib as STATIC, not SHARED.

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