I am trying to get a project working with SDL2, assimp, opengl, and glew and cannot get glew to link properly (almost a duplicate but a more comprehensive question and answer, I think).
My qmake .pro file :
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
HEADERS += \
objloader.h \
display.h \
eventloop.h \
shader.h \
texture.h
SOURCES += main.cpp \
objloader.cpp \
display.cpp \
eventloop.cpp \
shader.cpp \
texture.cpp
INCLUDEPATH += "C:/code middleware/glew-1.12.0/include/" \
"C:\code middleware\glm\\" \
"C:\code middleware\SDL2-2.0.3\include\\" \
"C:\Users\smart_000\Desktop\assimp\include\\"
DEPENDPATH += "C:/code middleware/glew-1.10.0/bin/Release\Win32/" \
"C:\code middleware\SDL2-2.0.3\lib/x86/" \
"C:/Users/smart_000/Desktop/assimp/bin/" \
"C:/code middleware/glew-1.12.0/lib/Release/Win32/" \
"C:/code middleware/glew-1.12.0/bin/Release/Win32/"
LIBS += -L"C:\code middleware\SDL2-2.0.3\lib\x86" -lSDL2main -lSDL2
LIBS += -L"C:/Users/smart_000/Desktop/assimp/lib/" -lassimp.dll -lzlib
LIBS += -lopengl32
LIBS += -lglu32
LIBS += -L"C:/code middleware/glew-1.12.0/lib/Release/Win32/" -lglew32 -lglu32
The linker errors I am getting: linker errors
What I have tried already:
Checking file path problems ('/' and '\' kind of stuff and spaces in file names etc.)
Linking dynamically and statically (Yes, I defined GLEW_STATIC where I needed to, and I linked to -lglew32s and such)
SDL stuff: messing with and defining 'NO_SDL_GLEXT' above it
Making test programs and trying to link it with just g++ (I used the -static flag where I should have when I tried the static one and placed the linker flags after the files that needed them). These errors were the same as the qt ones minus the warnings.
Putting the glew source code directly in my project and building it (exact same errors) --- The issues were eerily similar and made no sense to me. I had commented out the qmake stuff and re ran qmake; I wasn't aware I could get linker errors like that if I put it in my project like I did.
Running qmake after my changes, lol
Moving 'LIBS' and 'DEPENDPATH' around and added 'CONFIG += opengl' in desperation
Messing with debug and release builds.
What I haven't tried:
Moving libraries and things to the system path
MAKING SURE THE LIBRARIES WERE BUILT FOR MINGW!
The relevant code(I know it's terrible; I was just hacking around when I encountered these issues) :
"main.cpp" :
#include <GL/glew.h>
#include <iostream>
#include <SDL.h>
#include <objloader.h>
#include "display.h"
#include "eventloop.h"
Display* display = NULL;
void callback()
{
std::cout << "yay" << std::endl;
display->Swap();
}
int main(int argc, char* argv[])
{
UShortVector indices;
Vec3Vector vertices;
Vec2Vector uvs;
Vec3Vector normals;
bool success = ObjLoader::loadObj("cube.obj", indices, vertices, uvs, normals);
display = new Display();
EventLoop eventLoop;
eventLoop.SetLoopCallback(&callback);
display->Create("yay");
eventLoop.Start();
return 0;
}
"display.h"
#ifndef DISPLAY_H
#define DISPLAY_H
#include <GL/glew.h>
#include <SDL.h>
#include <iostream>
class Display
{
public:
Display();
~Display();
void Create(const char* title);
void Swap();
SDL_Window* window_ = NULL;
SDL_GLContext glContext_;
};
#endif // DISPLAY_H
"shader.h"
#ifndef SHADER_H
#define SHADER_H
#include <GL/glew.h>
#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <memory.h>
class Shader
{
public:
GLuint LoadShaders(const char * vertex_file_path, const char * fragment_file_path);
private:
Shader();
~Shader();
};
#endif // SHADER_H
"shader.cpp"
#include "shader.h"
Shader::Shader()
{
}
Shader::~Shader()
{
}
GLuint Shader::LoadShaders(const char * vertexShaderPath, const char * fragmentShaderPath)
{
FILE* vertexFile = fopen(vertexShaderPath, "r");
FILE* fragmentFile = fopen(fragmentShaderPath, "r");
if(!vertexFile || !fragmentFile)
{
if(!vertexFile)
{
perror("could not open the vertex shader file");
}
if(!fragmentFile)
{
perror("could not open the fragment shader file");
}
}
GLuint programID = glCreateProgram();
GLuint vertShader = glCreateShader(GL_VERTEX_SHADER);
GLuint fragShader = glCreateShader(GL_FRAGMENT_SHADER);
const size_t MAX_LINE_LENGTH = 120;
char line[MAX_LINE_LENGTH];
std::vector<GLchar*> vertShaderSource;
std::vector<GLchar*> fragmentShaderSource;
while(fgets(line, MAX_LINE_LENGTH, vertexFile) != NULL)
{
vertShaderSource.push_back((GLchar*)line);
memset((void*)line, '\0', sizeof(line));
}
while(fgets(line, MAX_LINE_LENGTH, fragmentFile) != NULL)
{
fragmentShaderSource.push_back((GLchar*)line);
memset((void*)line, '\0', sizeof(line));
}
glShaderSource(vertShader, vertShaderSource.size(), (const GLchar**)&vertShaderSource, NULL);
glShaderSource(fragShader, fragmentShaderSource.size(), (const GLchar**)&fragmentShaderSource, NULL);
// doesn't do anything at the moment, I know. It should still compile though.
return programID;
}
Right after I posted the question, I found the issue. Embarrassingly, it was an issue I have run into before with assimp (although I just now realized why re-building it with cmake worked).
The hallmarks:
Weird linker errors with a library when you know the library is being found.
You primarily work on a windows system :)
The solution:
Check the build kit that you are using with Qt creator Vs. the libs you are using.
I was using the MINGW one only and my libs were compiled using the MSVC++ compiler
The libs you are looking for are .a files: specifically lib{name}.a . In this case, I was looking for libglew32.dll.a <- note the .dll in there for whether it is a dll import library or a static one like libglew32s.a <- note the s for static.
Where to go to get the rights libs :
- Go here for building it: Building glew on windows with mingw.
- Go here to download the pre-built one that I did (older version of glew): https://launchpad.net/glew-cmake/+milestone/1.10.0
The Download link that I used: glew-gcc-1.10.0-win32.zip (md5) Glew-Cmake 1.10.0 Binaries (MinGW) <- I tried to post a picture, but apparently, I am not cool enough to do that yet.
My updated and working qmake .pro file :
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
HEADERS += \
objloader.h \
display.h \
eventloop.h \
shader.h \
texture.h
SOURCES += main.cpp \
objloader.cpp \
display.cpp \
eventloop.cpp \
shader.cpp \
texture.cpp
INCLUDEPATH += "C:/code middleware/glew-gcc-1.10.0-win32/include/" \
"C:/code middleware/glm/" \
"C:/code middleware/SDL2-2.0.3/include/" \
"C:/Users/smart_000/Desktop/assimp/include/"
DEPENDPATH += "C:/code middleware/SDL2-2.0.3/lib/x86/" \
"C:/Users/smart_000/Desktop/assimp/bin/" \
"C:/code middleware/glew-gcc-1.10.0-win32/lib/" \
"C:/code middleware/glew-gcc-1.10.0-win32/bin/"
LIBS += -L"C:/code middleware/SDL2-2.0.3/lib/x86" -lSDL2main -lSDL2
LIBS += -L"C:/Users/smart_000/Desktop/assimp/lib/" -lassimp.dll -lzlib
LIBS += -L"C:/code middleware/glew-gcc-1.10.0-win32/lib/" -lglew32.dll
LIBS += -lopengl32
LIBS += -lglu32
Note: Don't forget the .dll on the end of the libs (-lglew32.dll).
- Happy Linking!
Related
Before asking the problem, I would like to tell that i have thoroughly searched for the answer here. None of them seems to address my issue.
Problem:
I have created a simple C++ DLL file using Qt after following steps given on the Qt wiki the problem is though the DLL is created and I have linked it to my Qt widget app, the app crashes on creating the object of the file.
Here I am posting the source code and the qdebug output
libraray Qt pro
QT += core gui widgets
TARGET = myLib
TEMPLATE = lib
DEFINES += MYLIB_LIBRARY
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
mylib.cpp
HEADERS += \
mylib.h \
mylib_global.h
unix {
target.path = /usr/lib
INSTALLS += target
}
mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#include "mylib_global.h"
class MYLIBSHARED_EXPORT MyLib
{
public:
MyLib();
int add(int x, int y);
int sub(int x, int y);
};
#endif // MYLIB_H
mylib_global.h
#ifndef MYLIB_GLOBAL_H
#define MYLIB_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(MYLIB_LIBRARY)
# define MYLIBSHARED_EXPORT Q_DECL_EXPORT
#else
# define MYLIBSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // MYLIB_GLOBAL_H
mylib.cpp
#include "mylib.h"
#include<QDebug>
MyLib::MyLib()
{
}
int MyLib::add(int x, int y)
{
qDebug()<<"Adding";
return x+y;
}
int MyLib::sub(int x, int y)
{
return x-y;
}
Now the app
myWidgetApp.pro
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = myWidgetApp
TEMPLATE = app
DEFINES += QT_DEPRECATED_WARNINGS
SOURCES += \
main.cpp \
mainwindow.cpp
HEADERS += \
mainwindow.h
FORMS += \
mainwindow.ui
INCLUDEPATH += "D:\Gurushant\My Other Side Projects\Making dll Files\myLib"
LIBS += "D:\Gurushant\My Other Side Projects\Making dll Files\build-myLib-Desktop_Qt_5_9_1_MinGW_32bit-Release\release\myLib.dll"
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include"mylib.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
MyLib lib;
lib.add(1,2);
}
MainWindow::~MainWindow()
{
delete ui;
}
Now the application output
D:\Gurushant\My Other Side Projects\Making dll Files\build-myWidgetApp-Desktop_Qt_5_9_1_MinGW_32bit-Release\release\myWidgetApp.exe crashed.
I am using Windows 7 Professional with Qt 5.9.1
So far after doing a lot of trial and error, the best way to include the library is to
INCLUDEPATH += (Your_Path)
DEPENDPATH += (Your Path)
(if your target path is win32)
win32:CONFIG(release, debug|release): LIBS += -L(path) -l(lib_file_without_dot_dll)
don't use space after -L
I am trying to read a mat-file in an own mat_file_read.cpp in a Qt project, and I am having problems. My error:
error lnk2019: unresolved external symbol matOpen referenced in function "int __cdecl read_mat_file(class QString)" (?read_mat_file##YAHVQString###Z)"
In my project.pro, I am including:
INCLUDEPATH += C:\Program Files\MATLAB\MATLAB Production Server\R2015a\extern\include\
LIBS += -LC:\Program Files\MATLAB\MATLAB Production Server\R2015a\bin\win64
-llibmx
-llibmat
-llibeng
In the header of my cpp file:
#include <stdio.h>
#include <stdlib.h>
#include "mat.h"
#include "matrix.h"
#include <QString>
#include <QFileDialog>
In my mat_file_reader.cpp:
#include "read_mat_file.h"
int read_mat_file(QString file)
{
// Variable definition
int result;
MATFile *pmat;
if (file.isEmpty()) return 0;
QByteArray ba = file.toLatin1();
const char *rootFile = ba.data();
pmat = matOpen(rootFile,"r");
result = 0;
return (result==0)?EXIT_SUCCESS:EXIT_FAILURE;
}
And the curious thing is the Qt editor is recognizing the functions from "mat.h". It is suggesting me the functions....
Thanks so much in advance.
I think maybe it's because you forget your \ in the end of your lines.
And also, maybe you need to avoid having spaces in your path, or try putting it in $$quote(), like the following:
INCLUDEPATH += $$quote(C:/Program Files/MATLAB/MATLAB Production Server/R2015a/extern/include)
LIBS += -L$$quote(C:/Program Files/MATLAB/MATLAB Production Server/R2015a/bin/win64) \
-llibmx \
-llibmat \
-llibeng
Finally I found a solution, although I don't understand fine why.... I only changed the next lines in my project.pro of Qt:
INCLUDEPATH += C:\Program Files\MATLAB\MATLAB Production Server\R2015a\extern\include\
LIBS += -llibmx -LC:\librerias\matlab\extern\lib\win64\microsoft
LIBS += -llibmat -LC:\librerias\matlab\extern\lib\win64\microsoft
LIBS += -llibeng -LC:\librerias\matlab\extern\lib\win64\microsoft
Now it is working.... It's strange I think, but for me It's ok. :)
Thanks so much #Suever for the support.
I have been trying to use OpenCV with Qt Creator, but I had no success. I read lot of forums but none helped.
Here is my code:
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <qDebug>
#include <QCoreApplication>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
cv::Mat image = cv::imread("lol.jpg");
cv::namedWindow("MyImage",45);
cv::imshow("MyImage",image);
qDebug()<<"TEST-OCV-1";
cv::waitKey(1000);
return a.exec();
}
My .pro File
QT += core
QT -= gui
TARGET = ocv1
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp
INCLUDEPATH += F:/OpenCV/opencv/build/include
LIBS += -LF:/OpenCV/opencv/build/x64/vc12/bin \
-llibopencv_core240d \
-llibopencv_highgui240d \
-llibopencv_imgproc240d \
-llibopencv_features2d240d \
-llibopencv_calib3d240d \
I have also tried including the libs like
LIBS += -LF:/OpenCV/opencv/build/x64/vc12/lib \
-lopencv_core249 \
-lopencv_highgui249 \
-lopencv_imgproc249 \
-lopencv_features2d249 \
-lopencv_calib3d249 \
And
LIBS += -LF:/OpenCV/opencv/build/x64/vc12/lib \
-lopencv_core249 \
-lopencv_highgui249 \
-lopencv_imgproc249 \
-lopencv_features2d249 \
-lopencv_calib3d249 \
But I keep getting this error, though a command prompt starts it just as the text press enter to exit.
Starting C:\Qt\Qt5.2.0\Tools\QtCreator\bin\build-ocv1-Desktop_Qt_5_2_0_MSVC2012_64bit-Debug\debug\ocv1.exe...
C:\Qt\Qt5.2.0\Tools\QtCreator\bin\build-ocv1-Desktop_Qt_5_2_0_MSVC2012_64bit-Debug\debug\ocv1.exe exited with code -1073741515
I have about 15 errors, when I want to get a video capture to view it frame by frame in an image.
First I call my video from my link.
Then get from it my frame.
Then convert it into image.
Finally view it in pixmap.
MY CODE
#include "form1.h"
#include "ui_form1.h"
#include <QtCore>
#include <QtGui>
#include <QGraphicsAnchorLayout>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsWidget>
#include "qimage.h"
#include <QFileDialog>
#include <QPixmap>
#include "qpixmap.h"
Form1::Form1(QWidget *parent) :
QDialog(parent),
ui(new Ui::Form1)
{
ui->setupUi(this);
video->open("D:/Downloads/DirectX/Zlatan Ibrahimovic ● Taekwondo Goals.mp4");
timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(updatePicture()));
timer->start(20);
}
QString fileName;
QImage Form1::getQImageFromFrame(cv::Mat frame) {
//converts the color model of the image from RGB to BGR because OpenCV uses BGR
cv::cvtColor(frame, frame, CV_RGB2BGR);
return QImage((uchar*) (frame.data), frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
}
Form1::~Form1()
{
delete ui;
}
void Form1::updatePicture()
{
cv::Mat frame1;
video->operator >>( frame1);
img = getQImageFromFrame(frame1);
ui->label->setPixmap(QPixmap::fromImage(img));
}
void Form1::on_pushButton_clicked()
{
//fileName = QFileDialog::getOpenFileName(this,
//tr("Open Image"), "/elhandasya/Desktop", tr("Image Files (*.png *.jpg *.bmp)"));
//QPixmap pix(fileName);
}
'
The errors like this:
undefined reference to `cv::Mat::Mat()
D:\ubunto\QT5\Tools\QtCreator\bin\Video_Player-build-Desktop_Qt_5_0_1_MinGW_32bit-Debug\debug\form1.o:-1: In function `ZN5Form1D2Ev'
My LIBS
#-------------------------------------------------
#
# Project created by QtCreator 2013-12-16T09:23:28
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = Video_Player
TEMPLATE = app
SOURCES += main.cpp\
form1.cpp
HEADERS += form1.h
FORMS += form1.ui
INCLUDEPATH += -I"D:/ubunto/OpenCV/opencv/build/include/opencv2/imgproc"
INCLUDEPATH += -I"D:/ubunto/OpenCV/opencv/build/include/"
#INCLUDEPATH += "D:/ubunto/OpenCV/opencv/build/include/"
LIBS += -LD:/ubunto/OpenCV/opencv/build/x86/mingw/bin
-lopencv_core
-lopencv_imgproc
-lopencv_highgui
-lopencv_legacy
-lopencv_gpu
-lopencv_video
-lopencv_ml
-lopencv_contrib
#LIBS += D:\ubunto\emgu\emgucv-windows-x86 2.4.0.1717\lib
#-opencv_calib3d240
#-opencv_videostab240
#-opencv_calib3d240
#-opencv_contrib240
#-opencv_core240
#-opencv_features2d240
#-opencv_flann240
#-opencv_gpu240
#-opencv_highgui240
#-opencv_imgproc240
#-opencv_legacy240
#-opencv_ml240
#-opencv_nonfree240
#-opencv_objdetect240
#-opencv_photo240
#-opencv_stitching240
#-opencv_video240
If you take a look at the source code of cvVideo (an application that shows how to create a Qt window to display videos loaded with OpenCV) you can see how to achieve what you are looking for.
cvVideo.pro:
TEMPLATE = app
QT += core gui
contains(QT_VERSION, ^5\\.[0-8]\\..*) {
message("* Using Qt $${QT_VERSION}.")
QT += widgets
# On my system I have to specify g++ as compiler else it will use clang++ by default
#QMAKE_CXX=g++
#QMAKE_CC=gcc
}
HEADERS += \
cvWindow.h
SOURCES += \
main.cpp \
cvWindow.cpp
## OpenCV settings for Unix/Linux
unix:!mac {
message("* Using settings for Unix/Linux.")
INCLUDEPATH += /usr/local/include/opencv
LIBS += -L/usr/local/lib/ \
-lopencv_core \
-lopencv_highgui \
-lopencv_imgproc
}
## OpenCV settings for Mac OS X
macx {
message("* Using settings for Mac OS X.")
INCLUDEPATH += /usr/local/include/opencv
LIBS += -L/usr/local/lib/ \
-lopencv_core \
-lopencv_highgui \
-lopencv_imgproc
}
## OpenCV settings for Windows and OpenCV 2.4.2
win32 {
message("* Using settings for Windows.")
INCLUDEPATH += "C:\\opencv\\build\\include" \
"C:\\opencv\\build\\include\\opencv" \
"C:\\opencv\\build\\include\\opencv2"
LIBS += -L"C:\\opencv\\build\\x86\\vc10\\lib" \
-lopencv_core242 \
-lopencv_highgui242 \
-lopencv_imgproc242
}
# Runs this app automatically after the building has succeeded
#QMAKE_POST_LINK=./$$TARGET
Error tells you that you have to link, in you makefile, the specific library that include Mat:
-lopencv_core
Take a look at the documentaion.
When there are errors like:
In function `ZN5Form1D2Ev'
It could be that you have two different opencv version installed, isn't it?
As part of my Qt project, I have a WSO2 WSF/C++ module as a webservice.
Now the instructions to build this module are pretty straight-forward in CLI (Windows environment):
To compile:
cl.exe /D "WIN32" /D "_WINDOWS" /D "_MBCS" /D "AXIS2_DECLARE_EXPORT" /D "AXIS2_SVR_MULTI_THREADED" /w /nologo /I %WSFCPP_HOME%\include /c hello.cpp
To link:
link.exe /nologo /LIBPATH:%WSFCPP_HOME%\lib axutil.lib axiom.lib axis2_parser.lib axis2_engine.lib wso2_wsf.lib /DLL /OUT:hello.dll *.obj
In order to automate the build process, I want to integrate these steps to my .pro file. However I have absolutely no idea how to proceed. Any suggestions?
EDIT: Here's my current code:
project.pro
TEMPLATE = lib
CONFIG += dll
CONFIG -= qt
VERSION = 1.0
TARGET = hello
SOURCES += hello.cpp
HEADERS += hello.hpp
DEFINES += AXIS2_DECLARE_EXPORT AXIS2_SVR_MULTI_THREADED
INCLUDEPATH += "C:\wsfcpp\include"
LIBS += \
-L"C:\wsfcpp\lib" -laxutil \
-laxiom \
-laxis2_parser \
-laxis2_engine \
-lwso2_wsf
hello.hpp
#ifndef HELLO_H
#define HELLO_H
#include <ServiceSkeleton.h>
using namespace wso2wsf;
class Hello : public ServiceSkeleton
{
public:
WSF_EXTERN WSF_CALL Hello(){};
OMElement* WSF_CALL invoke(OMElement *message, MessageContext *msgCtx);
OMElement* WSF_CALL onFault(OMElement *message);
void WSF_CALL init();
OMElement* greet(OMElement *inMsg);
};
#endif // HELLO_H
hello.cpp
#include <ServiceSkeleton.h>
#include <iostream>
#include <stdio.h>
#include <axutil_env.h>
#include <Environment.h>
#include <OMText.h>
#include "hello.hpp"
using namespace wso2wsf;
using namespace std;
/** Load the service into axis2 engine */
WSF_SERVICE_INIT(Hello)
OMElement* Hello::invoke(OMElement *ele, MessageContext *msgCtx)
{
return greet(ele);
}
OMElement* Hello::onFault(OMElement *ele)
{
OMElement *responseEle = new OMElement("HelloServiceErrorResponse");
responseEle->setText("Hello Service Failed");
return responseEle;
}
void Hello::init()
{
}
OMElement* Hello::greet(OMElement* inMsg)
{
OMElement *helloEle = new OMElement("greetResponse");
OMElement *text = new OMElement("text");
helloEle->setText(greet);
return helloEle;
}
Create a .pro file like this:
TEMPLATE = lib
TARGET = hello
DEFINES += AXIS2_DECLARE_EXPORT AXIS2_SVR_MULTI_THREADED
SOURCES += hello.cpp
LIBS += -Lpath/to/the/libs -laxutil -laxiom -laxis2_parser -laxis2_engine -lwso2_wsf
and integrate it into your build process. That will require the Qt/qmake you're using to be compiled for MSVC. (but mixing mingw and MSVC inside a single project wouldn't work anyway)