Qt Creator 中内部版本号自动递增

发布于 2024-08-04 19:05:10 字数 148 浏览 3 评论 0原文

我希望在 C++ 源代码中有一个变量(或 #define),每次使用 Qt Creator 构建源代码时该变量都会递增。有什么办法可以做到这一点,也许是一些 Qt Creator 插件或类似的?如果我在命令行上使用“make”来构建,是否有办法做到这一点?

I would like to have a variable (or #define) in C++ source that will increment each time I use Qt Creator to build source code. Is there any way I can do this, perhaps some Qt Creator plugin or similar? If there is a way to do it if I use "make" on command line to build?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

思慕 2024-08-11 19:05:11

在 .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

我应该注意,这会导致每次构建时构建编号都会递增,并且如果您尝试构建但失败,也会增加构建编号。更好的方法是根据代码的状态获取内部版本号,许多版本控制工具可以为您提供文本字符串(如果不是数字)。

In your .pro file, you can create a variable that contains the results of a command-line program. You can then use that to create a define.

BUILDNO = $(command_to_get_the_build_number)
DEFINES += BUILD=${BUILDNO}

If you just want a simple incrementing number, you could use a pretty simple script:

#!/bin/bash
number=`cat build_number`
let number += 1
echo "$number" | tee build_number #<-- output and save the number back to file

I should note that this would cause the build number to increment every time you build, and also increment if you try to build but it fails. A better way is to get a build number based on the state of the code, and many version control tools can get you a text string for that, if not a number.

⒈起吃苦の倖褔 2024-08-11 19:05:11

Joerg Beutel 改进的解决方案的 Windows 等效项 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;

The Windows equivalent for Joerg Beutel's improved solution 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%

Usage

#include "build.h"
...
qDebug() << "Build number:" << BUILD;
深爱不及久伴 2024-08-11 19:05:11

正如我之前所写的,经过一些测试后,我发现原来的解决方案有问题,因为每次新构建完成时版本号都没有更新。在很多情况下,我编辑了源文件,运行构建,但仍然得到相同的内部版本号...构建过程只是决定没有任何更改,并跳过将更新内部版本号的步骤。我首先尝试找到一种方法来强制执行这一步,但无法弄清楚。最后我决定走一条不同的路。现在我使用脚本生成头文件
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 的文件中。我本可以通过解析生成的头文件中的数字来避免第三个文件,但我决定不这样做。请注意,脚本和生成的标头位于项目目录中,而 build_number 文件位于构建目录中。这并不完美,但我可以忍受。

为了把事情整合在一起,现在还有一些事情要做。首先,需要将生成的头文件添加到 Qt Designer 中的项目中...右键单击“头文件”并选择“添加现有文件”。其次,它必须包含在访问内部 BUILD 定义的 C++ 文件中... #include "build_number.h" ...最后但并非最不重要的一些补充必须进行到项目文件 (MyProject.pro)。请注意,我从 Calebs 解决方案中删除了这些内容,因此我们从头开始:

build_nr.commands = ../MyProject/build_number.sh
build_nr.depends = FORCE
QMAKE_EXTRA_TARGETS += build_nr
PRE_TARGETDEPS += build_nr

这些行(我将它们放在 HEADERS 部分之前)强制执行脚本,该脚本从 build_number 读取最后一个内部版本号,递增它,将其写回并生成 build_number.h 文件的更新版本。由于这是项目源的一部分,因此新值每次都会链接到代码中。

有一点值得一提 - 现在构建过程永远认为没有任何改变。因此,即使您保持代码不变,新运行的 make 也会生成新的版本号并构建新的二进制文件。旧的解决方案在代码更改时留下了数字,即使源代码未更改,这个新的解决方案也会强制进行新的构建,因为我强制更改了该头文件。人们可能更喜欢介于两者之间的东西,但由于标头仅包含在一个位置,因此重建速度非常快并且不会造成太大影响。但是,如果有人知道如何两全其美,请提供建议。至少现在我不会有两个具有相同版本号的不同二进制文件。

As I wrote before after some testing I found that the original solution has a problem since the version number is not updated every time a new build is done. In a lot of cases I had edited a source file, run the build, but still got the same build number ... The building process just decided that nothing was changed and skipped the step which would have updated the build number. I first attempted to find a way to force that step, but couldn't figure it out. Finally I decided to go a different way. Now I use the script to generate a header file
build_number.h which contains a #define BUILD with the updated number behind. So Calebs script is now a bit modified (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

The incrementing number is still stored within a file called build_number. I could have avoided a third file by parsing the generated header-file for the number, but decided against it. Note that the script and the generated header are located in the projects directory while the build_number file is in the build directory. That's not perfect, but I can live with it.

In order to put things together there are now some more things to do. First the generated header-file needs to be added to the project in the Qt Designer ... Right-click on Header-Files and "Add existing file". Second, it has to be included in the C++-file where the BUILD define inside is accessed ... #include "build_number.h" ... and last but not least some additions have to be made to the project file (MyProject.pro). Note that I deleted the stuff from Calebs solution, so we start from scratch here :

build_nr.commands = ../MyProject/build_number.sh
build_nr.depends = FORCE
QMAKE_EXTRA_TARGETS += build_nr
PRE_TARGETDEPS += build_nr

These lines (I put them before the HEADERS section) force the execution of the script, which reads the last build number from build_number, increments it, writes it back and also generates an updated version of the build_number.h file. Since that's part of the source of the project the new value gets linked into the code every time.

There's one thing to mention - now the building process is never at the opinion that nothing has changed. So even if you leave your code unchanged a new run of make will generate a new version number and build a new binary. The old solution left the number when code changed, this new solution forces a new build even when the source is unchanged, since I force a change in that one header file. One would have prefered something in between but since the header is only included in one place the rebuild is very fast and doesn't hurt much. But still, if somebody knows how to get the best of both worlds please advise. At least now I'll not have two different binaries with the same version number.

只有一腔孤勇 2024-08-11 19:05:11

迦勒的建议很好,但对我来说并没有“开箱即用”。相反,我遇到了一些错误,需要阅读一些内容才能修复它们。变化非常小。我在 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 一样。

Caleb's suggestion is great, but didn't work "out of the box" in my case. I got some errors instead and it took some reading to fix them. The changes are very minor. I was using Qt 4.7 on Ubuntu Linux ... The first change, if you can believe it, was in the shell script to go from let number += 1 to let number++ ... I normally use/program Windoze, so I can't explain that, but when I run the script from a command line (shell prompt) in the original case I get errors reported, in the changed case all goes well and incrementing numbers are returned ...

Since it's not completely reported by Caleb - I used build_number.sh as the name of the shell script and made another file with the name build_number (without .sh) and put just a zero inside, nothing else.

The last and most obnoxious bug was fixed by replacing BUILDNO = $$(command_to_get_the_build_number) with BUILDNO = $$system(./build_number.sh) in the Qt project file. Note the system after $$ and the required ./ in front of the file name. The later is elementary for a regular Linux user, but not as much so for a Windows user.

Hope this makes it more straight forward for people new to all this, like myself. You can read more in the Qt Designer Help section if you seek for qmake, including the function reference, Advanced Use etc.

Oh, one last word ... I also had to change DEFINES += -DBUILD=$${BUILDNO} to DEFINES += BUILD=$${BUILDNO}, so the -D is gone. Inside your C++ code you would use BUILD as if you had written #define BUILD 1234 at the top of your file.

柠檬色的秋千 2024-08-11 19:05:11

这是我根据handle的解决方案提出的Win7解决方案。
当您右键单击您的目标并选择“属性”|“此解决方案”时,此解决方案还会使 Windows 提供您的版本号。细节。它适用于 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

并将其放入你的 proj 文件夹中。 (copy /b myapp.rc +,, 是难以理解的 Microsoft 语言中的“触摸”- 更新文件的时间戳。)到目前为止,一切顺利 - 那又怎样?!

如果您不需要将版本编码到二进制文件中,则此部分是可选的。创建一个 .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
    }
}

