FindQt4 fails to link QtOpenGL project properly - qt

Projects that use the QtOpenGL fail to link to gl calls, but only on Windows (Linux is happy). The MSVC 2008 error messages for the following minimal case project are:
1>gllink.obj : error LNK2019: unresolved external symbol __imp__glLoadIdentity#0 referenced in function "protected: virtual void __thiscall ImageWidget::initializeGL(void)" (?initializeGL#ImageWidget##MAEXXZ)
1>gllink.obj : error LNK2019: unresolved external symbol __imp__glMatrixMode#4 referenced in function "protected: virtual void __thiscall ImageWidget::initializeGL(void)" (?initializeGL#ImageWidget##MAEXXZ)
1>gllink.exe : fatal error LNK1120: 2 unresolved externals
These errors disappear when I manually add "opengl32.lib" to the "Additional Dependencies" list, but I believe this should not be necessary, since this should either be done by FindQt4.cmake, or should be taken care of by the dependency of QtOpenGL on opengl32. Of course, I must be mistaken, so I would really appreciate some input on how to properly fix this project.
gllink.cpp
#include <QtOpenGL>
#include <QWidget>
class ImageWidget : public QGLWidget
{
public:
ImageWidget(QWidget* parent = 0) :
QGLWidget(parent)
{
}
protected:
void initializeGL()
{
glMatrixMode( GL_MODELVIEW );
glLoadIdentity();
}
};
int main()
{
ImageWidget w;
return 0;
}
CMakeLists.txt
PROJECT( gllink )
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
FIND_PACKAGE( Qt4 4.6.0 REQUIRED COMPONENTS QtCore QtGui QtOpenGL )
INCLUDE( ${QT_USE_FILE} )
ADD_EXECUTABLE( gllink gllink.cpp )
TARGET_LINK_LIBRARIES( gllink ${QT_LIBRARIES} )

FindQt4 doesn't take care of that, you have to search for OpenGL by yourself. Now CMake provides a FindOpenGL package, so fixing your project is just a matter of adding find_package( OpenGL ) and linking the libraries to your target:
PROJECT( gllink )
CMAKE_MINIMUM_REQUIRED( VERSION 2.8 )
FIND_PACKAGE( OpenGL )
FIND_PACKAGE( Qt4 4.6.0 REQUIRED QtCore QtGui QtOpenGL )
INCLUDE( ${QT_USE_FILE} )
ADD_EXECUTABLE( gllink gllink.cpp )
TARGET_LINK_LIBRARIES( gllink ${OPENGL_LIBRARIES} ${QT_LIBRARIES} )
Btw, you should check if those libraries are really found and warn the user about the problem if they're not :)

Related

How to reference a Qt Application?

In order to test some functions of a Qt application (named qtapp), I build the Qt application as lib/dll library. The ctor and dtor have been correctly exported in the library. However compiling the test project (a Qt console project named consoleTest) is always running to the following link errors:
Link:
1> Bibliothek "C:\Users\gmbh\test\x64\Debug\consoleTest.lib" und Objekt C:\Users\gmbh\test\x64\Debug\consoleTest.exp" werden erstellt.
1>moc_testFour.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static struct QMetaObject const qtapp::staticMetaObject" (?staticMetaObject#qtapp##2UQMetaObject##B)".
1>testFour.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""public: static struct QMetaObject const qtapp::staticMetaObject" (?staticMetaObject#qtapp##2UQMetaObject##B)".
1>C:\Users\gmbh\test\x64\Debug\consoleTest.exe : fatal error LNK1120: 1 nicht aufgelöste Externe
The Qt application is quite simple:
#ifndef QTAPP_H
#define QTAPP_H
#include <QtWidgets/QMainWindow>
#include "ui_qtapp.h"
class __declspec(dllexport) qtapp : public QMainWindow
{
Q_OBJECT
public:
qtapp(QWidget* parent = 0);
~qtapp();
private:
Ui::qtappClass ui;
};
#endif // QTAPP_H
Implementation:
#include "qtapp.h"
__declspec(dllexport) qtapp::qtapp(QWidget* parent)
: QMainWindow(parent)
{
ui.setupUi(this);
}
__declspec(dllexport) qtapp::~qtapp()
{
}
If I simply include #include "qtapp.h" in the test project, the compiler yields the above error.
My questions:
What are the causes for the errors?
How to correctly deploy a Qt
application as lib?
My compiler is visual studio 2013, qt has the version of 5.4.2
That's actually a question independent of Qt. When linking an application against the library you need to have __declspec(dllimport) instead of __declspec(dllexport).
To achieve that, one usually uses defines that change when linking the library vs linking the application against the library. Microsoft has a help page on that "Importing into an Application Using __declspec(dllimport)".
The Qt documentation provides another one. The one thing where Qt can help, is replacing the __declspec by a cross-platform Q_DECL_IMPORT.

