3

I found some ways (like Qt run script before make) how to run a script building one target before compiling anything else.

I don't seem to get the whole concept. I don't know how to make several targets (several C++ header files) by calling a script/executable before compiling everything since I need those generated header files for compilation.

In plain make I would do something like:

GENERATOR= \dist\gen_headers.exe

BUILD_SOURCES+= header1.h header2.h header3.h

header1.h header2.h header3.h: headers.h.in $(GENERATOR)
    -$(RM) header1.h
    -$(RM) header2.h 
    -$(RM) header3.h
    $(GENERATOR) headers.h.in

clean-hook:
    -$(RM) header1.h >NUL: 2>NUL:
    -$(RM) header2.h >NUL: 2>NUL:
    -$(RM) header3.h >NUL: 2>NUL:

How can I do this in qmake in a pro that looks like the following file?

win32:TEMPLATE = vclib
!win32:TEMPLATE = lib

QT += core
CONFIG += staticlib
CONFIG += no_keywords

#C++ exception specification ignored except to indicate a function is not __declspec(nothrow)
QMAKE_CXXFLAGS += /wd4290

#forcing value to bool ->performance warning
QMAKE_CXXFLAGS += /wd4800

INCLUDEPATH += .
...

HEADERS += header1.h \
    header2.h \
    header3.h \
    ...

SOURCES += source.cpp \
    ...

contains(DEFINES, ARCH_x32) {
    DESTDIR = ../Bin32
    CONFIG(debug, debug|release) {
        OBJECTS_DIR = ./debug_x86
        MOC_DIR = ./debug_x86
        TARGET = lib32D
    } else {
        OBJECTS_DIR = ./release_x86
        MOC_DIR = ./release_x86
        TARGET = lib32
    }
}

contains(DEFINES, ARCH_x64) {
    DESTDIR = ../Bin64
    CONFIG(debug, debug|release) {
        OBJECTS_DIR = ./debug_x64
        MOC_DIR = ./debug_x64
        TARGET = lib64D
    } else {
        OBJECTS_DIR = ./release_x64
        MOC_DIR = ./release_x64
        TARGET = lib64
    }
}

EDIT 1:

I've tried to add the following code before the contains statements but it doesn't seem to work.

headers.target = headersDep
headers.commands = echo "Building headers..."; \
                 dist\gen_headers.exe headers.h.in; \
                 echo "Done building headers."; \
headers.depends =

QMAKE_EXTRA_TARGETS += headers
PRE_TARGETDEPS = headersDep

When calling qmake I get the error that header1, header2 and header3 couldn't be found. If I try to compile I get a similar error No such file or directory. My echoed output is never shown. So what am I doing wrong?

EDIT 2

Well, I found system(command). I removed the contents from Edit 1 and added the following right before the INCLUDEPATH statements.

message(Building headers...)
system(dist\gen_headers.exe headers.h.in):message(Done building headers.)

My headers are built now if I call qmake to build the project so that's good. But there is one problem: The pair of messages I issue on building the headers appears 5 times. Why is that? I want to build the headers only once.

Lilo
  • 341
  • 2
  • 14
  • Following the same post that you linked in your post, you can do something like this for multiple targets: `QMAKE_EXTRA_TARGETS += targetlib1 targetlib2` and `PRE_TARGETDEPS = extra1 extra2`. Is this that you want to do? – Azeem Jun 29 '17 at 10:15
  • @Azeem No, this is not exactly what I want. My executable generates all three targets with one call. – Lilo Jun 29 '17 at 10:25
  • Maybe this answer can help you : https://stackoverflow.com/a/3626970/6165833 – ymoreau Jun 30 '17 at 09:06
  • `system()` is run by qmake and not make (and apparently more than once, thus your 5 calls ?), so you would not get your headers updated each time you build your project (but only when you run qmake again). – ymoreau Jun 30 '17 at 09:09
  • @ymoreau Then do you have a suggestion how to issue this command by make using the pro file? – Lilo Jun 30 '17 at 09:45
  • As I said above, this answer suggests to run a command at build time : stackoverflow.com/a/3626970/6165833. `QMAKE_PRE_LINK` in your case if you need the headers before the build. But I just tried on a small example and it is run after the build (before link), so not useful in your case. Only for dealing with lib to link with, sorry. – ymoreau Jun 30 '17 at 10:00

1 Answers1

2

I finally found a way. I used the possibility in qmake to add my own compiler and got inspiration from here.

I added the following lines just before the contains statements.

# Building headers for each call of make (build process).
HEADERS_IN = headers.h.in
gen_headers.name = Building auto generated headers.
gen_headers.input = HEADERS_IN
gen_headers.output = header1.h header2.h header3.h
gen_headers.commands = dist\gen_headers.exe $${HEADERS_IN}
gen_headers.CONFIG += target_predeps
gen_headers.dependency_type = TYPE_C
gen_headers.variables_out = HEADERS
QMAKE_EXTRA_COMPILERS += gen_headers

Now, if I compile within Visual Studio, the headers are built and the content of gen_headers.name is issued as output.

Lilo
  • 341
  • 2
  • 14