drhalftone/LAUCalTagWidget

Build woes on Raspbian

UberEclectic opened this issue · 8 comments

Hello, Dr. Lau.
I am attempting to build on the latest Raspian.
Out of the box I get:

$ qmake
$ make
g++ -c -pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG_OUTPUT -DQT_NO_DEBUG -DQT_MULTIMEDIAWIDGETS_LIB -DQT_MULTIMEDIA_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -I../../include/opencv4 -I../../../include/arm-linux-gnueabihf/qt5 -I../../../include/arm-linux-gnueabihf/qt5/QtMultimediaWidgets -I../../../include/arm-linux-gnueabihf/qt5/QtMultimedia -I../../../include/arm-linux-gnueabihf/qt5/QtOpenGL -I../../../include/arm-linux-gnueabihf/qt5/QtWidgets -I../../../include/arm-linux-gnueabihf/qt5/QtGui -I../../../include/arm-linux-gnueabihf/qt5/QtNetwork -I../../../include/arm-linux-gnueabihf/qt5/QtCore -I. -I../../../lib/arm-linux-gnueabihf/qt5/mkspecs/linux-g++ -o laumemoryobject.o laumemoryobject.cpp
In file included from laumemoryobject.cpp:33:0:
laumemoryobject.h:37:23: fatal error: emmintrin.h: No such file or directory
 #include "emmintrin.h"
                       ^
compilation terminated.
Makefile:2614: recipe for target 'laumemoryobject.o' failed
make: *** [laumemoryobject.o] Error 1

The #include file has a clause:

#ifndef Q_PROCESSOR_ARM
#include "emmintrin.h"
#endif

So it appears that something about the project hierarchy isn't inheriting the #define for Q_PROCESSOR_ARM.

As a workaround, I tried the following but there is a warning followed later by a fatal error:

$ qmake DEFINES+="__ARM_ARCH=6 Q_PROCESSOR_ARM=__ARM_ARCH"
$ make

The warning:

g++ -c -pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -D__ARM_ARCH=6 -DQ_PROCESSOR_ARM=__ARM_ARCH -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG_OUTPUT -DQT_NO_DEBUG -DQT_MULTIMEDIAWIDGETS_LIB -DQT_MULTIMEDIA_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -I../../include/opencv4 -I../../../include/arm-linux-gnueabihf/qt5 -I../../../include/arm-linux-gnueabihf/qt5/QtMultimediaWidgets -I../../../include/arm-linux-gnueabihf/qt5/QtMultimedia -I../../../include/arm-linux-gnueabihf/qt5/QtOpenGL -I../../../include/arm-linux-gnueabihf/qt5/QtWidgets -I../../../include/arm-linux-gnueabihf/qt5/QtGui -I../../../include/arm-linux-gnueabihf/qt5/QtNetwork -I../../../include/arm-linux-gnueabihf/qt5/QtCore -I. -I../../../lib/arm-linux-gnueabihf/qt5/mkspecs/linux-g++ -o laumemoryobject.o laumemoryobject.cpp
laumemoryobject.cpp: In copy constructor ‘LAUMemoryObjectData::LAUMemoryObjectData(const LAUMemoryObjectData&)’:
laumemoryobject.cpp:111:1: warning: base class ‘class QSharedData’ should be explicitly initialized in the copy constructor [-Wextra]
 LAUMemoryObjectData::LAUMemoryObjectData(const LAUMemoryObjectData &other)
 ^~~~~~~~~~~~~~~~~~~

The fatal error:

g++ -c -pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -D__ARM_ARCH=6 -DQ_PROCESSOR_ARM=__ARM_ARCH -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG_OUTPUT -DQT_NO_DEBUG -DQT_MULTIMEDIAWIDGETS_LIB -DQT_MULTIMEDIA_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -I../../include/opencv4 -I../../../include/arm-linux-gnueabihf/qt5 -I../../../include/arm-linux-gnueabihf/qt5/QtMultimediaWidgets -I../../../include/arm-linux-gnueabihf/qt5/QtMultimedia -I../../../include/arm-linux-gnueabihf/qt5/QtOpenGL -I../../../include/arm-linux-gnueabihf/qt5/QtWidgets -I../../../include/arm-linux-gnueabihf/qt5/QtGui -I../../../include/arm-linux-gnueabihf/qt5/QtNetwork -I../../../include/arm-linux-gnueabihf/qt5/QtCore -I. -I../../../lib/arm-linux-gnueabihf/qt5/mkspecs/linux-g++ -o laucaltagglobject.o laucaltagglobject.cpp
laucaltagglobject.cpp: In member function ‘void LAUCalTagGLObject::processGL(QOpenGLTexture*, QOpenGLFramebufferObject*)’:
laucaltagglobject.cpp:536:114: error: ‘glGetTexImage’ was not declared in this scope
         glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, (unsigned char *)memoryObject[0].constPointer());
                                                                                                                  ^
laucaltagglobject.cpp: In member function ‘std::vector<std::vector<cv::Point_<float> > > LAUCalTagGLObject::quadArea(cv::Mat, int, int)’:
laucaltagglobject.cpp:1149:60: error: ‘CV_RETR_TREE’ was not declared in this scope
     cv::findContours(sbImage.clone(), contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cv::Point(0, 0));
                                                            ^~~~~~~~~~~~
laucaltagglobject.cpp:1149:74: error: ‘CV_CHAIN_APPROX_NONE’ was not declared in this scope
     cv::findContours(sbImage.clone(), contours, hierarchy, CV_RETR_TREE, CV_CHAIN_APPROX_NONE, cv::Point(0, 0));
                                                                          ^~~~~~~~~~~~~~~~~~~~