CMake: new subclass of dependency "unresolved external symbol"

I have a problem subclassing a VTK class, but I think the problem could be linked to any kind of library.
I did a vtkInteractorStyleImage subclass, just overriding a method:
#ifndef dcmInteractorStyleImage_h
#define dcmInteractorStyleImage_h
#include "vtkInteractionStyleModule.h" // For export macro
#include "vtkInteractorStyleImage.h"
class VTKINTERACTIONSTYLE_EXPORT dcmInteractorStyle : public vtkInteractorStyleImage
{
public:
static dcmInteractorStyle *New();
vtkTypeMacro(dcmInteractorStyle, vtkInteractorStyleImage);
virtual void OnLeftButtonDown();
void PrintSelf(ostream& os, vtkIndent indent);
};
#endif
The thing is I use it in a Qt class. So I include this in my CMakeLists.txt (simplified):
set(GENERIC_VIEW_CPP
View/UI/dcminteractorstyle.cpp # my new class
)
SET(GENERIC_VIEW_H
View/UI/dcminteractorstyle.h # my new class
)
add_library(generic ${GENERIC_VIEW_CPP} ${GENERIC_VIEW_H})
...
add_library(ui_qt ${UI_QT_CXX}
${UI_FORM_HEADERS} ${UI_RESOURCES_RCC}
${MODEL_WRAPPED_HEADERS}
${GENERIC_VIEW_CPP} ${GENERIC_VIEW_H} #necesary here?
)
qt5_use_modules(ui_qt Core Gui Widgets)
----------------------------------------------------------
# VTK
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
# ITK
find_package(ITK REQUIRED)
include(${ITK_USE_FILE})
if (ITKVtkGlue_LOADED)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
else()
find_package(ItkVtkGlue REQUIRED)
include(${ItkVtkGlue_USE_FILE})
set(Glue ItkVtkGlue)
endif()
------------------------------------------------
set_source_files_properties(${UI_RESOURCES_RCC} PROPERTIES GENERATED ON)
add_executable(UtilidadDICOM WIN32 main.cpp ${UI_RESOURCES_RCC})
target_link_libraries(UtilidadDICOM
model
ui_qt
generic
${Glue}
${VTK_LIBRARIES}
${ITK_LIBRARIES}
)
The error trying to compile:
ui_qt.lib(viewerwidget.cpp.obj):-1: error: LNK2019: unresolved
external symbol "public: static class dcmInteractorStyle * __cdecl
dcmInteractorStyle::New(void)" (?New#dcmInteractorStyle##SAPAV1#XZ)
referenced in function "public: static class vtkSmartPointer __cdecl vtkSmartPointer::New(void)"
(?New#?$vtkSmartPointer#VdcmInteractorStyle####SA?AV1#XZ)
ui_qt is a library declared in CMake, as you can see above.
Any ideas? Thank you.
Short answer is that your class is not being linked. Try seeing the value in generic just before linking it to your executable. Do a message just before target_link_libraries:
MESSAGE(${generic})
and see if the generic.lib is actually being linked.

QVTKWidget error when linking Qt with VTK

I'm having the famous linking error when trying to combine Qt and VTK. I've done all the steps of installing Qt with VTK correctly so I don't know what could possibly be wrong.
I'm using windows 8 with Qt5 and VTK 6.3 on visual studio.
Here is the error I get:
Drawing.obj : error LNK2019: symbole externe non résolu "__declspec(dllimport) public: __thiscall QVTKWidget::QVTKWidget(class QWidget *,class QFlags<enum Qt::WindowType>)" (__imp_??0QVTKWidget##QAE#PAVQWidget##V?$QFlags#W4WindowType#Qt#####Z) référencé dans la fonction "public: __thiscall Drawing::Drawing(void)" (??0Drawing##QAE#XZ)
1>Drawing.obj : error LNK2019: symbole externe non résolu "__declspec(dllimport) public: virtual __thiscall QVTKWidget::~QVTKWidget(void)" (__imp_??1QVTKWidget##UAE#XZ) référencé dans la fonction "public: __thiscall Drawing::~Drawing(void)" (??1Drawing##QAE#XZ)
And here is the code I use:
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QVtk w;
w.show();
//start();
return a.exec();
}
I followed everything that was written here: Combining Qt 5.4.1 with vtk 6.2.0 (using CMake GUI 3.2.1) on windows but somehow I get this error.
Also, I've added: $(QTDIR)\lib to my additional libraries $(QTDIR)\include to my "other include directories" and the followings to my additional dependencies.
qtmaind.lib
C:\Users\Lonni\VTK\Build2012Qt\lib\MinSizeRel\QVTKWidgetPlugin.lib
Qt5Cored.lib
Qt5Guid.lib
Qt5Locationd.lib
Qt5Multimediad.lib
Qt5MultimediaWidgetsd.lib
Qt5Testd.lib
Qt5AxContainerd.lib
Qt5AxBased.lib
Qt5OpenGLd.lib
opengl32.lib
glu32.lib
Qt5Sensorsd.lib
Qt5Svgd.lib
Qt5Widgetsd.lib
EDIT:
I did not use CMake for the project as I have issues when using Cmake even with the small example provided on the wiki which gives the following error with the following CMakeLists.txt. NB: I use Visual Studio as a generator.
CMakeLists:
cmake_minimum_required(VERSION 2.8)
if(POLICY CMP0020)
cmake_policy(SET CMP0020 NEW)
endif()
PROJECT(RenderWindowNoUiFile)
find_package(VTK REQUIRED)
include(${VTK_USE_FILE})
if(${VTK_VERSION} VERSION_GREATER "6" AND VTK_QT_VERSION VERSION_GREATER "4")
# Instruct CMake to run moc automatically when needed.
set(CMAKE_AUTOMOC ON)
find_package(Qt5Widgets REQUIRED QUIET)
else()
find_package(Qt4 REQUIRED)
include(${QT_USE_FILE})
endif()
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
file(GLOB UI_FILES *.ui)
file(GLOB QT_WRAP *.h)
file(GLOB CXX_FILES *.cxx)
if(${VTK_VERSION} VERSION_GREATER "6" AND VTK_QT_VERSION VERSION_GREATER "4")
qt5_wrap_ui(UISrcs ${UI_FILES} )
# CMAKE_AUTOMOC in ON so the MocHdrs will be automatically wrapped.
add_executable(RenderWindowNoUiFile MACOSX_BUNDLE
${CXX_FILES} ${UISrcs} ${QT_WRAP})
qt5_use_modules(RenderWindowNoUiFile Core Gui)
target_link_libraries(RenderWindowNoUiFile ${VTK_LIBRARIES})
else()
QT4_WRAP_UI(UISrcs ${UI_FILES})
QT4_WRAP_CPP(MOCSrcs ${QT_WRAP})
add_executable(RenderWindowNoUiFile MACOSX_BUNDLE ${CXX_FILES} ${UISrcs} ${MOCSrcs})
if(VTK_LIBRARIES)
if(${VTK_VERSION} VERSION_LESS "6")
target_link_libraries(RenderWindowNoUiFile ${VTK_LIBRARIES} QVTK)
else()
target_link_libraries(RenderWindowNoUiFile ${VTK_LIBRARIES})
endif()
else()
target_link_libraries(RenderWindowNoUiFile vtkHybrid QVTK vtkViews ${QT_LIBRARIES})
endif()
endif()
Error:
CMake Error at C:/Program Files (x86)/CMake/share/cmake-3.2/Modules/FindQt4.cmake:1326 (message):
Found unsuitable Qt version "" from NOTFOUND, this code requires Qt 4.x
Call Stack (most recent call first):
CMakeLists.txt:18 (find_package)

CMake tests fails but if just run testing executable so everything is ok

I'm using mingw (4.9.1) that was stored with last Qt official build. CMake version is 3.1.2. The situation is when i called make test so i got failed tests with exceptions, but, if i just run this test *.exe by manually — everything is ok, tests running!
What can be wrong?
And yes, I checked the libs its liked with...
There are these files...
CMakeLists.txt:
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
CMAKE_POLICY(SET CMP0020 NEW)
#ENABLE_TESTING( true )
SET( CMAKE_AUTOMOC ON )
SET( CMAKE_INCLUDE_CURRENT_DIR ON )
SET(CMAKE_PREFIX_PATH $ENV{QTDIR})
FIND_PACKAGE( Qt5Core REQUIRED )
FIND_PACKAGE( Qt5Test REQUIRED )
ADD_EXECUTABLE( coretest coretest.cpp )
ADD_TEST( coretest coretest )
QT5_USE_MODULES( coretest Core Test )
TARGET_LINK_LIBRARIES( coretest ${QT_LIBRARIES} )
And single test code file (coretest.cpp):
#include <QTest>
class Coretest : public QObject {
Q_OBJECT
private slots:
void t1();
};
void Coretest::t1()
{
QVERIFY(true);
}
QTEST_MAIN(Coretest)
#include "coretest.moc"
Well, I've got the solution. Just forget to check Path var...

QT Plugin with CMake

Greetings all,
I am trying to implement a QT Plugin with CMake. But this "Q_EXPORT_PLUGIN2" directive stops my class from compiling. I can compile the plugin if I commented this out,but it won't work as a plugin if I do so.
QT doc says:
Q_EXPORT_PLUGIN2 ( PluginName, ClassName )
The value of PluginName should
correspond to the TARGET specified in
the plugin's project file
What about in CMake case? What should be the value for 'PluginName'?
Here is my Plugin Interface :
#ifndef RZPLUGIN3DVIEWERFACTORY_H_
#define RZPLUGIN3DVIEWERFACTORY_H_
#include <QObject>
#include "plugin/IRzPluginFactory.h"
class RzPlugin3DViewerFactory :public QObject,public IRzPluginFactory{
Q_OBJECT
Q_INTERFACES(IRzPluginFactory)
private:
QString uid;
public:
RzPlugin3DViewerFactory();
virtual ~RzPlugin3DViewerFactory();
IRzPlugin* createPluginInstance();
IRzPluginContext* createPluginContextInstance();
QString & getPluginUID();
};
#endif /* RZPLUGIN3DVIEWERFACTORY_H_ */
And implementation
#include "RzPlugin3DViewerFactory.h"
#include "RzPlugin3DViewer.h"
RzPlugin3DViewerFactory::RzPlugin3DViewerFactory() {
uid.append("RzPlugin3DView");
}
RzPlugin3DViewerFactory::~RzPlugin3DViewerFactory() {
// TODO Auto-generated destructor stub
}
IRzPlugin* RzPlugin3DViewerFactory::createPluginInstance(){
RzPlugin3DViewer *p=new RzPlugin3DViewer;
return p;
}
IRzPluginContext* RzPlugin3DViewerFactory::createPluginContextInstance()
{
return NULL;
}
QString & RzPlugin3DViewerFactory::getPluginUID()
{
return uid;
}
Q_EXPORT_PLUGIN2(pnp_extrafilters, RzPlugin3DViewerFactory)
Error Message is :
[ 12%] Building CXX object
CMakeFiles/RzDL3DView.dir/RzPlugin3DViewerFactory.cpp
.obj
C:\svn\osaka3d\trunk\osaka3d\rinzo-platform\src\dlplugins\threedviewer\RzPlugin3
DViewerFactory.cpp:36: error: expected
constructor, destructor, or type
conversi on before '(' token make[2]:
*** [CMakeFiles/RzDL3DView.dir/RzPlugin3DViewerFactory.cpp.obj]
Error 1
make[1]: *
[CMakeFiles/RzDL3DView.dir/all] Error
2 make: * [all] Error 2
Ok , I fixed the problem by giving the project name specified in Cmake file.
PROJECT (RinzoDLPlugin3DViewer CXX C)
So,now in CPP file its
Q_EXPORT_PLUGIN2(RinzoDLPlugin3DViewer , RzPlugin3DViewerFactory)
and included qpluginh.h
#include <qplugin.h>
I think the macro should be Q_EXPORT_PLUGIN2(pnp_rzplugin3dviewerfactory, RzPlugin3DViewerFactory) or whatever you have listed as the target name in the .pro file. In fact, the "pnp" part stands for "Plug & Paint" which is the Qt demo program for writing plugins :)
Edit:
Since I misunderstood how CMake works, this information isn't really relevant to the OP. I did do a quick search however and turned up this discussion of Qt, plugins and CMake. I hope there is some useful info there.
http://lists.trolltech.com/qt-interest/2007-05/msg00506.html

Resources