how to swig omit forward declaration - c++

I am trying to run swig on vendor header so I do not need to redefine the implementation in a separate header file
swig -go -cgo -intgosize 64 -module qt -o $WORK/qt/_obj/qt_wrap.cxx -outdir $WORK/qt/_obj/ \
-I$HOME/Qt5.9.1/5.9.1/gcc_64/include -I$HOME/Qt5.9.1/5.9.1/gcc_64/include/QtOpenGL \
-I$HOME/Qt5.9.1/5.9.1/gcc_64/include/QtWidgets -I$HOME/Qt5.9.1/5.9.1/gcc_64 \
/include/QtGui -I$HOME/Qt5.9.1/5.9.1/gcc_64/include/QtCore -c++ qt.swigcxx
I am getting the error below during go build
$HOME/Qt5.9.1/5.9.1/gcc_64/include/QtWidgets/qapplication.h:57: Error:
Syntax error in input(1).
Upon inspecting
qapplication.h:57
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtCore/qcoreapplication.h>
#include <QtGui/qwindowdefs.h>
#include <QtCore/qpoint.h>
#include <QtCore/qsize.h>
#include <QtGui/qcursor.h>
#ifdef QT_INCLUDE_COMPAT
# include <QtWidgets/qdesktopwidget.h>
#endif
#include <QtGui/qguiapplication.h>
QT_BEGIN_NAMESPACE
class QDesktopWidget;
Obviously fail on the forward declaration.
Below is qt.swigcxx:
// See swig.org for more inteface options,
// e.g. map std::string to Go string
%module qt
%{
#include <QPushButton>
#include <QApplication>
%}
%ignore "";
%include <qapplication.h>
%include <qpushbutton.h>
How can I change so that swig omits the forward declaration?

If you really need to inform SWIG it should ignore something in the source code, you can use the macros it defines: Documentation
So your qapplication.h changes to this:
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtCore/qcoreapplication.h>
#include <QtGui/qwindowdefs.h>
#include <QtCore/qpoint.h>
#include <QtCore/qsize.h>
#include <QtGui/qcursor.h>
#ifdef QT_INCLUDE_COMPAT
# include <QtWidgets/qdesktopwidget.h>
#endif
#include <QtGui/qguiapplication.h>
QT_BEGIN_NAMESPACE
#ifndef SWIG
class QDesktopWidget;
#endif
Be careful with this tactic in general, though, you might end up doing something to make the SWIG preprocessor succeed, but then fail the C++ compilation because you left out something important.
Another approach is to avoid %include altogether (speaking from enterprise experience here). As your project grows large, SWIG will increasingly slow down as a result of including everything from your header files. In the end, just copying the declarations SWIG needs is worth it for the compilation times.

Related

Linux: Conflicts using inotify with fcntl

I'm having a strange linking issue after I included inotify in my program to monitor changes to a filesystem. The project includes <fcntl.h> in many other source files. However, when I include <sys/inotify.h> in the source file which is doing the directory monitoring, I get this error:
/usr/include/fcntl.h:30:1: error: expected initializer before ‘extern’
__BEGIN_DECLS
My project uses CMake, although that doesn't seem to be relevant for finding inotify. It IS finding the inotify declarations to my knowledge, since when I included , it threw an error that inotify_init() and the other functions I used were not defined. Inotify includes fcntl and is partially built on top of some of the functionality there, so my first thought was that it's importing a different version of fcntl than the rest of my program.
In ObjectManager.h:
#ifndef MANAGE_OBJECT_H
#define MANAGE_OBJECT_H
#include "config.h"
//includes all lua headers under extern 'C'
#include <lua.hpp>
#include <list>
#include <unordered_map>
#include <pthread.h>
class ObjectManager //...
The only thing that changed was ObjectManager.cc, with the addition of sys/notify and the implementation of the watcher (not included because this is a linking issue):
#include "config.h"
#include "ObjectManager.h"
#include "Control.h"
#ifdef OBJECT_MANAGER_ENABLED
#include <string.h>
#include <stdio.h>
#include <dirent.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <vector>
#include <unistd.h>
#include <fstream>
#include <sys/inotify.h>
//... inotify implementation
Where Control.h declares #include <fcntl.h>.
This is the closest issue I found, related to some problems in the implementation of different fcntl headers for userspace usage. https://lkml.org/lkml/2008/9/16/98
The same problem occurs on Linux 2.6 running on Centos 6 and Linux 4.0 running on Centos 7.
Any ideas on what is causing this error and how to successfully include inotify?
Resolution: A function definition lacked a semicolon at the END of ObjectManager.h right before a #endif, and the resulting GCC error that propagated through the next includes in a complicated manner, resulting in a strange preprocessor error in fcntl.h.