这里提供了更完整的版本:版本控制 DLL< /a>.顺便说一句:如果没有 VarFileInfo 块,它将无法工作。此 .rc 用于右键单击并在属性 | 中获取此信息之类的内容。细节。我有一个用于此信息和应用程序图标的 M$ .rc 文件,并在 Qt Creator 的资源下添加其他资源。

不是那么可选:这是我花了一些时间寻找的部分。在 Qt Creator 中,打开您的项目,单击小计算机图标并将其置于发布模式。单击“项目”。单击“添加构建步骤”,选择“自定义流程步骤”,然后单击帽子图标“^”,直到它位于列表顶部。假设您已将 .rc 命名为“myapp.rc”。使构建步骤如下:

Command: cmd.exe
Arguments:/c build_inc.bat
Working Directory: %{CurrentProject:Path}

虽然基于 qmake 的版本可能在命令行或从 IDE 调用的命令行工具中运行良好,但我相信在 Qt Creator 中,构建步骤更好。 Qt Creator 实际上并不为每个构建运行 qmake;而是为每个构建运行 qmake。但每次构建都会运行构建步骤。

现在,将其添加到您的 .pro 文件中:

RC_FILE +=  myapp.rc

另外,将 myapp.rc 添加到您的项目中。它会显示在“其他文件”下。

