Laziness is the engine of progress. Working in programming for the second decade, I still agree with this thesis. But in every joke, as you know, there is a bit of joke.
This article will discuss how to make a computer write routine code for you. And as much as possible to automate this process and integrate with the project assembly. Qmake will help us in all this
Why do you need it
In my current project, it became necessary to apply an object-based approach when working with data physically stored in a relational database. So ORM. It just so happened that this corporate segment project is being developed on Qt. Yes, even though this is the most beautiful framework, it is not quite suitable for programming complex corporate applications. Nevertheless, the choice in favor of Qt was made for a number of very compelling reasons.
So, there is a small relational database of about 100 tables. It is necessary to write a thin layer of business logic, which in the future will become overgrown with fat. There is a description of the structure of the database in XML.
You can roll up your sleeves and write 100 business logic classes of the same type in a week. Write numerous tests comparing these classes, an XML description of the metadata and the database structure itself. But, this is not the approach of a real Jedi! Indeed, because we already have everything necessary to describe the prototypes of business logic classes, we just need to turn .xml into .h.
Code generator
To begin with, let's deal with XML. The description of the tables looks like this:
<table name="TestTable" > <field name="id" type="INTEGER" /> <field name="name" type="VARCHAR(100)" /> </table>
Of course, using the same QDomDocument you can quite quickly write your own preprocessor generator, but it would be more correct to use XSL. For XSLT transformations, it is convenient to use some kind of console processor. I used
xsltproc . This simple utility takes as input XML, XSL and prints the resulting text to where it will be said. You can use another tool, you can write yourself, it does not matter. Using a simple template we get
class TestTable { public: int id(); QString name(); };
Yes, while this is a thin-thin skeleton, which should be fat, even at the stage of automatic generation, but these details will be omitted. We are still important principle itself.
So, we already know how to automatically generate code in any quantities, it remains to automate this process.
')
Automation
I work in QtCreator and I want to include my XML files with a description of the data structure directly in the project. For files that are not involved in the standard build process, there is a “Other Files” project section. In the .pro file it is called OTHER_FILES, which is typical. But we will not interfere with flies with cutlets, we will get our section right away. Add our description there, and then add our section to the “Other files”:
ORM_FILES += classes.qoc OTHER_FILES += $$ORM_FILES
Now the fun begins. QMake is an incredibly sophisticated thing. There are more than a hundred keywords for describing pro-files. One of the features is QMAKE_EXTRA_COMPILERS. This is a mechanism for specifying the rules for launching additional compilers, preprocessors and other code interpreters in the pro-file. This is how moc and uic are called. The original description can be found
here . True, it is quite concise. In our profile, the following should be added:
orm.output = ${QMAKE_FILE_IN_PATH}/${QMAKE_FILE_IN_BASE}_qoc.h # orm.input = ORM_FILES # orm.commands = xsltproc -o ${QMAKE_FILE_OUT} ${QMAKE_FILE_IN} # orm.variable_out = HEADERS # orm.name = ORM # ( qmake) QMAKE_EXTRA_COMPILERS += orm
You can try to collect, at this stage, everything should already work.
Restore order
The above piece actually resembles qmake .prf files that are located in / usr / share / qt4 / mkspecs / features if you are using Linux. When we write
CONFIG += xml
for example, the xml.prf config is connected. Thus, you can put these instructions in the orm.prf file and put it in the specified folder. Then to process our XML-ek it will be enough to write
CONFIG += orm
Instead of conclusion
Now a few words about possible pitfalls. I almost immediately wrote this config on the manual, but nothing happened. In the build console, there was no launch of xsltproc and the header was not generated. Having tried various options, I found that xsltproc is at least called if you write orm.variable_out = SOURCES. Then I discovered that I forgot to write # define protection in the XSL template to prevent the header from being re-enabled, and after correcting the template EXTREMELY, the config worked and started to generate the generated header regularly. I do not believe in miracles, I wrote it off at four in the morning. But, if you find something like this - I warned you.