我想在C ++源代码中有一个变量(或#define
),每次使用Qt Creator构建源代码时都会增加。有什么方法可以做到这一点,也许是一些Qt Creator插件或类似的?如果我在命令行上使用“make”来构建时有办法吗?
答案 0 :(得分:18)
在.pro文件中,您可以创建一个包含命令行程序结果的变量。然后,您可以使用它来创建定义。
BUILDNO = $$(command_to_get_the_build_number)
DEFINES += BUILD=$${BUILDNO}
如果您只想要一个简单的递增数字,您可以使用一个非常简单的脚本:
#!/bin/bash
number=`cat build_number`
let number += 1
echo "$number" | tee build_number #<-- output and save the number back to file
我应该注意,这会导致每次构建时构建号都会增加,如果你尝试构建它也会增加但是它会失败。更好的方法是根据代码的状态获取内部版本号,并且许多版本控制工具可以为您提供文本字符串,如果不是数字。
答案 1 :(得分:7)
正如我之前在一些测试后写的那样,我发现原始解决方案存在问题,因为每次完成新构建时版本号都不会更新。在很多情况下,我编辑了一个源文件,运行构建,但仍然得到相同的构建号...构建过程刚刚决定什么都没有改变,并跳过了更新构建号的步骤。我首先试图找到一种方法来强迫这一步,但无法弄明白。最后我决定采取不同的方式。现在我使用该脚本生成头文件
build_number.h
,其中包含#define BUILD
,后面有更新后的数字。所以Calebs脚本现在有点修改(build_number.sh
):
#!/bin/bash
number=`cat build_number`
let number++
echo "$number" | tee build_number #<-- output and save the number back to file
echo "#define BUILD ""$number" | tee ../MyProject/build_number.h
递增数字仍存储在名为build_number
的文件中。我可以通过解析生成的头文件来避免第三个文件,但决定反对它。请注意,脚本和生成的标头位于projects目录中,而build_number
文件位于构建目录中。那不是完美的,但我可以忍受它。
为了把事情放在一起,现在还有一些事情要做。首先,需要将生成的头文件添加到Qt Designer中的项目中...右键单击Header-Files和“Add existing file”。其次,它必须包含在C ++文件中,其中访问BUILD定义内部... #include "build_number.h"
...最后但并非最不重要的是必须对项目文件进行一些添加({{1} })。请注意,我从Calebs解决方案中删除了这些内容,因此我们从头开始:
MyProject.pro
这些行(我把它们放在HEADERS部分之前)强制执行脚本,该脚本从build_nr.commands = ../MyProject/build_number.sh
build_nr.depends = FORCE
QMAKE_EXTRA_TARGETS += build_nr
PRE_TARGETDEPS += build_nr
读取最后一个构建号,递增它,写回来并生成{{的更新版本1}}文件。由于这是项目源的一部分,因此每次都会将新值链接到代码中。
有一件事需要提及 - 现在构建过程从不认为没有任何改变。因此,即使您保持代码不变,新的make运行也会生成新版本号并构建新的二进制文件。旧的解决方案在代码更改时留下了数字,这个新的解决方案强制新的构建,即使源不变,因为我强制更改那个头文件。人们可能会喜欢介于两者之间,但由于标题仅包含在一个地方,因此重建速度非常快且不会造成太大伤害。但是,如果有人知道如何充分利用两个世界,请提供建议。至少现在我没有两个具有相同版本号的不同二进制文件。
答案 2 :(得分:7)
Windows等效于Joerg Beutel的改进解决方案https://stackoverflow.com/a/5967447/1619432:
的.pro:
build_nr.commands = build_inc.bat
build_nr.depends = FORCE
QMAKE_EXTRA_TARGETS += build_nr
PRE_TARGETDEPS += build_nr
HEADERS += build.h
build_inc.bat:
@echo off
set /p var= <build.txt
set /a var= %var%+1
echo %var% >build.txt
echo #define BUILD %var% >build.h
echo %var%
用法
#include "build.h"
...
qDebug() << "Build number:" << BUILD;
答案 3 :(得分:4)
Caleb的建议很棒,但在我的案例中并没有“开箱即用”。我得到了一些错误,需要一些阅读才能修复它们。这些变化非常小。我在Ubuntu Linux上使用Qt 4.7 ...第一个更改,如果您可以相信,在shell脚本中从let number += 1
转到let number++
...我通常使用/编程Windoze,所以我无法解释这一点,但是当我在原始情况下从命令行(shell提示符)运行脚本时,我会报告错误,在更改的情况下一切顺利,并且返回递增的数字...
由于Caleb没有完全报告 - 我使用build_number.sh
作为shell脚本的名称,并创建了另一个名为build_number
的文件(没有.sh
)并且只放了一个零在里面,没有别的。
通过在Qt项目文件中用BUILDNO = $$(command_to_get_the_build_number)
替换BUILDNO = $$system(./build_number.sh)
来修复最后一个最令人讨厌的错误。请注意system
之后的$$
以及文件名前面的必需./
。对于普通的Linux用户来说,后者是基本的,但对于Windows用户来说则不是那么多。
希望这能让所有这些人都更加直接,比如我自己。如果您寻求qmake,您可以在Qt Designer帮助部分阅读更多内容,包括功能参考,高级使用等。
哦,最后一句话......我还必须将DEFINES += -DBUILD=$${BUILDNO}
更改为DEFINES += BUILD=$${BUILDNO}
,因此-D
已消失。在C ++代码中,您可以使用BUILD
,就像在文件顶部写了#define BUILD 1234
一样。
答案 4 :(得分:1)
这是我基于handle's solution提出的Win7解决方案。 当您右键单击yer target时,此解决方案还会使Windows为您提供版本#,然后选择Properties |细节。它适用于Win7,可能是大多数早期版本。
好的,你制作了你的build_inc.bat:
@echo off
copy /b myapp.rc +,,
set /p var= <build.txt
set /a var= %var%+1
echo %var% >build.txt
echo #define BUILD %var% >build.h
并将其放在yer proj文件夹中。 (copy /b myapp.rc +,,
是不可思议的Microsoft-eese,用于触摸&#34; - 更新文件的时间戳。)到目前为止,这么好 - 那又怎样?!!
如果您不需要编码到二进制文件中的版本,则此部分是可选的。创建.rc文件,例如:
#include "build.h"
1 VERSIONINFO
FILEFLAGS 32
FILEVERSION 1, 0, BUILD, 0
PRODUCTVERSION 1, 0, BUILD, 0
FILEOS 4
FILETYPE 1
{
BLOCK "StringFileInfo"
{
BLOCK "040904B0"
{
VALUE "FileDescription", "program"
VALUE "OriginalFilename", "program.exe"
VALUE "CompanyName", "you"
VALUE "FileVersion", "Release"
VALUE "LegalCopyright", "Copyright (c) 2016, you, fool!"
VALUE "ProductName", "Yer proggie"
VALUE "ProductVersion", "Release"
}
}
BLOCK "VarFileInfo"
{
VALUE "Translation", 0x0409, 0x04B0
}
}
这里有一个更全面的版本:Versioning DLLs。顺便说一句:如果没有VarFileInfo块,它将无法工作。这个.rc用于右键单击并在Properties |中获取此信息细节。我有这个信息的M $ .rc文件和应用程序图标,并在资源下的Qt Creator中添加其他资源。
不是那么可选:这是我花了一些时间黑客找到的部分。在Qt Creator中,打开yer proj,单击小计算机图标并将其置于释放模式。点击&#34; Projects&#34;。单击&#34; Add Build Step&#34;,选择Custom Process Step,然后单击帽子图标&#34; ^&#34;直到它位于列表的顶部。假设你已经命名为yer .rc,&#34; myapp.rc&#34;。使构建步骤如下:
Command: cmd.exe
Arguments:/c build_inc.bat
Working Directory: %{CurrentProject:Path}
虽然基于qmake的版本可能在命令行或从IDE调用的命令行工具中运行良好,但在Qt Creator中,构建步骤更可取,我相信。 Qt Creator并没有为每个版本运行qmake;但每次构建都会运行构建步骤。
现在,将此添加到yer .pro文件中:
RC_FILE += myapp.rc
另外,将myapp.rc添加到你的项目中。它会出现在&#34;其他文件&#34;。
之下现在重建。每次重建都会触发资源文件的触摸,从而运行&#34; rc&#34;每次。否则,构建号码不会被编码到二进制权限中。它对我来说很快。每次重建都会增加这个数字。我只是将它们添加到&#34;发布&#34;建立;所以调试版本不会增加它。他们只使用最后一次构建的编号。我相信,你需要在发布时运行一次以避免错误。这在Qt Creator中没有单独重新运行qmake的情况下工作;每次都会给你一个不同的内部版本号。它不会触发任何其他重新编译。你有运行&#34; rc&#34;的开销。并且每次都要联系,而不是在一切都是最新的时候什么都不做;但OTOH,我只为发布版本而做;你几乎总是链接建立或运行无论如何;再一次,&#34; rc&#34;很快。
可选:您可以在任何位置移动BUILD预处理器符号。 #。 (注意:您还可以使用以下内容添加应用程序图标:
IDI_ICON1 ICON DISCARDABLE "Icons/myicon.ico"
这使得它甚至在文件运行之前就显示在资源管理器中。)
您还可以添加&#34; build.h&#34;你可以在Qt Creator中正式使用它,将它包含在你想要使用build#in的文件中,并将其用作字符串,例如用:
#include <QDebug>
#include "build.h"
#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)
qDebug() << QString("(build ")+STR(BUILD)+")";
我刚注意到一个副作用:如果你这样做,它将在Release中的每次运行之前重建。我想这付出的代价并不算太糟糕。我想我总是可以将运行时复制到release目录中,并从Explorer运行它;或者只是忍受我的about.h的额外编译,&#34; rc&#34;以及发布中每次运行的链接。就此而言,我可以创建一个外部工具来使用键盘快捷键来运行它。我对此有任何改进,我当然乐于接受。暂时,我不打扰,只是编译&#34; about.cpp&#34;,运行&#34; rc&#34;并且与每次运行相关联并不需要很长时间。人们:自动编号!
☮!
编辑:可选:为了使其仅在您构建或重建项目时增加构建号,而不是在您运行它时(即使构建将始终在发布中),请转到项目|构建并运行|运行,单击&#34;添加部署步骤&#34;并选择&#34;自定义流程步骤&#34;:
Command: cmd.exe
Arguments: /c if exist build.old copy /y build.old build.txt
Working Directory: %{CurrentProject:Path}
然后,添加
copy /y build.txt build.old
在.bat文件中关闭@echo后。尽管涉及到,但甚至可以制作自定义的新项目模板:Extending Qt Creator Manual
编辑:我现在已经使用了一个而不是两个自定义构建步骤。