This year I have started writing apps for my Pebble. One of the first things that I usually do is put in some kind of “About…” screen so I can easily tell what version of the code I am using.  The about screen for wrist-spin looks like this

pebble_screenshot_2016-10-22_16-37-11

As often happens on a new platform its the simplest things that trip me up. The version number (versionLabel) used in the Pebble app that is published is stored in an appinfo.json file like this

{
  "uuid": "00000000-0000-0000-0000-000000000000",
  "shortName": "wrist-spin",
  "longName": "Wrist Spin",
  "companyName": "Derek Wilson",
  "versionCode": 13,
  "versionLabel": "1.4",
  "sdkVersion": "3",
  "targetPlatforms": ["aplite", "basalt", "chalk"],
  "watchapp": {
    "watchface": false
  },

The first mechanism I tried from a question on stackoverflow was to modify the build script (wscript) like this

def build(ctx):
    ctx.load('pebble_sdk')

    def generate_appinfo(task):
        src = task.inputs[0].abspath()
        tgt = task.outputs[0].abspath()

        json_data=open(src)
        data = json.load(json_data)

        f = open(tgt,'w')
        f.write('#ifndef appinfo_h\n')
        f.write('#define appinfo_h\n')
        f.write('#define VERSION_LABEL "' + data["versionLabel"] + '"\n')
        f.write('#endif\n')
        f.close()

    ctx(
        rule   = generate_appinfo,
        source = 'appinfo.json',
        target = 'appinfo.h',
    )

    build_worker = os.path.exists('worker_src')
    binaries = []

    for p in ctx.env.TARGET_PLATFORMS:
        ctx.set_env(ctx.all_envs[p])
        ctx.set_group(ctx.env.PLATFORM_NAME)
        app_elf='{}/pebble-app.elf'.format(ctx.env.BUILD_DIR)
        ctx.pbl_program(source=ctx.path.ant_glob('src/**/*.c','generated/**/*.c'),
        target=app_elf)

        if build_worker:
            worker_elf='{}/pebble-worker.elf'.format(ctx.env.BUILD_DIR)
            binaries.append({'platform': p, 'app_elf': app_elf, 'worker_elf': worker_elf})
            ctx.pbl_worker(source=ctx.path.ant_glob('worker_src/**/*.c'),
            target=worker_elf)
        else:
            binaries.append({'platform': p, 'app_elf': app_elf})

    ctx.set_group('bundle')
    ctx.pbl_bundle(binaries=binaries, js=ctx.path.ant_glob('src/js/**/*.js'))

To produce a file called appinfo.h which I can then include like this

#include 

#include "globals.h"

static char versionBuffer[10];

#include "appinfo.h"

void init_version() {
    snprintf(versionBuffer,sizeof(versionBuffer),"%s",VERSION_LABEL);
}

char* get_version() {
    return versionBuffer;
}

It does work, sort of. If you clean the project then the generated file is deleted and sometimes the script attempted to compile the code before the header has been generated. Often running the build twice seemed to get it to work, but not always.

So I tried a different mechanism suggested on the pebble dev forums.

#include 

#include "globals.h"

static char versionBuffer[10];

/* 
 * using the hacky method described here
 * https://forums.getpebble.com/discussion/10405/how-can-i-get-my-app-version-in-c-code
 */ 
#include "pebble_process_info.h"
extern const PebbleProcessInfo __pbl_app_info;
void init_version() {
    snprintf(versionBuffer,sizeof(versionBuffer),"%d.%d%s",
        __pbl_app_info.process_version.major, 
        __pbl_app_info.process_version.minor,
        "" 
    );
}

char* get_version() {
    return versionBuffer;
}

This looks a bit more hacky but seems to work just fine.