使用 PlatformIO 自动增加内部版本号
Auto increment build number using PlatformIO
我有几个用于家庭自动化的微控制器项目。我的每个节点都有一个在代码中手动设置的版本号。这个版本号是在节点启动的时候上报的,告诉我哪个代码是运行.
有时在对代码进行一些更改后忘记更改版本号。所以必须找到一个自动解决方案。
我对解决方案有一些想法:
- 创建文件 (version.h): #define BUILDNO xxx
- 将其包含在相关的c代码中
- 每次构建前自动递增 xxx
能实现吗?或者有没有其他类似结果的解决方案?
使用 C 或 C++ (Arduino) 时,您必须依赖 pre-build 程序。您必须添加一个 pre-build 程序,该程序使用简单的更新文件:
#define VERSION "1.0.0"
您的自动递增程序需要将当前版本存储在某处(最好在 version.h
内,这样它就不会不同步)并在编译时读取、递增和存储它。
您可以使用 vurdalakov or this one on cplusadd.blogspot.com 中使用 Makefile 的解决方案。
我根据我的问题的答案做了一些研究。 PlatformIO 可以在编译前 运行 自定义脚本。以下是生成内部版本号并将其包含到您的项目代码中的过程:
- 在项目文件夹中创建一个 Python 脚本:buildscript_versioning.py
FILENAME_BUILDNO = 'versioning'
FILENAME_VERSION_H = 'include/version.h'
version = 'v0.1.'
import datetime
build_no = 0
try:
with open(FILENAME_BUILDNO) as f:
build_no = int(f.readline()) + 1
except:
print('Starting build number from 1..')
build_no = 1
with open(FILENAME_BUILDNO, 'w+') as f:
f.write(str(build_no))
print('Build number: {}'.format(build_no))
hf = """
#ifndef BUILD_NUMBER
#define BUILD_NUMBER "{}"
#endif
#ifndef VERSION
#define VERSION "{} - {}"
#endif
#ifndef VERSION_SHORT
#define VERSION_SHORT "{}"
#endif
""".format(build_no, version+str(build_no), datetime.datetime.now(), version+str(build_no))
with open(FILENAME_VERSION_H, 'w+') as f:
f.write(hf)
- 在platformio.ini中添加一行:
extra_scripts =
pre:buildscript_versioning.py
构建您的项目将 运行 脚本。将创建 2 个文件:
版本控制:一个简单的文本文件,用于存储最后的内部版本号
include/version.h:要包含的头文件
现在您可以将此行添加到您的 C 代码中:
#include <version.h>
我在这里创建了一个带有一些文档的 gitlab 存储库:https://gitlab.com/pvojnisek/buildnumber-for-platformio/tree/master
欢迎进一步的想法!
我喜欢你的解决方案。但是基于源代码的版本号不是更有用吗? PlatformIO 有一个关于动态构建变量的部分,其中包含一个从 git 源版本中提取哈希的示例
https://docs.platformio.org/en/latest/projectconf/section_env_build.html#id4(向下滚动到动态构建变量部分)
对于我的用例,我 不需要 一定需要一个递增的数字,即 总是增加一个,但任何一种升序numbers 很好,因此使用 timeticks 对我来说很好。
在你的platformio.ini中:
[common]
firmware_version = '"0.1.0+${UNIX_TIME}"'
[env:release]
build_flags =
-D FIRMWARE_VERSION=${common.firmware_version}
这将为您提供以下格式的宏定义:
#define FIRMWARE_VERSION "0.1.0+1615469592"
我用 git describe
和 PlatformIO 的 advanced scripting 解决了这个问题。
首先,我使用它的项目在很大程度上依赖于 git 标签进行版本控制。在我看来,在多个地方手动跟踪版本号是一件痛苦的事情,它应该都基于 git 标签。这使得 CI 等非常容易,因为我永远不会忘记在某个地方更新某个文件中的版本,它只需要引用 git 标签(github/gitlab 上的正则表达式保护标签也有帮助).
使用git describe
,我们可以将提交描述注入到 PIO 构建中。
这是一个例子:
platformio.ini
[env:my_env]
platform = teensy
board = teensy40
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
auto_firmware_version.py
import subprocess
Import("env")
def get_firmware_specifier_build_flag():
ret = subprocess.run(["git", "describe"], stdout=subprocess.PIPE, text=True) #Uses only annotated tags
#ret = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, text=True) #Uses any tags
build_version = ret.stdout.strip()
build_flag = "-D AUTO_VERSION=\\"" + build_version + "\\""
print ("Firmware Revision: " + build_version)
return (build_flag)
env.Append(
BUILD_FLAGS=[get_firmware_specifier_build_flag()]
)
main.cpp
#include <Arduino.h>
void setup(){
serial.begin(115200);
serial.print("Firmware Version: ");
serial.println(AUTO_VERSION); // Use the preprocessor directive
// OR //
char firmware_char_array[] = AUTO_VERSION;
serial.println(firmware_char_array, sizeof(firmware_char_array));
}
void loop(){
// Loop
}
使用此配置,您可以获得字符串文字形式的固件版本。您可以随意使用它,因为它是在预处理器而不是编译器中处理的。
例如,这将打印提交对齐的标签:
v1.2.3
或者,如果提交时没有标签,则与最新标签的关系:
v1.2.3-13-gabc1234
└────┤ └┤ └─────┴─ Short commit Hash (not the g)
│ └─ Distance from tag
└─ Latest Tag in Git
您可以在 python 脚本中随意自定义此字符串,例如:
build_version = "My_Project_Firmware-" + ret.stdout.strip() + "-" + env['PIOENV'].upper()
会产生:
My_Project_Firmware-v1.2.3-13-gabc1234-MY_ENV
我使用 env['PIOENV']
来区分不同的构建环境,如果您有常规构建和调试构建,这很有用。
主要是 platformIO 论坛的副本 post:
autoinc-semver也是一个很好的解决方法。
您只需在您的代码中包含 version.h
文件,如下所示。
#define _VERSION_MAJOR 0
#define _VERSION_MINOR 0
#define _VERSION_PATCH 1
#define _VERSION_BUILD 41
#define _VERSION_DATE 04-07-2020
#define _VERSION_TIME 14:40:18
#define _VERSION_ONLY 0.0.1
#define _VERSION_NOBUILD 0.0.1 (04-07-2020)
#define _VERSION 2.0.3+41 (04-07-2020)
然后您只需将 semver-build.bat ./version.h
或 semver-build.sh ./version.h
命令作为 pre-built 选项添加到您的编译环境。
我有几个用于家庭自动化的微控制器项目。我的每个节点都有一个在代码中手动设置的版本号。这个版本号是在节点启动的时候上报的,告诉我哪个代码是运行.
有时在对代码进行一些更改后忘记更改版本号。所以必须找到一个自动解决方案。
我对解决方案有一些想法:
- 创建文件 (version.h): #define BUILDNO xxx
- 将其包含在相关的c代码中
- 每次构建前自动递增 xxx
能实现吗?或者有没有其他类似结果的解决方案?
使用 C 或 C++ (Arduino) 时,您必须依赖 pre-build 程序。您必须添加一个 pre-build 程序,该程序使用简单的更新文件:
#define VERSION "1.0.0"
您的自动递增程序需要将当前版本存储在某处(最好在 version.h
内,这样它就不会不同步)并在编译时读取、递增和存储它。
您可以使用 vurdalakov or this one on cplusadd.blogspot.com 中使用 Makefile 的解决方案。
我根据我的问题的答案做了一些研究。 PlatformIO 可以在编译前 运行 自定义脚本。以下是生成内部版本号并将其包含到您的项目代码中的过程:
- 在项目文件夹中创建一个 Python 脚本:buildscript_versioning.py
FILENAME_BUILDNO = 'versioning'
FILENAME_VERSION_H = 'include/version.h'
version = 'v0.1.'
import datetime
build_no = 0
try:
with open(FILENAME_BUILDNO) as f:
build_no = int(f.readline()) + 1
except:
print('Starting build number from 1..')
build_no = 1
with open(FILENAME_BUILDNO, 'w+') as f:
f.write(str(build_no))
print('Build number: {}'.format(build_no))
hf = """
#ifndef BUILD_NUMBER
#define BUILD_NUMBER "{}"
#endif
#ifndef VERSION
#define VERSION "{} - {}"
#endif
#ifndef VERSION_SHORT
#define VERSION_SHORT "{}"
#endif
""".format(build_no, version+str(build_no), datetime.datetime.now(), version+str(build_no))
with open(FILENAME_VERSION_H, 'w+') as f:
f.write(hf)
- 在platformio.ini中添加一行:
extra_scripts =
pre:buildscript_versioning.py
构建您的项目将 运行 脚本。将创建 2 个文件:
版本控制:一个简单的文本文件,用于存储最后的内部版本号
include/version.h:要包含的头文件
现在您可以将此行添加到您的 C 代码中:
#include <version.h>
我在这里创建了一个带有一些文档的 gitlab 存储库:https://gitlab.com/pvojnisek/buildnumber-for-platformio/tree/master 欢迎进一步的想法!
我喜欢你的解决方案。但是基于源代码的版本号不是更有用吗? PlatformIO 有一个关于动态构建变量的部分,其中包含一个从 git 源版本中提取哈希的示例 https://docs.platformio.org/en/latest/projectconf/section_env_build.html#id4(向下滚动到动态构建变量部分)
对于我的用例,我 不需要 一定需要一个递增的数字,即 总是增加一个,但任何一种升序numbers 很好,因此使用 timeticks 对我来说很好。
在你的platformio.ini中:
[common]
firmware_version = '"0.1.0+${UNIX_TIME}"'
[env:release]
build_flags =
-D FIRMWARE_VERSION=${common.firmware_version}
这将为您提供以下格式的宏定义:
#define FIRMWARE_VERSION "0.1.0+1615469592"
我用 git describe
和 PlatformIO 的 advanced scripting 解决了这个问题。
首先,我使用它的项目在很大程度上依赖于 git 标签进行版本控制。在我看来,在多个地方手动跟踪版本号是一件痛苦的事情,它应该都基于 git 标签。这使得 CI 等非常容易,因为我永远不会忘记在某个地方更新某个文件中的版本,它只需要引用 git 标签(github/gitlab 上的正则表达式保护标签也有帮助).
使用git describe
,我们可以将提交描述注入到 PIO 构建中。
这是一个例子:
platformio.ini
[env:my_env]
platform = teensy
board = teensy40
framework = arduino
extra_scripts =
pre:auto_firmware_version.py
auto_firmware_version.py
import subprocess
Import("env")
def get_firmware_specifier_build_flag():
ret = subprocess.run(["git", "describe"], stdout=subprocess.PIPE, text=True) #Uses only annotated tags
#ret = subprocess.run(["git", "describe", "--tags"], stdout=subprocess.PIPE, text=True) #Uses any tags
build_version = ret.stdout.strip()
build_flag = "-D AUTO_VERSION=\\"" + build_version + "\\""
print ("Firmware Revision: " + build_version)
return (build_flag)
env.Append(
BUILD_FLAGS=[get_firmware_specifier_build_flag()]
)
main.cpp
#include <Arduino.h>
void setup(){
serial.begin(115200);
serial.print("Firmware Version: ");
serial.println(AUTO_VERSION); // Use the preprocessor directive
// OR //
char firmware_char_array[] = AUTO_VERSION;
serial.println(firmware_char_array, sizeof(firmware_char_array));
}
void loop(){
// Loop
}
使用此配置,您可以获得字符串文字形式的固件版本。您可以随意使用它,因为它是在预处理器而不是编译器中处理的。
例如,这将打印提交对齐的标签:
v1.2.3
或者,如果提交时没有标签,则与最新标签的关系:
v1.2.3-13-gabc1234
└────┤ └┤ └─────┴─ Short commit Hash (not the g)
│ └─ Distance from tag
└─ Latest Tag in Git
您可以在 python 脚本中随意自定义此字符串,例如:
build_version = "My_Project_Firmware-" + ret.stdout.strip() + "-" + env['PIOENV'].upper()
会产生:
My_Project_Firmware-v1.2.3-13-gabc1234-MY_ENV
我使用 env['PIOENV']
来区分不同的构建环境,如果您有常规构建和调试构建,这很有用。
主要是 platformIO 论坛的副本 post:
autoinc-semver也是一个很好的解决方法。
您只需在您的代码中包含 version.h
文件,如下所示。
#define _VERSION_MAJOR 0
#define _VERSION_MINOR 0
#define _VERSION_PATCH 1
#define _VERSION_BUILD 41
#define _VERSION_DATE 04-07-2020
#define _VERSION_TIME 14:40:18
#define _VERSION_ONLY 0.0.1
#define _VERSION_NOBUILD 0.0.1 (04-07-2020)
#define _VERSION 2.0.3+41 (04-07-2020)
然后您只需将 semver-build.bat ./version.h
或 semver-build.sh ./version.h
命令作为 pre-built 选项添加到您的编译环境。