I am trying to turn ovpn3's ovpncli example into a class that derives from QObject. I'm unable to turn the source file into a separate interface (.h) and implementation (.cpp) file. To make the MOC happy, I've put #include "openvpn.moc" at the end of openvpn.cpp (the source file). I am getting this error however: :-1: error: No rule to make target 'openvpn.moc', needed by 'openvpnmanager.o'. Stop. I've cleaned the build directory, re-ran qmake, and rebuilt it 1000 times. Despite this, it still refuses to work. What am I doing wrong?
myproject.pro:
QT += core widgets network
CONFIG += c++11
UI_SOURCES_DIR = src/gui
UI_HEADERS_DIR = include
. . .
SOURCES += \
src/main.cpp \
src/gui/loginwindow.cpp \
src/api/api.cpp \
src/openvpn/openvpn.cpp \
src/alert.cpp \
src/gui/vpn.cpp \
src/api/account.cpp \
src/crypto.cpp \
src/killswitch.cpp \
src/vpnstatus.cpp \
src/gui/logdialog.cpp \
src/logitem.cpp \
src/authenticationworker.cpp \
src/api/error.cpp \
src/openvpn/openvpnmanager.cpp \
src/api/server.cpp \
src/api/authenticationresponse.cpp
HEADERS += \
include/loginwindow.h \
include/api.h \
include/alert.h \
include/vpn.h \
include/account.h \
include/crypto.h \
include/killswitch.h \
include/configtype.h \
include/vpnstatus.h \
include/connectionstatus.h \
include/loglevel.h \
include/logdialog.h \
include/logitem.h \
include/authenticationworker.h \
include/error.h \
include/openvpnmanager.h \
include/server.h \
include/authenticationresponse.h \
FORMS += \
src/gui/loginwindow.ui \
src/gui/vpn.ui \
src/gui/logdialog.ui
RESOURCES += \
src/resources.qrc
DISTFILES +=
openvpn.cpp:
class Client : public QObject, public ClientAPI::OpenVPNClient {
Q_OBJECT
public:
. . .
TL;DR
Simply delete your build-xxx folder, and rebuild from scratch!
Context
You (almost) never have to include a .moc file. Moc files are created automatically by the mocompiler and compiled and linked in a dedicated translation unit (i.e. like any .cpp file).
The only exception is when your QObject class is declared in a cpp file (which happens to be your case!), because the .moc implementation will still require your class definition to compile. As suggested in the comments, there is a detailed explanation here.
Potential issues
Regarding your specific issue, moc file issues can originate from:
the Q_OBJECT keyword is missing (but you have it). This token is used to trigger the generation of a .moc file for that specific class. Without it, most QObject features are missing.
the class was parsed/compiled previously without the Q_OBJECT keyword, and cached as a non-QObject class. In that case, you just have to manually delete your build folder (or run qmake manually), to force identifying again which classes should be moced.
You are using the wrong filename for your moced file. The correct name is typically
moc_filename.cpp when your class is declared in a header file
filename.moc when your class is declared in a source file
qmake does not actually parses your .cpp file. This can be the case if your .pro file doesn't include it in the SOURCES variable, or if you are just never running qmake (specific setup, etc.)
Sample Makefile
You can double check it your moc files has appropriate rules in the Makefile of its project. Below is a sample portion of a Makefile:
compiler_moc_source_make_all: mysourcefile.moc
compiler_moc_source_clean:
-$(DEL_FILE) mysourcefile.moc
mysourcefile.moc: /home/aleravat/Qt/5.9.7/gcc_64/include/QtCore/QCoreApplication \
/home/aleravat/Qt/5.9.7/gcc_64/include/QtCore/qcoreapplication.h \
/home/aleravat/Qt/5.9.7/gcc_64/include/QtCore/qglobal.h \
/home/aleravat/Qt/5.9.7/gcc_64/include/QtCore/qconfig-bootstrapped.h \
# [...] more includes
/home/aleravat/Qt/5.9.7/gcc_64/bin/moc $(DEFINES) --include ./moc_predefs.h [...] mysourcefile.cpp -o mysourcefile.moc
Related
I'm not quite completely understand how linux or g++ (gcc) define what include path it need to use to find some package. Here is what I mean:
I actually have a c++ project in QtCreator and I use qmake build system. I include in my code a header-only framework file, which needs a Boost of one of the last version. I have already in my system boost-1.64.0, but it's too old, so I've installed boost-1.80.0. But when I try to build the program a compilation error raises with the text:
{name_of_my_pro_file}.pro: rpm boost1.64.0-devel is not installed!!!
I thought if I just replace boost folder in /usr/include/ or /usr/local/include/ with folder of the newer boost version linux can use it instead of older one. But the error mentioned above still raises. I've tried to edit boost folder name in Makefile. Directly in my .pro file there is not any mentions about boost. But nothing helped me. I can handle it only when I renamed boost-1.80.0 folder to boost-1.64.0. And now it works.
It seems that name boost-1.64.0 is written somewhere in the system and it doesn't see any other packages.
I guess that I just don't understand how to work with this stuff correctly and doing something wrong. Can somebody explain what should I do?
My distro is Oracle Linux Server 8.4.
EDIT:
My .pro file:
QT += core gui network xml
QMAKE_CXXFLAGS += -std=c++0x
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = TilesDataProvider
TEMPLATE = app
#DESTDIR = ./output
DEFINES += QT_DEPRECATED_WARNINGS
DEFINES += QT_DEPRECATED_WARNINGS
CONFIG += no_abi_dump
INCLUDEPATH += \
$$PWD \
$$PWD\guts \
$$PWD\SRTM \
$$PWD\tileSources \
/usr/include
CONFIG(release, debug|release){
message(release)
TARGET = TilesDataProvider
OBJECTS_DIR = tmp/TilesDataProvider/release
MOC_DIR = tmp/TilesDataProvider/moc
}
CONFIG(debug, debug|release){
message(debug)
TARGET = TilesDataProvider_d
OBJECTS_DIR = tmp/TilesDataProvider/debug
MOC_DIR = tmp/TilesDataProvider/moc
DEFINES += _DEBUG
}
SOURCES += \
main.cpp \
tileSources/MapTileSource.cpp \
tileSources/SrtmTileSource.cpp \
guts/Position.cpp \
guts/t_task.cpp \
guts/MapConversions.cpp \
SRTM/altdatabank.cpp \
SRTM/altdatamap.cpp \
SRTM/geoid.cpp \
SRTM/srtm_coordinate.cpp \
SRTM/t_geodata.cpp \
SRTM/t_pageid.cpp \
t_image.cpp \
tilesdataprovider.cpp
HEADERS += \
tileSources/MapTileSource.h \
tileSources/SrtmTileSource.h \
guts/MapGraphics_global.h \
guts/Position.h \
guts/t_task.h \
guts/MapConversions.h \
SRTM/altdatabank.h \
SRTM/altdatamap.h \
SRTM/geoid.h \
SRTM/srtm_coordinate.h \
SRTM/t_geodata.h \
SRTM/t_pageid.h \
SRTM/tiff_param.h \
t_image.h \
tilesdataprovider.h
I have just been editing code for a proprietary software that has just been working fine. I will show some of the relevant code:
I've dealt with linker errors through QT before through a number of "Run qmake & rebuilds" however this time nothing seems to have changed with the program, yet every reference to a specific file is returning as undefined.
SOURCES += \
main.cpp \
mainwindow.cpp \
program.cpp \
dv.cpp \
s.cpp \
l.cpp \
n.cpp \
t.cpp \
t_c.cpp
HEADERS += \
mainwindow.h \
program.h \
dv.h \
s.h \
l.h \
n.h \
t.h \
tt.h \
t_c.h
FORMS += \
mainwindow.ui \
dv.ui \
s.ui \
l.ui \
n.ui \
t.ui \
testframe.ui \
t_c.ui
Class program.h includes nothing except the needed Q libraries (QMap, QString, etc)
Class t_c.h includes program.h.
Class t.h includes program.h, tt.h (which only includes Q libraries), and t_c.h
Class mainwindow.h includes program.h, dv.h, s.h, n.h, t.h
The latest addition was the creation of t_c.h and the adding of functions from program.h before it broke. I would think it would be an issue with t.h however every single reference to program.h's methods are "undefined", even in mainwindow.cpp
/usr/bin/ld: mainwindow.o: in function `MainWindow::MainWindow(QWidget*)':
mainwindow.cpp:(.text+0x121): undefined reference to `Program::method(QString)'
undefined reference to ... [all the way down]
I've tried cleaning, re-running qmake, deleting the build folder.
There are no external libraries outside of the Q Libraries. There is no "assembly_86_64" nor "vtable" related errors.
For some reason half of my functions cleared out after I condensed them in QT's view.
Alright.
I have been able to successfully integrate opencv with Qt using the following tutorial:
How to link opencv in QtCreator and use Qt library
However, When I try to write line #include "opencv/cv.h in my .cpp file, qt throws me an error:
D:\opencv\opencv_bin\install\include\opencv2\flann\saving.h:113: error: exception handling disabled, use -fexceptions to enable
throw FLANNException("Invalid index file, cannot read");
^
I am not sure if this is a qt problem or an opencv installation problem.
TEMPLATE = app
TARGET = cube4
QT += 3d
SOURCES = cubeview.cpp main.cpp \
haptics.cpp
HEADERS = cubeview.h \
haptics.h \
src/haptics.h \
src/adll.h \
src/afuncs.h \
src/atypes.h \
src/avars.h \
src/glut.h \
src/StdAfx.h \
hdl/hdl.h \
hdl/hdlConstants.h \
hdl/hdlErrors.h \
hdl/hdlExports.h \
hdlu/hdlu.h \
hdlu/hdluExports.h
HEADERS += \
Widget.h
RESOURCES = cube.qrc
win32:LIBS += -LD:\\opencv\\opencv_bin\\bin \
libopencv_core248d \
libopencv_highgui248d \
libopencv_imgproc248d \
libopencv_features2d248d \
libopencv_calib3d248d \
win32: INCLUDEPATH +="D:/opencv/opencv_bin/install/include"
Thanks iHarob. The solution was to add "exceptions" to the CONFIG variable in your project file (the *.pro file):
CONFIG += exceptions
This takes care of passing the correct compiler flags. The answer can be found here:
How to enable exception handling in mingw
I have a game with two separate projects for the application itself and the tests. I'm building all of the projects in-source. Here's a shortened version of my project structure:
game
game.pro
app
app.pro
Entity.h
Entity.cpp
Entity.o
moc_Entity.cpp
moc_Entity.o
tests
layer
layer.pro
Entity.o (duplicated)
moc_Entity.cpp (duplicated)
moc_Entity.o (duplicated)
tst_Layer.cpp
app.pro:
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
}
TARGET = cotw-clone
TEMPLATE = app
MOC_DIR = .moc
OBJECTS_DIR = .obj
HEADERS += MainWindow.h \
Map.h \
Tile.h \
Character.h \
Layer.h \
NewGameDialog.h \
GameController.h \
Stair.h \
Random.h \
MapGenerator.h \
TileData.h \
Statistics.h \
StatisticsDialog.h \
StatisticWidget.h \
Range.h \
Level.h \
RandomMapGenerator.h \
AiController.h \
MonsterJournalWidget.h \
InventoryDialog.h \
PathSearch.h \
PathNode.h \
Path.h \
Geometry.h \
EntityDatabase.h \
EntityData.h \
Entity.h \
CharacterData.h \
EntityMetadata.h
SOURCES +=\
MainWindow.cpp \
Map.cpp \
Tile.cpp \
Character.cpp \
Layer.cpp \
NewGameDialog.cpp \
GameController.cpp \
Stair.cpp \
TileData.cpp \
Statistics.cpp \
StatisticsDialog.cpp \
StatisticWidget.cpp \
Level.cpp \
RandomMapGenerator.cpp \
AiController.cpp \
MonsterJournalWidget.cpp \
InventoryDialog.cpp \
PathSearch.cpp \
PathNode.cpp \
Path.cpp \
EntityDatabase.cpp \
EntityData.cpp \
Entity.cpp \
CharacterData.cpp \
main.cpp
FORMS += MainWindow.ui \
NewGameDialog.ui \
StatisticsDialog.ui \
StatisticWidget.ui \
MonsterJournalWidget.ui \
InventoryDialog.ui
RESOURCES += \
icons/icons.qrc \
tiles/tiles.qrc
RESOURCES += \
entities/entities.qrc
My problem is that all of the tests projects use classes from the app project, which means they're compiling all of these classes even though they've already been compiled when app was built. Take the layer test project, for example:
layer.pro:
QT += testlib
QT -= gui
greaterThan(QT_MAJOR_VERSION, 4) {
QT += widgets
}
TARGET = tst_LayerTest
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += tst_LayerTest.cpp
DEFINES += SRCDIR=\\\"$$PWD/\\\"
HEADERS += "../../app/Entity.h"
SOURCES += "../../app/Entity.cpp"
So how can I point qmake to the .o (and qrc_, .moc etc.) files that have already been produced in app? Is there some qmake variable for this purpose, or is my project structure just fundamentally flawed?
You can use wildcards in qmake .pro files, to save having to maintain a list of all file names.
For example,
SOURCES += *.cpp
Each time you run qmake, that pattern *.cpp gets expanded in to the current list of files matching the pattern.
You can also use -= to remove file names, if you have a particular filename that you wish to exclude.
For example:
SOURCES += *.cpp
SOURCES -= main.cpp
Edit
I almost suggested in my earlier answer that you introduce a library, using qt's lib template, to contain your common code.
Then your build structure would look like this - assuming that you can move files around, from app/ to lib/:
game
game.pro
app
app.pro
main.cpp
lib
lib.pro
Entity.h
Entity.cpp
Entity.o
moc_Entity.cpp
moc_Entity.o
tests
layer
layer.pro
tst_Layer.cpp
You can find some info on library projects in "Building a Library" on the Qt website
If, for some reason, you can't move your files around, then you can introduce a new directory for the library, and have it pull in source files from the app directory - but that is definitely more faff, and more confusing:
game
game.pro
app
app.pro - builds only main.o
main.cpp
Entity.h
Entity.cpp
moc_Entity.cpp
lib
lib.pro
Entity.o
moc_Entity.o
tests
layer
layer.pro
tst_Layer.cpp
Edit 2
One problem you have is you are putting object files in to the LIBS variable, which defines what libraries your code will link against. So that'll be why you are getting errors with those files.
Try changing those LIBS uses to OBJECTS instead, and it may work.
If not, have a read of this thread, which is asking pretty much the same thing.
In particular, see the answer by ChrisW67 of '13th May 2012, 10:14' which begins;
Try:
OBJECTS += f1.o f2.o f3.o f3.o
although I think that, if you have the source, building it into your
app directly or via a library is a better option.
I've successfully powered my way through the WDK XPSDrv sample project and modified it to do what I need. However, I absolutely cannot figure out how to get the build scripts to reference/include/whatever shell32.lib. I'm a .NET guy! This is strange and terrifying territory.
I think adding a dependency reference is what I need to do. When I compile I get this error
3>errors in directory c:\winddk\7600.16385.1\src\printgit\xpsdrvsmpl\
src\filters\common
3>c:\winddk\7600.16385.1\src\printgit\xpsdrvsmpl\src\filters\common\
xdstrmflt.cpp(238) : error C3861: 'ShellExecute': identifier not found
Due to my extreme lack of knowledge (and hurry) I'm not using visual studio, just simple mods in notepad++ and the shell wdk build environment. I have a surrogate project in VS where I've been writing and testing small chunks of code. In that project I added a Dependency library to shell32.lib and everything worked perfectly.
There's a makefile that references a sources, the contents are below.
Not that it matters, but the code that requires shell32 is
HINSTANCE statu = ShellExecute(NULL,TEXT("open"),szTempFileName,NULL,NULL,9);
Here's the sources file.
INCLUDES=$(INCLUDES); \
.\; \
.\..\inc; \
.\..\debug; \
$(DDK_INC_PATH); \
$(SDK_INC_PATH)\gdiplus; \
USE_ATL=1
USE_STL=1
ATL_VER=70
STL_VER=70
# We use STL 7.0, which is not available pre-Vista. We therefore set USE_LIBCMT=1
# If STL 7.0 is not necessary, USE_MSVCRT=1 is recommended
USE_LIBCMT=1
USE_IDLBASED_DLLDATA=1
USE_OBJECT_ROOT=1
MSC_WARNING_LEVEL=/W4 /WX
USE_NATIVE_EH=1
PRECOMPILED_CXX=1
PRECOMPILED_INCLUDE=precomp.h
# To remove debug code remove -DDBG from the line below
C_DEFINES=$(C_DEFINES) -D_UNICODE -DUNICODE
SOURCES=\
bkpchndlr.cpp \
bkpthndlr.cpp \
bkschema.cpp \
cmpthndlr.cpp \
cmprofpthndlr.cpp \
cmprofpchndlr.cpp \
cmintpthndlr.cpp \
cmschema.cpp \
cmprofileschema.cpp \
cmintentsschema.cpp \
globals.cpp \
nupschema.cpp \
nupchndlr.cpp \
nupthndlr.cpp \
pchndlr.cpp \
pgscpchndlr.cpp \
pgscpthndlr.cpp \
pgscschema.cpp \
porientpthndlr.cpp \
porientschema.cpp \
psizepthndlr.cpp \
psizeschema.cpp \
pimagepthndlr.cpp \
pimageschema.cpp \
pshndlr.cpp \
pthndlr.cpp \
ptquerybld.cpp \
schema.cpp \
wmpchndlr.cpp \
wmpthndlr.cpp \
wmschema.cpp \
workbuff.cpp
TARGETNAME=xdsmplcmn
TARGETTYPE=LIBRARY
For example in your sources file:
TARGETLIBS=$(SDK_LIB_PATH)\kernel32.lib $(SDK_LIB_PATH)\user32.lib $(SDK_LIB_PATH)\shell32.lib
... amend as needed ;)
However, your error is actually not a linker error but a compiler error, so you'll likely want to include the header that declares ShellExecute, which is shellapi.h, in some way.
Just looked the sample up in my WDK (7600.16385.1) and as a matter of fact you removed the very important part reproduced below, to which you just would have to append the other .lib files to link against:
TARGETLIBS= \
$(SDK_LIB_PATH)\kernel32.lib \
$(SDK_LIB_PATH)\user32.lib \
$(SDK_LIB_PATH)\winspool.lib \
$(SDK_LIB_PATH)\ole32.lib \
$(SDK_LIB_PATH)\oleaut32.lib \
$(SDK_LIB_PATH)\advapi32.lib \
$(SDK_LIB_PATH)\msxml6.lib \
$(SDK_LIB_PATH)\uuid.lib \
$(SDK_LIB_PATH)\Comdlg32.lib \
$(OBJ_PATH)\..\debug\$O\xdsdbg.lib \
$(OBJ_PATH)\..\common\$O\xdsmplcmn.lib \
... apologies, there are plenty of sources files as part of this sample, so of course I cannot really know which of the samples you modified and are trying to build :)