PDA

View Full Version : qmake: Custom code generation that produces both header and cpp files...



chenz
28th February 2012, 01:14
I want to include a custom code generation step in my project that produces both header and cpp files from an input file.

So far I only found examples that generate one type of file.

I experimented quite a bit, but just could not get it to work. Is this even possible in qmake, or should I start looking at other build tools (ie cmake)?

ChrisW67
28th February 2012, 01:21
Assuming the generated header is #included in the generated cpp file, and the header does not need to be run through MOC, it should be sufficient to to run the generator and add the resulting cpp file to SOURCES.

chenz
28th February 2012, 01:39
But then the files will not be regenerated when the input file is modified...

ChrisW67
28th February 2012, 02:12
How have you defined your extra processing in your PRO file?

This works for me:


fakecompiler.name = Test Compiler
fakecompiler.input = FAKEINPUTS
fakecompiler.commands = fakeit.sh ${QMAKE_FILE_IN}
fakecompiler.output = ${QMAKE_FILE_IN}.cpp
fakecompiler.variable_out = SOURCES
fakecompiler.clean = ${QMAKE_FILE_IN}.cpp ${QMAKE_FILE_IN}.h

QMAKE_EXTRA_COMPILERS += fakecompiler

TEMPLATE = app

SOURCES += main.cpp
FAKEINPUTS += something.fake

(fakeit.sh generates a do nothing FILE.cpp and FILE.h from the given file name)

First run:


chrisw@newton /tmp/test $ ls
fakeit.sh main.cpp something.fake test.pro
chrisw@newton /tmp/test $ qmake
chrisw@newton /tmp/test $ make
g++ -c -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -o main.o main.cpp
make: Circular something.fake <- something.fake.o dependency dropped.
fakeit.sh something.fake
g++ -c -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -o something.fake.o something.fake.cpp
g++ -Wl,-O1 -Wl,-rpath,/usr/lib64/qt4 -o test main.o something.fake.o -L/usr/lib64/qt4 -lQtGui -L/usr/lib64 -L/usr/lib64/qt4 -L/usr/X11R6/lib -lQtCore -lgthread-2.0 -lrt -lglib-2.0 -lpthread


Second run:


chrisw@newton /tmp/test $ make
make: Circular something.fake <- something.fake.o dependency dropped.
make: Nothing to be done for `first'.


Third run:


chrisw@newton /tmp/test $ touch something.fake
chrisw@newton /tmp/test $ make
make: Circular something.fake <- something.fake.o dependency dropped.
fakeit.sh something.fake
g++ -c -pipe -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_GUI_LIB -DQT_CORE_LIB -DQT_SHARED -I/usr/share/qt4/mkspecs/linux-g++ -I. -I/usr/include/qt4/QtCore -I/usr/include/qt4/QtGui -I/usr/include/qt4 -I. -o something.fake.o something.fake.cpp
g++ -Wl,-O1 -Wl,-rpath,/usr/lib64/qt4 -o test main.o something.fake.o -L/usr/lib64/qt4 -lQtGui -L/usr/lib64 -L/usr/lib64/qt4 -L/usr/X11R6/lib -lQtCore -lgthread-2.0 -lrt -lglib-2.0 -lpthread


I haven't tracked down the circular reference, but it doesn't seem harmful.

chenz
28th February 2012, 02:29
That does not work if you try to include something.fake.h

ChrisW67
28th February 2012, 02:32
What do you mean?

chenz
28th February 2012, 02:42
something.fake.h is not generated as a dependency of main.cpp (because qmake does not know anything about something.fake.h).
For me the files are generated *after* it tries to compile main.cpp.

ChrisW67
28th February 2012, 02:51
Yes, I can see that here. So the problem is not that the outputs are not rebuilt when the inputs change, but that the outputs of the custom compiler are a not generated early enough. I don't have time to tinker with it right now. Perhaps someone else will chime in.

chenz
28th February 2012, 03:10
Thanks for trying anyway :)

ChrisW67
28th February 2012, 04:52
fake_cpp.name = Compiler to CPP
fake_cpp.input = FAKEINPUTS
fake_cpp.commands = fakeit.sh ${QMAKE_FILE_IN}
fake_cpp.output = ${QMAKE_FILE_IN_BASE}.cpp
fake_cpp.variable_out = SOURCES
fake_cpp.clean = ${QMAKE_FILE_IN_BASE}.cpp

fake_h.name = Compiler to H
fake_h.input = FAKEINPUTS
fake_h.commands = @echo Fake making the header for ${QMAKE_FILE_IN}
fake_h.depends = ${QMAKE_FILE_IN_BASE}.cpp
fake_h.output = ${QMAKE_FILE_IN_BASE}.h
fake_h.clean = ${QMAKE_FILE_IN_BASE}.h

QMAKE_EXTRA_COMPILERS += fake_cpp
QMAKE_EXTRA_COMPILERS += fake_h


TEMPLATE = app

SOURCES += main.cpp
FAKEINPUTS += something.fake


Seems to work when main.cpp references "something.h". Line 11 causes a request for "something.h" to build the dependency "something.cpp", which has a side-effect of creating our header also. The command at line 10 must exist but does nothing (use @true on UNIX).

I changed the generated file names a bit to remove the circular dependency problem.