Why doesn't PRIu64 work in this code?

As per this answer, I tried printing a uint64_t, but it gives me an error:
error: expected ``)' before 'PRIu64'
Following is the minimal code showing what I am trying to do:
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
#include <cstdio>
class X {
X() {
uint64_t foo = 0;
printf("%07" PRIu64 ": ", foo);
}
};
int main() {}
This minimal code compiles, but my actual code does not. However, I have tried with the 2 lines inside X::X() exactly the same in my actual code, and that does not work.
What should I look for to debug this further? My actual code also #includes other headers. Could that be causing the problem? Does order of including the headers matter?
Edit
PRIu64 is defined as follows on my machine:
# if __WORDSIZE == 64
# define __PRI64_PREFIX "l"
# define __PRIPTR_PREFIX "l"
# else
# define __PRI64_PREFIX "ll"
# define __PRIPTR_PREFIX
# endif
# define PRIu64 __PRI64_PREFIX "u"
In C++ the macros are not automatically defined just by including the file.
You need to add the following:
#define __STDC_FORMAT_MACROS 1
before
#include <inttypes.h>
How to printf uint64_t? Fails with: "spurious trailing ‘%’ in format"
One other possibility for this issue I just found in my own code is if another header already pulls in <inttypes.h> before you define __STDC_FORMAT_MACROS. For example:
Utils.h (Perhaps originally written for C, as it was in our case):
#include <inttypes.h>
// ... Function declarations
MyFile.cpp:
#include "Utils.h"
#define __STDC_FORMAT_MACROS
#include <inttypes.h>
Since inttypes.h has already been included by Util.h, the compiler doesn't include it again, and doesn't see the declaration of __STDC_FORMAT_MACROS.
The solution is either to edit Utils.h to include #define __STDC_FORMAT_MACROS, or to make sure to define it before doing any includes in MyFile.cpp.
#define __STDC_FORMAT_MACROS
#include "Utils.h"
#include <inttypes.h>
The original setup actually compiled just fine on GCC 4.8 on Ubuntu, but failed with an old ltib GCC 4.3 toolchain for PowerPC, which made it all the more perplexing at first.
PRIu64 is not defined where you use it.
Replace it with the string "llu" and your code will compile (but that is not a fix, it just demonstrates the problem)
Maybe the include is missing. Maybe over zealos include guards and it being included without the magic token block the define. Maybe your pch is busted.
If you are on android JNI platform. Put this in your Android.mk:
LOCAL_CPPFLAGS := -D__STDC_FORMAT_MACROS

Use of #include <iostream.h>

I am working on an older project that still has the deprecated "#include iostream.h" inclusions. I understand that iostream.h is deprecated and should not be used, but some of the systems that this code has to run/compile on are old solaris machines running CC and do not have iostream available. My question is: how can I make my more modern g++ compiler accept the iostream.h inclusions.
EDIT: The compilier cannot find the iostream.h file so I am assuming that none of the .h versions of the library are available to g++.
The easiest solution is probably to create a local header file called iostream.h which just includes <iostream> and imports the namespace std. Then, in order for the compiler to allow #include <iostream.h> you add the local path to your include file search path. For g++, this works:
g++ -I local_folder [other flags] …
Incidentally, your remark about
… the deprecated "#include iostream.h"
isn’t quite correct: this isn’t deprecated because it has never been legal C++.
I'd take a step back and write another intermediate header you use everywhere instead that does something like:
#if defined(sun) || defined(__sun)
# if defined(__SVR4) || defined(__svr4__)
/* Solaris */
#include <iostream>
# else
/* SunOS */
#include "iostream.h"
# endif
#else
/* Sane, modern system */
#include <iostream>
#endif

