qmake额外的编译器,每个文件有多个输出

时间:2013-06-12 19:19:46

标签: qmake

Undocumented qmake中所述,我在qmake项目文件中声明了一个额外的编译器:

TEST = somefile.h

test_c.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.cpp
test_c.input = TEST
test_c.commands = C:/somedir/some.exe /i ${QMAKE_FILE_IN} /o ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.cpp
test_c.variable_out = SOURCES
test_c.name = MyTestC

QMAKE_EXTRA_COMPILERS += test_c

这很好用。但我也想生成一个头文件。我可以轻松地制作第二个自定义工具来解析此文件(或文件,如果> 1将在TEST中),但我不想解析每个文件两次。我试过了:

test_c.output = ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.cpp \
    ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_2.cpp

只是为了测试额外的编译器每次运行可以生成两个文件。我期待一些错误,如“file somefile_2.cpp doesn't exist”,但项目编译没有错误,第二个输出文件被忽略。在Makefile中somefile_2.cpp不存在。

现在我正在考虑两种变体:

  1. 创建一个额外的编译器来生成存档,其中所有需要的输出文件将立即保存。设置tool1.variable_out = TOOL_1_OUT,再添加两个带toolN.input = TOOL_1_OUT的额外编译器,只需“解压缩”已归档的文件(每个工具一个)并将它们附加到一些变量中。

    在这种情况下,每个输入文件将调用三次执行。这不是最佳选择,但至少解析器每个文件只运行一次。

  2. 试用.output_function选项。创建一个qmake函数,返回与.output现在相同的名称,但也将第二个文件名附加到HEADERS

  3. P.S。我使用的是MinGW x32 4.7,QtCreator 2.7.1,Qt 5.1.0,C ++ 11。

2 个答案:

答案 0 :(得分:2)

您的变体#2是正确的想法。这对我有用:

defineReplace(addToHeaders) {
    source = $$1
    source_split = $$split(source, ".")
    source_without_extension = $$first(source_split)
    HEADERS += ${QMAKE_VAR_OBJECTS_DIR}$${source_without_extension}_1.h
    return(${QMAKE_VAR_OBJECTS_DIR}$${source_without_extension}_1.cpp)
}
defineReplace(FILE_IN_addToHeaders) {
    # qmake emits a warning unless this function is defined; not sure why.
}

TEST = somefile.h

test_c.output_function = addToHeaders
test_c.input = TEST
test_c.commands = cp ${QMAKE_FILE_IN} ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.cpp ; cp ${QMAKE_FILE_IN} ${QMAKE_VAR_OBJECTS_DIR}${QMAKE_FILE_BASE}_1.h
test_c.variable_out = SOURCES
test_c.name = MyTestC

QMAKE_EXTRA_COMPILERS += test_c

它生成一个Makefile,它构建somefile_1.cpp和somefile_1.h,somefile_1.cpp被添加到SOURCES,somefile_1.h被添加到HEADERS。

答案 1 :(得分:2)

这样可行(变体#1):

MY_COMP = src/precompiled.h \
    src/file2.h

GENERATE_FOLDER = generated/

# build package file
my_build.clean = $${GENERATE_FOLDER}gen_${QMAKE_FILE_BASE}.pack
my_build.depends = [somepath]/my_precompiler.exe
my_build.output = $${GENERATE_FOLDER}gen_${QMAKE_FILE_BASE}.pack
my_build.input = MY_COMP
my_build.commands = [somepath]/my_precompiler.exe /i ${QMAKE_FILE_IN} /o $${GENERATE_FOLDER}gen_${QMAKE_FILE_BASE}.pack
my_build.variable_out = MY_PACKAGES
my_build.name = "package build"

# unpack cpp
my_unpack_cpp.clean = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.cpp
my_unpack_cpp.depends = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h
my_unpack_cpp.output = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.cpp
my_unpack_cpp.input = MY_PACKAGES
my_unpack_cpp.commands = [somepath]/my_precompiler.exe /unpack cpp /i ${QMAKE_FILE_IN} /o $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.cpp
my_unpack_cpp.variable_out = GENERATED_SOURCES
my_unpack_cpp.dependency_type = TYPE_C
my_unpack_cpp.name = "unpack code"
my_unpack_cpp.CONFIG = no_link

# unpack header
my_unpack_h.clean = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h
my_unpack_h.output = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h
my_unpack_h.input = MY_PACKAGES
my_unpack_h.commands = [somepath]/my_precompiler.exe /unpack h /i ${QMAKE_FILE_IN} /o $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h
my_unpack_h.variable_out = HEADERS
my_unpack_h.name = "unpack header"
my_unpack_h.CONFIG = no_link

QMAKE_EXTRA_COMPILERS += my_build my_unpack_h my_unpack_cpp

使用这种技术,每个解析的输出文件数可能会有所不同,但当然,对于项目中的所有文件,这些文件可能是不变的。

my_precompiler中解析文件,如果未保留unpack选项,则将两个文件(cpp + h)构建到两个QBuffers中。之后,我只是将构建的数据写入QFile:

QDataStream ds(&file);
ds.setVersion(QDataStream::Qt_5_1);

ds << qCompress(output_cpp.data(), 9);
ds << qCompress(output_h.data(), 9);

file.close();

实际上,现在qcompress并不盈利,因为生成的文件太小而不能压缩大小超过了头文件的大小zlib - sizeof(.pack)&gt;大小(.h + .h)。

启封:

QByteArray ba;

QDataStream ds(&file);
ds.setVersion(QDataStream::Qt_5_1);

ds >> ba;

if(unpack != "cpp")
{
 ds >> ba;
}
file.close();  

ba = qUncompress(ba);

file.setFileName(output);
if(!file.open(QFile::WriteOnly | QFile::Truncate)) return 1;

file.write(ba);
file.close();

生成时:

  1. 在生成的标题
  2. 的开头写#include“原始标题”
  3. 在生成代码的开头写#include“生成的标题”
  4. 因此我设置了这个:

    my_unpack_cpp.depends = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h
    

    所以/ unpack cpp(以及建筑物)在构建所需的头文件后执行。这个:

    my_build.depends = [somepath]/my_precompiler.exe
    

    set builded pack(因此,生成的cpp + h)依赖于my_precompiler,因此如果我修改并重建预编译器,所有内容都将被重建。

    P.S。恕我直言,这些线必须在重建前作为清洁工:

    my_build.clean = $${GENERATE_FOLDER}gen_${QMAKE_FILE_BASE}.pack
    my_unpack_cpp.clean = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.cpp
    my_unpack_h.clean = $${GENERATE_FOLDER}${QMAKE_FILE_BASE}.h
    

    但他们没有:(目前我忽略了这一点,但现在如果构建.pack失败,则使用先前构建的pack-file

相关问题