Monday, November 5, 2012

Auto-Incrementing Build Number in MPLABX

I must admit that I like a lot of the new features available in MPLABX. I used MPLAB for years and always felt it very lacking in the code editing department. MPLABX is much better in that regard although I still use Sublime Text 2 to do most of my source file editing. One of my favorite features of MPLABX is the build system being based on makefiles.

What Is It?

So the first question is what is an an auto-incrementing build number? Well, there are really two aspects to this as far as I'm concerned. The first is a definition that is available from within your source code so if you were to use a define like BUILD_NUMBER it would evaluate to the current build. This is handy for printing out the current build without having to change a hard-coded number somewhere. While that's nice I'm more interested in the other use of a build number which is in naming the output file. I wrote an SD bootloader that parses the name of the target hex file and determines if it's a newer version than that currently loaded. To accomplish this I use a specific naming convention of v[major]_[minor]_[build].hex. Instead of having to rename the output from MPLABX every time I like it to just assign a new name automatically each time I build.

Give Me The Code

My current implementation currently only increments the build number and is meant to run in a Windows environment. This is much easier to accomplish on a *nix machine. I do this because I want to control when the major and minor versions roll. The implementation is quite simple and you can modify it to suite your specific needs. The first thing you will need to do is find the .X folder created by MPLABX. It defaults to a name like [Project Name].X. In that folder there is a file named Makefile.

  1. Open Makefile in a text editor
  2. In the .build-post: section simply add a call to a batch script we will create called deploy.cmd (remember to indent it properly per the makefile syntax)
      call deploy.cmd
  3. Create a new file named deploy.cmd in the same folder as Makefile and add the following code
    setlocal enabledelayedexpansion
    set major=0
    set minor=0
    set buildnum=
    del /Q ..\bin\*.*
    for /f "delims=;" %%i in (build_number.txt) do set buildnum=%%i
    cp dist/default/production/piclibs.X.production.hex ../bin
    mv ../bin/piclibs.X.production.hex ../bin/v%major%_%minor%_%buildnum%.hex
    @echo ===============================================================
    @echo Created new firmware version: v%major%_%minor%_%buildnum%.hex 
    @echo ===============================================================
    set /a buildnum=%buildnum% + 1
    @echo %buildnum%;> build_number.txt
  4. Change the cp and mv lines to match the default name of your production output hex file
  5. Save and close deploy.cmd
  6. Create a file named build_number.txt in the same directory as Makefile and deploy.cmd
  7. Add the starting build number followed by a semicolon. Save and close.

That's it. When you build you'll get a file in your output directory (defined in deploy.cmd) that is appropriately named and it will increment the build number in build_number.txt.

Customize It

All of the magic happens in deploy.cmd which is simply a batch script that is run by the make process after a successful build. We hard code the major and minor version numbers in deploy.cmd with set statements so you can change those just by altering the assignments.

set major=0
set minor=0

I like to output my production files outside of the MPLABX folder because I don't like the nested location and I don't like the name it assigns. I like my outputs to be in a bin folder at the root of my project. You can alter this behavior by modifying the copy and move statements in deploy.cmd. You can also modify the name of your output file by modify the second half of the move line. If you have any suggestions or better approaches feel free to send me a message or post a comment.


  1. Hi

    Thanks for a great article. Do you have an example makefile for this, I can't seem to get the call syntax correct, I'm a makefile noob though..


    1. I sent you an email with an example project. Let me know if you have any issues or questions.

  2. This comment has been removed by the author.


Keep it clean and civil. That's all I ask.