现在重建。每次重建都会触发资源文件的触摸,从而每次都运行“rc”。否则,内部版本号将不会被编码到二进制文件中。它对我来说运行得很快。每次重建都会增加这个数字。我只是费心将它们添加到“发布”版本中;所以调试版本不会增加这个。他们只会使用最后一次构建的编号。我相信,您需要在发布时运行一次以避免错误。这无需每次在 Qt Creator 中单独重新运行 qmake 即可工作;并每次都会给你一个不同的内部版本号。它不会触发任何其他重新编译。您每次都会有运行“rc”和链接的开销,而不是如果一切都是最新的则什么也不做;但是OTOH,我只为发布版本这样做;无论如何,您几乎总是链接构建或运行;再说一次,“rc”很快。

可选:您可以将 BUILD 预处理器符号移动到您想要的位置。 #. (注意:您还可以添加您的应用程序图标,如下所示:

IDI_ICON1 ICON DISCARDABLE "Icons/myicon.ico"

这使得它甚至在文件运行之前就显示在资源管理器中。)

您还可以在 Qt Creator 中正式将“build.h”添加到您的项目中,将其包含在一个你想要使用 build # 的文件,并将其用作字符串,例如:

#include <QDebug>
#include "build.h"

#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)

qDebug() << QString("(build ")+STR(BUILD)+")";

我刚刚注意到一个副作用:如果你这样做,它将在每次运行 Release 之前重建。我想这并不算太糟糕的代价。我想我总是可以将运行时复制到发布目录中,然后从资源管理器运行它;或者只是忍受我的 about.h 的额外编译、“rc”的运行以及版本中每次运行的链接。就此而言,我可以创建一个外部工具来使用键盘快捷键运行它。我当然愿意接受对此的任何改进。目前,我不打扰,因为仅仅编译“about.cpp”,运行“rc”并与每次运行链接并不需要很长时间。尽管如此,人们:自动构建编号!

☮!

编辑:可选:为了让它仅在构建或重建项目时增加内部版本号,而不是在运行项目时增加内部版本号(即使构建始终会在发布中发生),请转到项目 |构建并运行 |运行,点击“添加部署步骤”并选择“自定义流程步骤”:

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 off后面 。尽管涉及,甚至可以制作自定义的新项目模板: 扩展Qt Creator 手册

编辑:我现在已经使它可以通过一个而不是两个自定义构建步骤来工作。

