I wasn't aware of the print rule either, and came up with a somewhat convoluted solution which may be of help.

It's essentially just a bash script which generates the file in a destination made by mktemp, then compares the temporary file with the destination, and updates if necessary.

It has to be run in the Jamroot, not in a lower level Jamfile because jam globbing doesn't pick up the generated files in time if it's done in the Jamfile.

$ cat Jamroot 

path-constant TOP : . ;

# generate current version information 
# (done here because jam globbing doesn't pick up generated files on time if done in their respective jamfiles) 
Echo [ SHELL "$(TOP)/common/version/generate.sh $(TOP) $(TOP)/common/version/bin_version.cc" ] ;

.....

$ cat common/version/generate.sh
#!/bin/bash

readonly TOP=$1; shift

readonly TEMP_DIR=$(mktemp -dt "$(basename $0.XXXXXXXXXX)")
trap "rm -rf ${TEMP_DIR}" EXIT

readonly VERSION=$(git describe --always --dirty --long --tags)
readonly NUM_COMMITS=$(git rev-list HEAD | wc -l | bc)
readonly BRANCH=$(git rev-parse --abbrev-ref HEAD)
readonly AHEAD_BY=$(git log --oneline origin/${BRANCH}..${BRANCH} | wc -l | bc)
readonly NUM_UNTRACKED=$(git ls-files --exclude-standard --others --full-name -- ${TOP} | wc -l | bc)
readonly HOSTNAME=$(hostname)

write_version_file()
{
local filename=${1}

cat <<- EOF > ${filename}
/*
* Version information
*
* - This is a generated file - do not edit
*/

#include "bin_version.h"

namespace app { namespace bin {

const char* version()       { return "${VERSION}"; }
const char* num_commits()   { return "${NUM_COMMITS}"; }
const char* date()          { return __DATE__ " "  __TIME__; }
const char* branch()        { return "${BRANCH}"; }
const char* ahead_by()      { return "${AHEAD_BY}"; }
const char* num_untracked() { return "${NUM_UNTRACKED}"; }
const char* user()          { return "${USER}"; }
const char* hostname()      { return "${HOSTNAME}"; }

}}
EOF
}

copy_if_different()
{
local src_file=$1
local dst_file=$2

if [ -f ${dst_file} ]; then

# diff the files
diff ${src_file} ${dst_file} > /dev/null

# if there are differences
if [ $? -ne 0  ]; then
echo "$(basename ${dst_file}) is out of date - updating"
mv ${src_file} ${dst_file}
fi
else
echo "$(basename ${dst_file}) does not exist - creating"
mv ${src_file} ${dst_file}
fi
}

main()
{
local dst_file=$1
local src_file=${TEMP_DIR}/version

write_version_file ${src_file}
copy_if_different ${src_file} ${dst_file}

printf "Version info: $VERSION\n"
printf "Num commits: $NUM_COMMITS"
}
main "$@"