I solved this problem with
git describe and the advanced scripting.
First off, I use git tags for versioning. I dont bother with manually writing it anywhere, it should all be based on the git tags. This makes CI and such really easy, Since I never forget to update the version in some file somewhere.
Here is an example:
platform = teensy
board = teensy40
framework = arduino
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)
serial.print("Firmware Version: ");
serial.println(AUTO_VERSION); // Use the preprocessor directive
// OR //
char firmware_char_array = AUTO_VERSION;
With this configuration, you get the firmware version as a string literal. You can use it however you want since it is dealt with in the preprocessor and not compiler.
This, for example, will print the tag that the commit is aligned with:
or, if there isnt a tag at the commit, the relation to the latest tag:
└────┤ └┤ └─────┴─ Short commit Hash (not the g)
│ └─ Distance from tag
└─ Latest Tag in Git
You can customize this string however you like in the python script, For example:
build_version = "My_Project_Firmware-" + ret.stdout.strip() + "-" + env['PIOENV'].upper()
I use the
env['PIOENV'] to distinguish between different build environments, Useful if you have regular builds and debug builds.