Glew Linking Problems in Qt Creator?

I'm trying to link GLEW (with SDL and OpenGL - note, not SDL's implementation of OpenGL) in Qt Creator via a QMake file, though I'm not having much luck. No matter what I try, I seem to get the same string errors which deals with conflicting declaration problems stemming from a few typedefs. What I'd like to know is why this is happening, along with what can be done about it.
Example
/usr/include/SDL/SDL_opengl.h:4855: error: conflicting declaration ‘typedef void (* PFNGLFRAGMENTLIGHTFVSGIXPROC)(GLenum, GLenum, const GLfloat*)’
/usr/include/GL/glew.h:12201: error: ‘PFNGLFRAGMENTLIGHTFVSGIXPROC’ has a previous declaration as ‘typedef void (* PFNGLFRAGMENTLIGHTFVSGIXPROC)(GLenum, GLenum, GLfloat*)’
Is this because I'm linking with SDL (seeing as how it has OpenGL support), or is there something else going on here?
Qmake File
QT += core
LIBS += -lSDL -lSDL_image -lopengl32 -lGLU -lGLEW
stdafx.h
#pragma once
/*************/
/* #includes */
/*************/
//GL / SDL
#include <GL/glew.h>
#define GLEW_STATIC
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glext.h>
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
//STD
#include <iostream>
#include <fstream>
//Qt
#include <QListIterator>
#include <QMapIterator>
#include <QVector4D>
#include <QColor>
/********************/
/* Using Statements */
/********************/
using std::cout;
using std::endl;
using std::cin;
using std::fstream;
stdafx.cpp
#define GL_GLEXT_PROTOTYPES
The only solution to your problem is not to use one (either GLEW, or SDL_opengl), or at least do not include both GL/glew.h and SDL/SDL_opengl.h headers in any source or header file.
I have had similar issues before which we "solved" by defining NO_SDL_GLEXT before the inclusion of <SDL/SDL_opengl.h>, so:
#define NO_SDL_GLEXT
#include <SDL/SDL_opengl.h>
I say "solved", because it made the errors go away, but I never investigated possible side-effects or problems (we ended up moving away from SDL shortly after that and never really used it anymore). Perhaps worth a try...

Syntax errors in C++ include file

I'm writing a game in c++ in microsoft visual studio 2010, yesterday I wrote a pong game and everything was fine but now the compiler telling me that there is a lot of errors for example:
1>w:\c++\planet escape\planet escape\room.h(25): error C2061: syntax error : identifier 'WorldMap'
And here is the Room.h file:
#pragma once
#include <allegro5/allegro.h>
#include <vector>
#include "Entity.h"
#include "WorldMap.h"
#include "Link.h"
#define ROOM_W 20
#define ROOM_H 20
class Room{
private:...
public:...
};
When in code there is no mistakes and it sees all the classes fine.
So what can cause such mistake?
EDIT:
here is the WorldMap.h
#pragma once
#include <allegro5/allegro.h>
#include "Room.h"
#include "Player.h"
#define WORLD_W 10
#define WORLD_H 10
class WorldMap{
private:...
public:...
};
If when I'm runing it he cant see it then why he see it when coding?
You have circular includes. Suppose you are compiling a file that has a #include "WorldMap.h" as the first applicable #include statement. The file WorldMap.h has that #include "Room.h" that is going to cause a lot of trouble. The problems start in earnest in Room.h at the #include "WorldMap.h" statement. That #include has no effect thanks to the #pragma once in WorldMap.h. When the compiler gets to the point of processing the main body of Room.h, the class WorldMap is neither defined nor declared.
Addendum
The solution is to get rid of those extraneous #include statements. The file WorldMap.h does not need to #include either of Room.h or Player.h. It instead needs to make forward declarations of the classes Room and Player. Similarly, you don't need all those #include statements in Room.h either.
It is in general a good idea to use forward declarations of types in your headers instead of including the file that defines the types. If the code in the header does not need to know details of the type in question, just use a forward declaration. Do not #include the header that defines the type.