【问题标题】:How to create a qmake function that creates a custom make target?如何创建一个创建自定义 make 目标的 qmake 函数?
【发布时间】:2016-10-03 13:18:54
【问题描述】:

我知道我们有QMAKE_EXTRA_TARGETS 来创建新的makefile 目标,其使用如下(如http://blog.qt.io/blog/2008/04/16/the-power-of-qmake/ 所示):

conv.target=convert
conv.input=file.in
conv.output=file.out
conv.commands=convert.sh file.in file.out
QMAKE_EXTRA_TARGETS+=conv

在我的例子中,convert.sh 用于多个文件和目标。我想创建一个带有参数(target_name、input_file、output_file)的方法,为我创建任务,这样我就不必重复上面的行了。

qmake 上的文档非常缺乏,或者我没有找到正确的来源,但据我了解,qmake 中有两种类型的函数:替换和测试(http://doc.qt.io/qt-5/qmake-language.html#replace-functions),我们可以使用创建自定义函数defineReplacedefineTest

我试过了:

defineTest(createConvertTask) {
    custom.target = $$1
    custom.input = $$2
    custom.output = $$3
    custom.commands = convert.sh $$2 > $$3
    QMAKE_EXTRA_TARGETS += custom
}

但这并没有真正起作用,因为在多次调用createConvertTask 之后,QMAKE_EXTRA_TARGETS 将只包含字符串custom 的多个副本。

但是,这个

defineTest(createConvertTask) {
    $$1.target = $$1
    $$1.input = $$2
    $$1.output = $$3
    $$1.commands = convert.sh $$2 > $$3
    QMAKE_EXTRA_TARGETS += $$1
}

失败并出现错误example.pro:2: error: Left hand side of assignment must expand to exactly one word.

关于如何解决这个问题的任何想法?

【问题讨论】:

    标签: c++ qt makefile qmake


    【解决方案1】:

    1.Option:自定义编译器

    像这样使用custom compiler

    convert.input = LIST_OF_IN_FILES  # note: no $$
    convert.output = $${SOME_DIR}/${QMAKE_FILE_BASE}.ext
    convert.commands = convert.sh ${QMAKE_FILE_IN} > $${SOME_DIR}/${QMAKE_FILE_BASE}.ext
    
    convert.CONFIG += no_link target_predeps
    QMAKE_EXTRA_COMPILERS += convert
    

    变量${QMAKE_FILE_IN} 包含当前 输入文件,与${QMAKE_FILE_BASE} 相同,但没有扩展名。在这里,输出文件名是从输入文件中生成的。 CONFIG 选项告诉 qmake 不要将输出文件添加到对象列表中,并将它们添加为主要目标的先决条件。此外还会生成一个make 目标compiler_convert_make_all

    只需添加文件:

    LIST_OF_IN_FILES += file1 file2
    

    制作

    make compiler_convert_make_all
    

    此选项还将所有输出文件添加到clean 目标(将在make clean 上删除。

    2.选项:使用eval()export()

    要将变量用作左手表达式,您可以使用eval() function,即“使用 qmake 语法规则评估字符串的内容”。

    eval($${1}.target = $$1)
    

    由于这是在函数内部完成的,因此您需要将所有变量 export() 到全局范围内。

    eval(export($${1}.target))
    

    然后添加目标并导出QMAKE_EXTRA_TARGETS

    QMAKE_EXTRA_TARGETS += $${1}
    export(QMAKE_EXTRA_TARGETS)
    

    加上一个replace function,返回值会添加到自定义convert目标的依赖中:

    convert.target = convert
    
    defineReplace(createConvertTask) {
        eval($${2}_custom.target = $$2)
        eval($${2}_custom.depends = $$1)
        eval($${2}_custom.commands = convert.sh $$1 > $$2)
        eval(export($${2}_custom.target))
        eval(export($${2}_custom.depends))
        eval(export($${2}_custom.commands))
    
        QMAKE_EXTRA_TARGETS += $${2}_custom
        export(QMAKE_EXTRA_TARGETS)
        return($${2}_custom)
     }
    
     convert.depends += $$createConvertTask(in_file_1, out_file_1)
     convert.depends += $$createConvertTask(in_file_2, out_file_2)
    
     QMAKE_EXTRA_TARGETS += convert
    

    生成的Makefile中的结果:

    out_file_1: in_file_1
           convert.sh in_file_1 > out_file_1
    
    out_file_2: in_file_2
           convert.sh in_file_2 > out_file_2
    
    convert: out_file_1 out_file_2
    

    这种方法更灵活,可以扩展以支持可变目标参数(此处为常量convert)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-04-28
      • 2016-02-24
      • 1970-01-01
      • 1970-01-01
      • 2017-10-14
      • 1970-01-01
      • 1970-01-01
      • 2011-11-04
      相关资源
      最近更新 更多