📜 ⬆️ ⬇️

Insert the code generator into the qmake assembly

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.

Source: https://habr.com/ru/post/139607/


All Articles