laucaltagglobject.cpp: In member function ‘LAUMemoryObject LAUCalTagGLObject::grabImage()’:
laucaltagglobject.cpp:1944:80: error: ‘glGetTexImage’ was not declared in this scope
         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_FLOAT, object.constPointer());
                                                                                ^
Makefile:4188: recipe for target 'laucaltagglobject.o' failed
make: *** [laucaltagglobject.o] Error 1

Could this be related to the OpenCV version?
I am using OpenCV4, which has its own compatibility includes for OpenCV2.
I hope that is not the issue, since I need to keep a consistent OpenCV version for GTK3 reasons.

Please advise.

I found the missing values are available as defines in another include file, "opencv2/imgproc/types_c.h" which I have added to the laucaltagglobject.h, after the related ones, as shown:

$ grep opencv2 laucaltagglobject.h
#include "opencv2/core/core.hpp"
#include "opencv2/calib3d/calib3d.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include "opencv2/imgproc/types_c.h"

Now there is a new error:

g++ -c -pipe -O2 -std=gnu++11 -Wall -W -D_REENTRANT -fPIC -D__ARM_ARCH=6 -DQ_PROCESSOR_ARM=__ARM_ARCH -DQT_DEPRECATED_WARNINGS -DQT_NO_DEBUG_OUTPUT -DQT_NO_DEBUG -DQT_MULTIMEDIAWIDGETS_LIB -DQT_MULTIMEDIA_LIB -DQT_OPENGL_LIB -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_NETWORK_LIB -DQT_CORE_LIB -I. -I../../include/opencv4 -I../../../include/arm-linux-gnueabihf/qt5 -I../../../include/arm-linux-gnueabihf/qt5/QtMultimediaWidgets -I../../../include/arm-linux-gnueabihf/qt5/QtMultimedia -I../../../include/arm-linux-gnueabihf/qt5/QtOpenGL -I../../../include/arm-linux-gnueabihf/qt5/QtWidgets -I../../../include/arm-linux-gnueabihf/qt5/QtGui -I../../../include/arm-linux-gnueabihf/qt5/QtNetwork -I../../../include/arm-linux-gnueabihf/qt5/QtCore -I. -I../../../lib/arm-linux-gnueabihf/qt5/mkspecs/linux-g++ -o laucaltagglobject.o laucaltagglobject.cpp
laucaltagglobject.cpp: In member function ‘void LAUCalTagGLObject::processGL(QOpenGLTexture*, QOpenGLFramebufferObject*)’:
laucaltagglobject.cpp:536:114: error: ‘glGetTexImage’ was not declared in this scope
         glGetTexImage(GL_TEXTURE_2D, 0, GL_RED, GL_UNSIGNED_BYTE, (unsigned char *)memoryObject[0].constPointer());
                                                                                                                  ^
laucaltagglobject.cpp: In member function ‘LAUMemoryObject LAUCalTagGLObject::grabImage()’:
laucaltagglobject.cpp:1944:80: error: ‘glGetTexImage’ was not declared in this scope
         glGetTexImage(GL_TEXTURE_2D, 0, GL_RGB, GL_FLOAT, object.constPointer());
                                                                                ^
Makefile:4188: recipe for target 'laucaltagglobject.o' failed
make: *** [laucaltagglobject.o] Error 1

In the same laucaltagglobject.h, there are some OpenGL related includes already:

#include <QOpenGLBuffer>
#include <QOpenGLTexture>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLFramebufferObject>

I do find glGetTexImage defined, here, but I am reluctant to add it explicitly, as I would hope to stick with the qmake-derived includes. FWIW, here is where I found the define.

/usr/include/GL/gl.h

And the relevant lines are as follows:

GLAPI void GLAPIENTRY glGetTexImage( GLenum target, GLint level,
                                     GLenum format, GLenum type,
                                     GLvoid *pixels );

Can you please advise what is the recommended resolution?

Dr. Lau,
This is certainly not urgent.
I'll keep digging to find the missing OpenGL-related include.

I found an answer as to why the code doesn't build when using the OOB Raspbian OpenGL:

$ glxinfo | grep -i version
server glx version string: 1.4
client glx version string: 1.4
GLX version: 1.4
    Version: 13.0.6
    Max core profile version: 0.0
    Max compat profile version: 2.1
    Max GLES1 profile version: 1.1
    Max GLES[23] profile version: 2.0
OpenGL version string: 2.1 Mesa 13.0.6
OpenGL shading language version string: 1.20
OpenGL ES profile version string: OpenGL ES 2.0 Mesa 13.0.6
OpenGL ES profile shading language version string: OpenGL ES GLSL ES 1.0.16

And according to the following post, OpenGL ES 2 doesn't include an implementation of glGetTexImage():

StackOverflow: opengl es 2.0 android c++ glGetTexImage alternative

SOLUTION: Will either need to re-write the code, or build the full desktop version of OpenGL.

Hey, Dr. Lau.

On RPI, I figured that crafting an alternate version of glGetTexImage() might be easier than making the full desktop version of OpenGL work. I do have a prototype of the code, but am facing an unrelated 4VL2 issue. I've ordered a new camera. As soon as I can actually test the code (and further remediate if need be), then I will submit a pull request for the change.
I have #ifdef QT_OPENGL_ES_2 // #endif around my changes, so people with full OpenGL desktop version will get the actual glGetTexImage().
I'll let you know when I have the enhancement ready. =D