Touch & Build: Auto-Update of Firmware Date and Time

It is very valuable to have a date and time information in the binary. That way for example using a shell I can check the version of the firmware running on a device, or it can be printed on a console or UART as needed.

Firmware Date and Time

Firmware Date and Time

The C/C++ language offers to macros which represent date and time.

__DATE__
__TIME__

They can be used directly or used with a pointer like below:

static const char *const FW_Date = __DATE__;
static const char *const FW_Time = __TIME__;

However, they match the date and time the when the file (or compilation unit) has been compiled. If that file is not recompiled, it keeps the ‘old’ date and time.

Alternatively, gcc provides the __TIMESTAMP__ macro which could be used, see GCC macros help page.

But for a firmware version I would like to have the latest date & time of it. Sure I could delete the object file or do a clean and a full build.

A more elegant solution is to ‘touch’ (or change) the file containing the date/time information. On Linux or a ‘bare’ make or cmake build I could use the ‘touch’ command for this, and that file will be recompiled.

On Windows and including Eclipse (MCUXpresso IDE in this case) it is very easy too: I can setup a pre-build step which touches the file I need to rebuild, and it gets recompiled every time I do a build: exactly what I need :-).

Go to the project settings, C/C++ Build, Settings and then edit the Pre-Build steps in the Build Steps tab:

Pre-build Step to touch a file

Pre-build Step to touch a file

Use the touch command to touch a file, e.g.

touch ../source/main.c

πŸ’‘ Make sure that there is line ending (CR/Return) at the end of the line!

The current directory is the build output directory, e.g. ‘Debug’.

That way I can always trigger a ‘touch & build’:

Touch and Build

Touch and Build

It is possible to use Eclipse Build variables too, for example if I would like to delete the ELF/Dwarf (Output binary) I could use

rm "${BuildArtifactFileName}"

And then this will cause the following build at least to re-link the binary.

Happy Dating πŸ™‚

Links

15 thoughts on “Touch & Build: Auto-Update of Firmware Date and Time

  1. Hi Erich,
    this is a very good idea! I normally store my sw ver in the code, but for example during development, you don’t update that value for each change, while this mechanism does!
    Of course also very useful the touch command! πŸ‘
    As always, many thanks for sharing this useful tips!
    Ale

    Liked by 1 person

    • I was first not aware that I could use the Linux touch command on Windows, so this is a great thing to have. The good thing is that with the pre-build step you can pretty much do whatever you want.

      Like

    • Agreed, deterministic is always good. The preferred way to have the production build deterministic is using a dedicated build server, and there you will do a ‘clean’ anyway before starting a build.
      The approach with the touch is just one example how to use a pre-build: you can pretty much do anything needed, depending on the development flow.

      Like

      • I prefer everyone being able to build ‘exactly’ the same binary if using the same build tools (and version) – even years later. That is why i never use these kind of preprocessor macros in source code.

        Liked by 2 people

  2. Hadn’t realized the date wouldn’t change every day, I’ll have to watch for that on my one project that uses __DATE__.
    Mostly we have menu files compiled from “source” created with our own “language” so I added a date function to that tool we use, along with a “once-per-day” trick to make it work. This method is easier for sure.

    I guess you could “rm main.o” instead of touching main.c (does touch keep changing the last change time of the file?)

    Liked by 1 person

    • __DATE__ is supplied by the compiler using the host system date, so it will change as it changes on the host and uses what value it has at compile time.
      And yes, you could remove main.o too that way. If you have release and build configurations (or other configurations), then you need to make sure it deletes the right one.
      And yes, touch changes the modification date of the file, triggering a re-build. I used main.c for demo purpose here, other than that I have version information in a ‘version.h’ file which I can touch too.

      Liked by 1 person

  3. I’ve been using this trick for a few years, and it’s very handy. On a recent HDD update ‘touch’ no longer works; turns out it was only working before because of some other software package that was installed, separate from CW (oh yeah, I use CW 10.7). So I had to do a few tricks, and that made it cumbersome; I couldn’t get it to just ‘work’ again, and error output is minimal for diagnosis.

    The other thing I did is to add ” & time &” at the end of post-build steps, so if I forget if I’ve compiled or not, I can see the last time it actually finished.

    Liked by 1 person

  4. Hi Rhys,
    good suggestion to add the time to the post build step. About ‘touch’ on Windows: it is not installed anywhere on my system (I cannot use it from a cmd). The IDE has some Linux like tools installed in \ide\buildtools\bin such as cp, echo, make, mkdir, mv, rm und sh. But no touch. The IDE says that it is executing a linux-like shell but not sure if it is built into sh or not.

    Like

    • Update: ‘touch’ is indeed part of the sh in \ide\buildtools\bin. You can verify this with launching a command prompt there, type sh and it will run a linux shell which has touch implemented, along with many more commands. I get the article updates with this information πŸ™‚

      Like

  5. Pingback: Using Linux Shell Commands on Windows with MCUXpresso Pre-/Post-Build Steps | MCU on Eclipse

  6. I usually do a prebuild step, where I generate from my CVS (which is usually git) the commit id into a c file, which is compiled into the project.
    With git this usually would be the first 8 digits of the git hash.
    Also very important is to store the state of the repo, whether it has modifications or not.
    This way the build is both reproducible, and trackable.

    I definitely know which commit was used to build it.
    As usually an IDE comes with a Debug and Release build option, it is also good practice to store this information into the binary.

    This eliminates the ever occurring question: Which HW did I just test in the cryo chamber for the last 2 weeks? No worries, just read out the information which was baked into it.

    If one takes these matters seriously, then the build is done with a toolchain which is versioned with conan for example.
    Because even if you know which git commit you used to build, do you really remember in 5 years, which exact IDE version you used. Every update might bring a new toolchain version.

    Liked by 1 person

    • Agreed, a version control system is essential for any reproducible build. Storing the build environment is is important too. What we did in a previous company I worked with was that we stored away the build machine doing the final build: that way we had exactly the environment (host operating system, tools installed, etc) to be able to reproduce the production build for up to 15 years. The issue sometimes was that the host machine was not made to survive 15 years (capacitors on the board, etc), so in addition to that the complete image(s) were stored independently too.

      Like

  7. Problem with this is, that if using CDT, the touch is after the moment that CDT has determined what to compile. So you can get the date/time of a previous build (attempt).
    I solved this by making a small program which makes a file which is included in the linker ‘ld’ file.
    In the prebuild phase it runs, and defines some global variables which hold build time/version information. These can then be referred in the source code.

    Liked by 1 person

    • That’s an interesting point, I have not observed that (yet). The solution with the symbols for the link phase/linker files sounds a good solution to me too, so thanks for that suggestion

      Like

What do you think?

This site uses Akismet to reduce spam. Learn how your comment data is processed.