4

I have several micro controller projects for home automation. Each of my nodes have a version number which is manually set in the code. This version number is reported during the startup of the node to inform me which code is running.

Sometimes changing the version number is forgotten after making some changes in the code. So an automatic solution has to be found.

I have some idea about the solution:

  1. create a file (version.h): #define BUILDNO xxx
  2. include it in the relevant c codes
  3. auto increment xxx before every build

Can it be implemented? Or are there any other solutions with similar result?

4

5 回答 5

9

我根据我的问题的答案进行了一些研究。PlatformIO 可以在编译前运行自定义脚本。以下是生成内部版本号并将其包含到项目代码中的过程:

  1. 在项目文件夹中创建一个 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)
  1. 在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 欢迎进一步的想法!

于 2019-07-08T23:18:03.070 回答
2

git describe我用PlatformIO 的高级脚本解决了这个问题。

首先,我使用它的项目严重依赖 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论坛帖子的副本:

https://community.platformio.org/t/how-to-build-got-revision-into-binary-for-version-output/15380/5?u=awbmilne

于 2021-04-01T21:28:55.560 回答
1

使用 C 或 C++ (Arduino) 时,您必须依赖预构建程序。您必须添加一个预构建程序,它使用简单的更新文件:

#define VERSION "1.0.0"

您的自动增量程序需要将当前版本存储在某个地方(最好在内部,version.h这样它就不会不同步)并在编译时读取、增量和存储它。

您可以使用来自vurdalakov的解决方案或使用 Makefiles的cplusadd.blogspot.com上的解决方案。

于 2019-07-08T08:39:57.070 回答
1

对于我的用例,我不一定需要一个始终增加 1的增量数字,但是任何一种升序数字都可以,因此使用 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"
于 2021-03-11T13:58:58.370 回答
0

我喜欢你的问题解决方案。但是基于源代码的版本号不是更有用吗?PlatformIO 有一个关于动态构建变量的部分,其中包含一个从 git 源版本https://docs.platformio.org/en/latest/projectconf/section_env_build.html#id4提取哈希的示例 (向下滚动到动态构建变量部分)

于 2020-08-02T10:21:38.980 回答