Friday, October 2, 2015

Auto-generated headers in qmake project files

qmake is quite handy for simple source code layout but supporting non-standard use-cases within qmake boundaries is not trivial.

One such example is adding auto-generated header to your project. There are three items qmake must be made aware of before you get the expected and consistent results:

  • arbitrary custom command for creating the header;
  • dependencies;
  • reverse dependencies from other files in the project.

The following snippet shows how to properly convert these items into the actual qmake syntax for "python gen-hdr.py > auto-gen.h" command which depends on a couple of extra files:

# This is a workaround to qmake bug (at least in 2.01a version) which
# results in invalid expansion of ${QMAKE_FILE_IN_PATH} variable within
# .commands definition in the presence of 'combine' .CONFIG option.
defineReplace(autoheadercmd) {
    LIST = $${1}
    return(python $$first(LIST) > $${2})
}

AUTOHEADER = gen-hdr.py hdr-template.py template-class.py
autohdr.CONFIG += combine
autohdr.input = AUTOHEADER
autohdr.output = auto-gen.h
autohdr.commands = ${QMAKE_FUNC_autoheadercmd}
autohdr.variable_out = HEADERS
QMAKE_EXTRA_COMPILERS = autohdr

This results in the following Makefile snippet:

compiler_autohdr_make_all: auto-gen.h
compiler_autohdr_clean:
    -$(DEL_FILE) auto-gen.h
auto-gen.h: gen-hdr.py \
        hdr-template.py \
        template-class.py
    python gen-hdr.py > auto-gen.h

or the following, in case of separate build directory:

compiler_autohdr_make_all: auto-gen.h
compiler_autohdr_clean:
 -$(DEL_FILE) auto-gen.h
auto-gen.h: ../gen-hdr.py \
  ../hdr-template.py \
  ../template-class.py
 python ../gen-hdr.py > auto-gen.h

Reverse dependencies are built automatically, and auto-gen.h will be properly listed where necessary in the Makefile, like this:

user.o: ../user.c ../user.h auto-gen.h
    $(CC) -c $(CFLAGS) $(INCPATH) -o user.o ../user.c

Correct reverse dependencies are especially important when using "make -j" for parallel compilation.

P.S.

See qmake: генерация файлов с помощью QMAKE_EXTRA_COMPILERS by Sergey Skoblikov for extra details, and its parent page - for various other qmake-related topics. (Both are in Russian.)