Here's a solution for Win7 I came up with based on handle's solution.
This solution also makes Windows give yer version # when you right-click yer target, and choose Properties | Details. It works in Win7, and probably most earlier versions.

Ok, you make yer 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

and put it in yer proj folder. (copy /b myapp.rc +,, is inscrutable Microsoft-eese for "touch" - to update a file's time-stamp.) So far, so good - so what?!!

This part is optional, if you don't need the version encoded into the binary. Create a .rc file, e.g.:

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

A more full-blown version is available here: Versioning DLLs. BTW: It won't work without the VarFileInfo block. This .rc is used for stuff like right-clicking and getting this info in Properties | Details. I have both a M$ .rc file for this info and the app icon, and add other resources in Qt Creator under Resources.

Not so optional: Here's the part I've spent some time hacking to find. In Qt Creator, with yer proj opened, click the little computer icon and put it in release mode. Click on "Projects". Click on "Add Build Step", choose Custom Process Step, and click the hat icon "^" until it is at the top of the list. Say you've named yer .rc, "myapp.rc". Make tha build step read as follows:

Command: cmd.exe
Arguments:/c build_inc.bat
Working Directory: %{CurrentProject:Path}

While a qmake-based version might work well from the command line or command line tools called from an IDE, in Qt Creator, the build steps are preferable, I believe. Qt Creator doesn't actually run qmake for each build; but build steps are run every build.

Now, add this to yer .pro file:

RC_FILE +=  myapp.rc

Also, add myapp.rc to yer proj. It'll show up under "Other Files".

Now rebuild. Every rebuild will trigger a touch of the resource file, thereby running "rc" every time. Otherwise, the build number won't get encoded into the binary right. It runs quickly for me. Every rebuild will increment this number. I've only bothered to add them to the "Release" build; so debug builds don't increment this. They'll just use the number of the last build. You will need to run it once in release to avoid an error, I believe. This works without separately re-running qmake each time in Qt Creator; and gives you a different build number each time. It doesn't trigger any other recompiles. You have the overhead of running "rc" and linking each time, as opposed to doing nothing if everything is up to date; but OTOH, I do it for release builds only; you almost always link for a build or run anyway; and again, "rc" is fast.

Optional: You can move the BUILD preprocessor symbol wherever you want in yer vers. #. (Note: You can also add yer app icon with something like this:

IDI_ICON1 ICON DISCARDABLE "Icons/myicon.ico"

This makes it show up in Explorer even before the file is run.)

You can also add "build.h" to yer proj formally in Qt Creator, include it in a file you want to use the build # in, and use it as a string, e.g. with:

#include <QDebug>
#include "build.h"

#define STR_EXPAND(tok) #tok
#define STR(tok) STR_EXPAND(tok)

qDebug() << QString("(build ")+STR(BUILD)+")";

I just noticed a side effect: If you do it this way, it will rebuild before every run in Release. I guess that's not too bad a price to pay. I guess I can always copy the runtimes into the release directory, and run it from Explorer; or just put up with the extra compile of my about.h, the run of "rc" and the link with each run in release. For that matter, I could just create an external tool to run it with a keyboard shortcut. I'm certainly open to any improvements on this. For the time being, I'm not bothering, as just compiling "about.cpp", running "rc" and linking with every run doesn't take very long. Still, people: automatic build numbers!

☮!

Edit: Optional: In order to get it to increment the build number only when you build or rebuild your project, but not when you run it (even though a build will always occur in Release), go to Projects | Build and Run | Run, click "Add a Deploy Step" and choose "Custom Process Step":

Command: cmd.exe
Arguments: /c if exist build.old copy /y build.old build.txt
Working Directory: %{CurrentProject:Path}

Then, add

copy /y build.txt build.old

after @echo off in the .bat file. It is even possible, although involved, to make custom new project templates: Extending Qt Creator Manual

Edit: I've now made it work with one, not two, custom build steps.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文