Reputation: 2404
Here's my situation:
I have a typical Qt C++ project that I'm building with qmake (.pro file).
I also have a python script that generates some code. The python script (let's call it update.py) generates three files, let's call them gen.h, gen.cpp, gen.qml.
Now what I'm doing now is manually running update.py in order to generate those files. Then I can run make and everything builds OK. The gen.h and gen.cpp are just "regular" files in my .pro file and they are checked into SVN.
What I want instead is to make it so that when I run make, update.py will get run and generate those files, and then they will get built along with the project. This way I can remove them from SVN and avoid the extra manual step.
FYI: I already have update.py setup to only re-generate those files when needed, so if you run update.py multiple times it won't keep blindly changing gen.h, gen.cpp, etc.
I have spent a huge amount of time trying to get this work (kinda embarrassing actually). I have been messing with QMAKE_EXTRA_TARGETS, QMAKE_EXTRA_COMPILERS, PRE_TARGETDEPS, etc, but nothing seems to quite work the way I want.
Oh, some more info: gen.cpp and gen.h have QObject based classes, so I need them to gen generated before the MOC is run.
Thanks!
Upvotes: 4
Views: 1656
Reputation: 728
if I understood this would fit your needs:
mytarget.target = .buildfile
mytarget.commands = ./update.py
QMAKE_EXTRA_TARGETS += mytarget
PRE_TARGETDEPS += .buildfile
with first statement you define a new Makefile target called "buildfile", with the second you define what your buildfile target does (it calls a update.py that generates code) with the third you define mytarget as a new qmake target and last one add buildfile target to qmake's target list.
Oh I forgot. I found this on qmake's manual: http://qt-project.org/doc/qt-4.8/qmake-environment-reference.html at this section. Maybe it useful ;)
And for moc you can define these:
new_moc.output = moc_${QMAKE_FILE_BASE}.cpp
new_moc.commands = moc ${QMAKE_FILE_NAME} -o ${QMAKE_FILE_OUT}
new_moc.depend_command = g++ -E -M ${QMAKE_FILE_NAME} | sed "s,^.*: ,,"
new_moc.input = NEW_HEADERS
QMAKE_EXTRA_COMPILERS += new_moc
I have done some test. And this works to me:
//.pro file:
QT += core gui
TARGET = test
TEMPLATE = app
SOURCES += main.cpp \
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
mytarget.target = .buildfile
mytarget.commands = ./update.py
QMAKE_EXTRA_TARGETS += mytarget
PRE_TARGETDEPS += .buildfile
new_moc.target = .mymoc
new_moc.output = moc_widget.cpp
new_moc.commands = moc widget.cpp -o moc_widget.o
new_moc.depend_command = g++ -E -M widget | sed "s,^.*: ,,"
new_moc.input = moc_widget.h
QMAKE_EXTRA_COMPILERS += new_moc
//update.py:
#!c:/Python/python.exe -u
fd=open("widget.h",'w')
fd.write("#ifndef WIDGET_H\n")
fd.write("#define WIDGET_H\n")
fd.write("#include <QWidget>\n")
fd.write("namespace Ui {\n")
fd.write("class Widget;\n")
fd.write("}\n")
fd.write("class Widget : public QWidget\n")
fd.write("{\n")
fd.write(" Q_OBJECT\n")
fd.write("public:\n")
fd.write(" explicit Widget(QWidget *parent = 0);\n")
fd.write(" ~Widget();\n")
fd.write("private:\n")
fd.write(" Ui::Widget *ui;\n")
fd.write("};\n")
fd.write("#endif // WIDGET_H\n")
fd.close()
fd=open("widget.cpp",'w')
fd.write("#include \"widget.h\"\n")
fd.write("#include \"ui_widget.h\"\n")
fd.write("Widget::Widget(QWidget *parent) :\n")
fd.write(" QWidget(parent),\n")
fd.write(" ui(new Ui::Widget)\n")
fd.write("{\n")
fd.write(" ui->setupUi(this);\n")
fd.write("}\n")
fd.write("\n")
fd.write("Widget::~Widget()\n")
fd.write("{\n")
fd.write(" delete ui;\n")
fd.write("}\n")
fd.close()
Upvotes: 3