让qmake正确运行我的代码生成器

时间:2012-10-11 17:46:27

标签: c++ qt code-generation qmake

这是我的情况:

我有一个典型的Qt C ++项目,我正在用qmake(.pro文件)构建。

我还有一个生成一些代码的python脚本。 python脚本(我们称之为update.py)生成三个文件,我们称之为gen.h,gen.cpp,gen.qml。

现在我正在做的是手动运行update.py以生成这些文件。然后我可以运行make,一切都构建好了。 gen.h和gen.cpp只是我的.pro文件中的“常规”文件,它们被检入SVN。

我想要的是做到这一点,当我运行make时,update.py将运行并生成这些文件,然后它们将与项目一起构建。这样我就可以将它们从SVN中删除,并避免额外的手动步骤。

仅供参考:我已经将update.py设置为仅在需要时重新生成这些文件,因此如果多次运行update.py,则不会盲目地更改gen.h,gen.cpp等。

我花了很多时间试图完成这项工作(实际上有点令人尴尬)。我一直在搞乱QMAKE_EXTRA_TARGETS,QMAKE_EXTRA_COMPILERS,PRE_TARGETDEPS等,但似乎没有什么能按照我想要的方式工作。

哦,更多信息:gen.cpp和gen.h有基于QObject的类,所以我需要它们在MOC运行之前生成。

谢谢!

1 个答案:

答案 0 :(得分:3)

如果我理解这符合您的需求:

mytarget.target = .buildfile
mytarget.commands = ./update.py
QMAKE_EXTRA_TARGETS += mytarget
PRE_TARGETDEPS += .buildfile

使用第一个语句定义一个名为“buildfile”的新Makefile目标, 第二步你定义你的构建文件目标做什么(它调用生成代码的update.py) 在第三个中,您将mytarget定义为新的qmake目标,最后一个将构建文件目标添加到qmake的目标列表中。

哦,我忘了。我在qmake的手册中找到了这个:http://qt-project.org/doc/qt-4.8/qmake-environment-reference.html。也许它很有用;)

对于moc,您可以定义以下内容:

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

我做了一些测试。这对我有用:

//.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()