Как построить несколько заголовочных файлов с помощью исполняемого файла перед компиляцией в qmake?


Я нашел несколько способов (например, Qt run script before make), Как запустить скрипт, создающий одну цель, прежде чем компилировать что-либо еще.

Я, кажется, не понимаю всей концепции. Я не знаю, как сделать несколько целевых объектов (несколько заголовочных файлов C++), вызвав скрипт/исполняемый файл перед компиляцией всего, так как мне нужны эти сгенерированные заголовочные файлы для компиляции.

В plain make я бы сделал что-то вроде:

GENERATOR= distgen_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:

Как я могу сделать это в qmake в профессионале, который выглядит например, следующий файл?

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
    }
}

Править 1:

Я попытался добавить следующий код перед операторами contains, но он, похоже, не работает.

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

QMAKE_EXTRA_TARGETS += headers
PRE_TARGETDEPS = headersDep

При вызове qmake я получаю ошибку, что header1, header2 и header3 не удалось найти. При попытке компиляции я получаю аналогичную ошибку No such file or directory. Мой Эхо-выход никогда не показывается. Так что же я делаю не так?

EDIT 2

Ну, я нашелсистему(команду) . Я удалил содержимое из Отредактируйте 1 и добавьте следующее Прямо перед операторами INCLUDEPATH.

message(Building headers...)
system(distgen_headers.exe headers.h.in):message(Done building headers.)

Мои заголовки теперь построены, если я вызову qmake, чтобы построить проект, так что это хорошо. Но есть одна проблема: пара сообщений, которые я выдаю при построении заголовков, появляется 5 раз. Почему это так? Я хочу построить заголовки только один раз.

1 3

1 ответ:

Я наконец нашел способ. Я использовал возможность в qmake для добавления моего собственного компилятора и получил вдохновение от здесь.

Я добавил следующие строки непосредственно перед операторами contains.

# 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

Теперь, если я компилирую в Visual Studio, заголовки создаются и содержимое gen_headers.name выдается в качестве вывода.