【问题标题】:Running a program/script from QMake从 QMake 运行程序/脚本
【发布时间】:2011-04-06 10:50:51
【问题描述】:

我们有一个相当大的代码库。绝大多数代码是使用 qmake 编译以生成 makefile。但是,有一些子项目是通过运行批处理文件或运行其他程序产生的。

我希望能够使用 qmake 编译所有内容,但我不知道如何让 qmake 简单地运行脚本。

我尝试过的一件事是在我的 pro 文件中使用 QMAKE_EXTRA_TARGETS,如下所示:

TEMPLATE = lib
SOURCES = placeholder.cpp
CONFIG += no_link staticlib
batch_runner.target   = placeholder.cpp
batch_runner.commands = my_batch_file.bat
QMAKE_EXTRA_TARGETS   = batch_runner

然后我必须让批处理文件像这样生成 placeholder.cpp:

# do the real work here
# ...
# create placeholder.cpp so qmake and nmake are happy
echo // dummy >> placeholder.cpp

这似乎工作正常。问题是它有点做作。如果我没有指定 batch_runner.target(即我将其留空)或没有将 placeholder.cpp 放在 SOURCES 中,则批处理文件永远不会运行。这是因为 qmake 没有使 batch_runner.commands 成为 Makefile 中任何其他依赖项的操作。

有没有更好的方法让 QMake 构造一个 Makefile 以便在 Makefile 执行时运行脚本?

【问题讨论】:

    标签: qt makefile qmake nmake


    【解决方案1】:

    看起来 QMAKE_POST_LINK 很适合这种事情。

    这似乎完成了工作。 my_batch_file.bat 在 nmake 运行时运行(而不是在 qmake 运行时),我不需要对占位符目标或文件做任何有趣的事情。

    很可能我不需要“配置”中列出的所有项目。

    TEMPLATE = lib
    TARGET   = 
    CONFIG  += no_link target_predeps staticlib
    
    QMAKE_POST_LINK  = my_batch_file.bat
    QMAKE_CLEAN     += batch_output.obj
    

    【讨论】:

      【解决方案2】:

      试试system() command。例如:

      system(pwd)
      

      【讨论】:

      • 有趣。这行得通,但是当运行“qmake”而不是运行“nmake”时,该命令会运行。它也恰好运行了 3 次,而不是真正应该运行的一次。
      • 您可能需要添加一些范围以确保它只运行一次。
      • 我刚刚在示例中添加了范围,因此该命令仅在运行 qmake 时运行一次。
      • @ArnoldSpence 你能解释一下你所说的一次性执行范围吗?
      【解决方案3】:

      这是另一个解决方案:

      TEMPLATE = aux
      OBJECTS_DIR = ./
      DESTDIR = ./
      
      first.commands = my_batch_file.bat
      QMAKE_EXTRA_TARGETS += first
      QMAKE_CLEAN += batch_output.obj
      

      模板aux 基本上会生成一个makefile,它在没有指定目标的情况下运行时什么都不做。 OBJECTS_DIRDESTDIR 变量设置为当前目录,以防止 qmake 创建 debugrelease 目录(将它们设置为 ./ 而不仅仅是 . 很重要;至少在视窗)。然后,使用QMAKE_EXTRA_TARGETS,我们重新定义目标first,以便在没有目标的情况下调用makefile时运行自定义命令。

      这有点老套,但它可以完成工作。

      补充: 如果要防止生成三个makefile(MakefileMakefile.DebugMakefile.Release),可以添加

      CONFIG -= debug_and_release
      

      但是,如果您使用它并且取决于 makefile 的调用方式(总是手动调用,由父目录的“子目录”*.pro 文件调用,...),则可能需要创建假 debugrelease 目标以避免“没有规则来制定目标......”错误。例如:

      release.target = release
      release-clean.target = release-clean
      release-install.target = release-install
      [...]
      debug.target = debug
      debug-clean.target = debug-clean
      debug-install.target = debug-install
      [...]
      QMAKE_EXTRA_TARGETS += release release-clean release-install [...]
      QMAKE_EXTRA_TARGETS += debug debug-clean debug-install [...]
      

      【讨论】:

        【解决方案4】:

        您可以使用 SUBDIRS 配置来运行多个不同的目标,即使来自同一个 makefile。这可能对您的额外目标特别有效,因为子目录配置可以指定要运行的 makefile 中的特定目标(有关详细信息,请参阅undocumented qmake)。在这种情况下,我会将所有“常规”构建命令放在一个 .pro 文件中,将外部构建命令放在另一个文件中,并使用一个子目录 .pro 文件来构建所有这些命令。我还没有测试过类似的东西,但它应该可以工作。

        regular.pro:

        SOURCES += main.cpp
        TARGET = regular.exe
        

        external.pro:

        batch_runner.commands = my_batch_file.bat
        QMAKE_EXTRA_TARGETS   += batch_runner
        
        other_runner.commands = other_batch_file.bat
        QMAKE_EXTRA_TARGETS   += other_runner
        

        do_it_all.pro:

        TEMPLATE = subdirs
        CONFIG += ordered
        
        regular.file = regular.pro
        SUBDIRS += regular
        
        batch.file = external.pro
        batch.target = batch_runner
        SUBDIRS += batch
        
        other.file = external.pro
        other.target = other_runner
        SUBDIRS += other
        

        【讨论】:

        • 这与我在原始问题中概述的问题相同。除非指定了 .target (您似乎不能只指定命令)并且 Makefile 的某些其他部分实际上需要 .target ,否则额外的目标将不会运行,否则它将不会运行。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-09-05
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多