Made buildinfo aware of builds from GIT

- Use commit number since last annotated tag as a
  revision number replacement. It'll eb followed
  by 'M' symbol if there're local modification in
  the source tree.

- Commit short SHA1 is included. Helps getting
  information about commit used to build blender
  with much faster.

- If build is not done from master branch, this also
  will be noticed in the splash screen.

This commit also replaces revision stored in the
files with git-specific fields (change and hash).
This is kind of breaks compatibility, meaning
files which were saved before this change wouldn't
display any information about which revision they
were saved with. When we'll finally switch to git,
we'll see proper hash and change number since
previous release in the files, for until then
svn version will be used as a change number and
hash will be empty.

Not a huge deal, since this field was only used
by developers to help torubleshooting things and
isn't needed for blender itself.

Some additional tweaks are probably needed :)
This commit is contained in:
Sergey Sharybin 2013-11-04 13:21:39 +00:00
parent d07f3f793b
commit 2010c6ad6c
15 changed files with 211 additions and 55 deletions

@ -1,16 +1,82 @@
# This is called by cmake as an extermal process from
# ./source/creator/CMakeLists.txt to write ./source/creator/buildinfo.h
# The FindSubversion.cmake module is part of the standard distribution
include(FindSubversion)
# Extract working copy information for SOURCE_DIR into MY_XXX variables
# with a default in case anything fails, for examble when using git-svn
set(MY_WC_REVISION "unknown")
set(MY_WC_HASH "")
set(MY_WC_BRANCH "")
set(MY_WC_CHANGE "unknown")
# Guess if this is a SVN working copy and then look up the revision
if(EXISTS ${SOURCE_DIR}/.svn/)
if(Subversion_FOUND)
Subversion_WC_INFO(${SOURCE_DIR} MY)
if(EXISTS ${SOURCE_DIR}/.git/)
if(EXISTS ${SOURCE_DIR}/.git/)
# The FindSubversion.cmake module is part of the standard distribution
include(FindGit)
if(GIT_FOUND)
execute_process(COMMAND git rev-parse --short HEAD
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE MY_WC_HASH
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND git rev-parse --abbrev-ref HEAD
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE MY_WC_BRANCH
OUTPUT_STRIP_TRAILING_WHITESPACE)
# Get latest version tag
execute_process(COMMAND git describe --match "v[0-9]*" --abbrev=0
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE _git_latest_version_tag
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT _git_latest_version_tag STREQUAL "")
execute_process(COMMAND git rev-list HEAD ^${_git_latest_version_tag} --count
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE MY_WC_CHANGE
OUTPUT_STRIP_TRAILING_WHITESPACE)
else()
# For the time being we don't have annotated release tags,
# count all the revisions in branch.
execute_process(COMMAND git rev-list HEAD --count
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE MY_WC_CHANGE
OUTPUT_STRIP_TRAILING_WHITESPACE)
endif()
# Update GIT index before getting dirty files
execute_process(COMMAND git update-index -q --refresh
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_STRIP_TRAILING_WHITESPACE)
execute_process(COMMAND git diff-index --name-only HEAD --
WORKING_DIRECTORY ${SOURCE_DIR}
OUTPUT_VARIABLE _git_changed_files
OUTPUT_STRIP_TRAILING_WHITESPACE)
if(NOT _git_changed_files STREQUAL "")
set(MY_WC_CHANGE "${MY_WC_CHANGE}M")
endif()
unset(_git_changed_files)
unset(_git_latest_version_tag)
endif()
endif()
else()
# Some crazy folks like me could have hacked git-svn chekout in a way
# so svnversion gives proper svn revision for themm which required having
# empty .svn folder.
#
# For such a crazy blokes put svn check into an else branch.
#
# (sergey)
if(EXISTS ${SOURCE_DIR}/.svn/)
# The FindSubversion.cmake module is part of the standard distribution
include(FindSubversion)
if(Subversion_FOUND)
Subversion_WC_INFO(${SOURCE_DIR} MY)
set(MY_WC_CHANGE "${MY_WC_REVISION}")
endif()
endif()
endif()
@ -27,7 +93,9 @@ endif()
# Write a file with the SVNVERSION define
file(WRITE buildinfo.h.txt
"#define BUILD_REV \"${MY_WC_REVISION}\"\n"
"#define BUILD_HASH \"${MY_WC_HASH}\"\n"
"#define BUILD_CHANGE \"${MY_WC_CHANGE}\"\n"
"#define BUILD_BRANCH \"${MY_WC_BRANCH}\"\n"
"#define BUILD_DATE \"${BUILD_DATE}\"\n"
"#define BUILD_TIME \"${BUILD_TIME}\"\n"
)

@ -410,9 +410,24 @@ def buildinfo(lenv, build_type):
"""
build_date = time.strftime ("%Y-%m-%d")
build_time = time.strftime ("%H:%M:%S")
build_rev = os.popen('svnversion').read()[:-1] # remove \n
if build_rev == '':
build_rev = '-UNKNOWN-'
if os.path.isdir(os.path.abspath('.git')):
latest_version_tag = os.popen('git describe --match "v[0-9]*" --abbrev=0').read().strip()
if latest_version_tag:
build_change = os.popen('git rev-list HEAD ' + latest_version_tag + ' --count').read().strip()
else:
build_change = os.popen('git rev-list HEAD --count').read().strip()
build_hash = os.popen('git rev-parse --short HEAD').read().strip()
build_branch = os.popen('git rev-parse --abbrev-ref HEAD').read().strip()
elif os.path.isdir(os.path.abspath('.svn')):
build_hash = ''
build_change = os.popen('svnversion').read()[:-1] # remove \n
build_branch = ''
else:
build_hash = ''
build_change = 'unknown'
build_branch = ''
if lenv['BF_DEBUG']:
build_type = "Debug"
build_cflags = ' '.join(lenv['CFLAGS'] + lenv['CCFLAGS'] + lenv['BF_DEBUG_CCFLAGS'] + lenv['CPPFLAGS'])
@ -429,7 +444,9 @@ def buildinfo(lenv, build_type):
lenv.Append (CPPDEFINES = ['BUILD_TIME=\\"%s\\"'%(build_time),
'BUILD_DATE=\\"%s\\"'%(build_date),
'BUILD_TYPE=\\"%s\\"'%(build_type),
'BUILD_REV=\\"%s\\"'%(build_rev),
'BUILD_HASH=\\"%s\\"'%(build_hash),
'BUILD_CHANGE=\\"%s\\"'%(build_change),
'BUILD_BRANCH=\\"%s\\"'%(build_branch),
'WITH_BUILDINFO',
'BUILD_PLATFORM=\\"%s:%s\\"'%(platform.system(), platform.architecture()[0]),
'BUILD_CFLAGS=\\"%s\\"'%(build_cflags),

@ -67,7 +67,19 @@ def write_sysinfo(op):
# build info
output.write("\nBlender:\n")
output.write(lilies)
output.write("version %s, revision %r. %r\n" % (bpy.app.version_string, bpy.app.build_revision, bpy.app.build_type))
if bpy.app.build_branch and bpy.app.build_branch != "Unknown":
output.write("version %s, branch %r, chage %r, hash %r, %r\n" %
(bpy.app.version_string,
bpy.app.build_branch,
bpy.app.build_change,
bpy.app.build_hash,
bpy.app.build_type))
else:
output.write("version %s, revision %r. %r\n" %
(bpy.app.version_string,
bpy.app.build_change,
bpy.app.build_type))
output.write("build date: %r, %r\n" % (bpy.app.build_date, bpy.app.build_time))
output.write("platform: %r\n" % (bpy.app.build_platform))
output.write("binary path: %r\n" % (bpy.app.binary_path))

@ -53,7 +53,7 @@ typedef struct Main {
char name[1024]; /* 1024 = FILE_MAX */
short versionfile, subversionfile; /* see BLENDER_VERSION, BLENDER_SUBVERSION */
short minversionfile, minsubversionfile;
int revision; /* svn revision of binary that saved file */
char build_change[16], build_hash[16]; /* change number and hash from buildinfo */
short recovered; /* indicate the main->name (file) is the recovered one */
struct Library *curlib;

@ -7292,7 +7292,8 @@ static BHead *read_global(BlendFileData *bfd, FileData *fd, BHead *bhead)
bfd->main->subversionfile = fg->subversion;
bfd->main->minversionfile = fg->minversion;
bfd->main->minsubversionfile = fg->minsubversion;
bfd->main->revision = fg->revision;
BLI_strncpy(bfd->main->build_change, fg->build_change, sizeof(bfd->main->build_change));
BLI_strncpy(bfd->main->build_hash, fg->build_hash, sizeof(bfd->main->build_hash));
bfd->winpos = fg->winpos;
bfd->fileflags = fg->fileflags;
@ -7926,8 +7927,11 @@ static void do_versions(FileData *fd, Library *lib, Main *main)
{
/* WATCH IT!!!: pointers from libdata have not been converted */
if (G.debug & G_DEBUG)
printf("read file %s\n Version %d sub %d svn r%d\n", fd->relabase, main->versionfile, main->subversionfile, main->revision);
if (G.debug & G_DEBUG) {
printf("read file %s\n Version %d sub %d change %s hash %s\n",
fd->relabase, main->versionfile, main->subversionfile,
main->build_change, main->build_hash);
}
blo_do_versions_pre250(fd, lib, main);
blo_do_versions_250(fd, lib, main);

@ -3261,7 +3261,7 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
char subvstr[8];
/* prevent mem checkers from complaining */
fg.pads= fg.pad= 0;
fg.pads= 0;
memset(fg.filename, 0, sizeof(fg.filename));
current_screen_compat(mainvar, &screen);
@ -3285,11 +3285,14 @@ static void write_global(WriteData *wd, int fileflags, Main *mainvar)
fg.minsubversion= BLENDER_MINSUBVERSION;
#ifdef WITH_BUILDINFO
{
extern char build_rev[];
fg.revision= atoi(build_rev);
extern char build_change[], build_hash[];
/* TODO(sergey): Add branch name to file as well? */
BLI_strncpy(fg.build_change, build_change, sizeof(fg.build_change));
BLI_strncpy(fg.build_hash, build_hash, sizeof(fg.build_hash));
}
#else
fg.revision= 0;
BLI_strncpy(fg.build_change, "unknown", sizeof(fg.build_change));
BLI_strncpy(fg.build_hash, "unknown", sizeof(fg.build_hash));
#endif
writestruct(wd, GLOB, "FileGlobal", 1, &fg);
}

@ -53,10 +53,6 @@ extern "C"
#include "BIK_api.h"
#include "BKE_global.h"
#include "ED_object.h"
#ifdef NAN_BUILDINFO
extern char build_rev[];
#endif
}
#include "MEM_guardedalloc.h"

@ -101,7 +101,8 @@ extern "C"
#include "ED_keyframing.h"
#ifdef WITH_BUILDINFO
extern char build_rev[];
extern char build_change[];
extern char build_hash[];
#endif
#include "MEM_guardedalloc.h"
@ -226,7 +227,14 @@ void DocumentExporter::exportCurrentScene(Scene *sce)
}
char version_buf[128];
#ifdef WITH_BUILDINFO
sprintf(version_buf, "Blender %d.%02d.%d r%s", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION, build_rev);
/* TODO(sergey): As soon as we fully switched to GIT, no need to check build_hash. */
if (build_hash[0] != '\0') {
sprintf(version_buf, "Blender %d.%02d.%d change:%s, hash:", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION,
build_change, build_hash);
}
else {
sprintf(version_buf, "Blender %d.%02d.%d r%s", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION, build_change);
}
#else
sprintf(version_buf, "Blender %d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
#endif

@ -48,8 +48,7 @@ typedef struct FileGlobal {
struct Scene *curscene;
int fileflags;
int globalf;
int revision; /* svn revision from buildinfo */
int pad;
char build_change[16], build_hash[16]; /* change number and hash from buildinfo */
/* file path where this was saved, for recover */
char filename[1024]; /* 1024 = FILE_MAX */
} FileGlobal;

@ -53,7 +53,9 @@
#ifdef BUILD_DATE
extern char build_date[];
extern char build_time[];
extern char build_rev[];
extern char build_change[];
extern char build_hash[];
extern char build_branch[];
extern char build_platform[];
extern char build_type[];
extern char build_cflags[];
@ -75,7 +77,9 @@ static PyStructSequence_Field app_info_fields[] = {
/* buildinfo */
{(char *)"build_date", (char *)"The date this blender instance was built"},
{(char *)"build_time", (char *)"The time this blender instance was built"},
{(char *)"build_revision", (char *)"The subversion revision this blender instance was built with"},
{(char *)"build_change", (char *)"The change number this blender instance was built with"},
{(char *)"build_hash", (char *)"The commit hash this blender instance was built with"},
{(char *)"build_branch", (char *)"The branch this blender instance was built from"},
{(char *)"build_platform", (char *)"The platform this blender instance was built for"},
{(char *)"build_type", (char *)"The type of build (Release, Debug)"},
{(char *)"build_cflags", (char *)"C compiler flags"},
@ -133,7 +137,9 @@ static PyObject *make_app_info(void)
#ifdef BUILD_DATE
SetBytesItem(build_date);
SetBytesItem(build_time);
SetBytesItem(build_rev);
SetBytesItem(build_change);
SetBytesItem(build_hash);
SetBytesItem(build_branch);
SetBytesItem(build_platform);
SetBytesItem(build_type);
SetBytesItem(build_cflags);
@ -150,6 +156,8 @@ static PyObject *make_app_info(void)
SetBytesItem("Unknown");
SetBytesItem("Unknown");
SetBytesItem("Unknown");
SetBytesItem("Unknown");
SetBytesItem("Unknown");
#endif
SetObjItem(BPY_app_ffmpeg_struct());

@ -1641,18 +1641,25 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
#ifdef WITH_BUILDINFO
int ver_width, rev_width;
char version_buf[128];
char revision_buf[128];
extern char build_rev[];
BLI_snprintf(version_buf, sizeof(version_buf),
"%d.%02d.%d", BLENDER_VERSION / 100, BLENDER_VERSION % 100, BLENDER_SUBVERSION);
BLI_snprintf(revision_buf, sizeof(revision_buf), "r%s", build_rev);
int label_delta = 0;
int hash_width, change_width;
char change_buf[128] = "\0";
char hash_buf[128] = "\0";
extern char build_hash[], build_change[], build_branch[];
/* TODO(sergey): As soon as we fully switched to GIT, no need to check build_hash. */
if (build_hash[0] != '\0') {
/* Builds made from tag only shows tag sha */
BLI_snprintf(hash_buf, sizeof(hash_buf), "Hash: %s", build_hash);
BLI_snprintf(change_buf, sizeof(change_buf), "Change: %s", build_change);
}
else {
BLI_snprintf(change_buf, sizeof(change_buf), "r%s", build_change);
}
BLF_size(style->widgetlabel.uifont_id, style->widgetlabel.points, U.pixelsize * U.dpi);
ver_width = (int)BLF_width(style->widgetlabel.uifont_id, version_buf) + 0.5f * U.widget_unit;
rev_width = (int)BLF_width(style->widgetlabel.uifont_id, revision_buf) + 0.5f * U.widget_unit;
hash_width = (int)BLF_width(style->widgetlabel.uifont_id, hash_buf) + 0.5f * U.widget_unit;
change_width = (int)BLF_width(style->widgetlabel.uifont_id, change_buf) + 0.5f * U.widget_unit;
#endif /* WITH_BUILDINFO */
block = uiBeginBlock(C, ar, "_popup", UI_EMBOSS);
@ -1667,9 +1674,23 @@ static uiBlock *wm_block_create_splash(bContext *C, ARegion *ar, void *UNUSED(ar
uiButSetFunc(but, wm_block_splash_close, block, NULL);
uiBlockSetFunc(block, wm_block_splash_refreshmenu, block, NULL);
#ifdef WITH_BUILDINFO
uiDefBut(block, LABEL, 0, version_buf, U.pixelsize * 494 - ver_width, U.pixelsize * 258, ver_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
uiDefBut(block, LABEL, 0, revision_buf, U.pixelsize * 494 - rev_width, U.pixelsize * 246, rev_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
#ifdef WITH_BUILDINFO
if (!STREQ(build_change, "0")) {
uiDefBut(block, LABEL, 0, change_buf, U.pixelsize * 494 - change_width, U.pixelsize * 270, change_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
label_delta = 12;
}
uiDefBut(block, LABEL, 0, hash_buf, U.pixelsize * 494 - hash_width, U.pixelsize * (270 - label_delta), hash_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
/* TODO(sergey): As soon as we fully switched to GIT, no need to check
* whether branch is empty or not.
*/
if (build_branch[0] != '\0' && !STREQ(build_branch, "master")) {
char branch_buf[128] = "\0";
int branch_width;
BLI_snprintf(branch_buf, sizeof(branch_buf), "Branch: %s", build_branch);
branch_width = (int)BLF_width(style->widgetlabel.uifont_id, branch_buf) + 0.5f * U.widget_unit;
uiDefBut(block, LABEL, 0, branch_buf, U.pixelsize * 494 - branch_width, U.pixelsize * (258 - label_delta), branch_width, UI_UNIT_Y, NULL, 0, 0, 0, 0, NULL);
}
#endif /* WITH_BUILDINFO */
layout = uiBlockLayout(block, UI_LAYOUT_VERTICAL, UI_LAYOUT_PANEL, 10, 2, U.pixelsize * 480, U.pixelsize * 110, style);

@ -1,3 +1,4 @@
# ***** BEGIN GPL LICENSE BLOCK *****
#
# This program is free software; you can redistribute it and/or
@ -51,8 +52,10 @@ if(WITH_BUILDINFO)
)
add_definitions(-DBUILD_DATE="\"\""
-DBUILD_TIME="\"\""
-DBUILD_REV="\"\""
-DBUILD_CHANGE="\"\""
-DBUILD_HASH="\"\""
-DBUILD_PLATFORM="\"\""
-DBUILD_BRANCH="\"\""
-DBUILD_TYPE="\"\""
)
endif()

@ -131,7 +131,9 @@ if(WITH_BUILDINFO)
# # define in header now, else these get out of date on rebuilds.
# -DBUILD_DATE="${BUILD_DATE}"
# -DBUILD_TIME="${BUILD_TIME}"
# -DBUILD_REV="${BUILD_REV}"
# -DBUILD_CHANGE="${BUILD_CHANGE}"
# -DBUILD_HASH="${BUILD_HASH}"
# -DBUILD_BRANCH="${BUILD_BRANCH}"
-DWITH_BUILDINFO_HEADER # alternative to lines above
-DBUILD_PLATFORM="${CMAKE_SYSTEM_NAME}"
-DBUILD_TYPE="${CMAKE_BUILD_TYPE}"

@ -39,7 +39,9 @@
/* currently only these are defined in the header */
char build_date[] = BUILD_DATE;
char build_time[] = BUILD_TIME;
char build_rev[] = BUILD_REV;
char build_hash[] = BUILD_HASH;
char build_change[] = BUILD_CHANGE;
char build_branch[] = BUILD_BRANCH;
char build_platform[] = BUILD_PLATFORM;
char build_type[] = BUILD_TYPE;

@ -153,7 +153,9 @@
#ifdef BUILD_DATE
extern char build_date[];
extern char build_time[];
extern char build_rev[];
extern char build_hash[];
extern char build_change[];
extern char build_branch[];
extern char build_platform[];
extern char build_type[];
extern char build_cflags[];
@ -219,7 +221,14 @@ static int print_version(int UNUSED(argc), const char **UNUSED(argv), void *UNUS
#ifdef BUILD_DATE
printf("\tbuild date: %s\n", build_date);
printf("\tbuild time: %s\n", build_time);
printf("\tbuild revision: %s\n", build_rev);
/* TODO(sergey): As soon as we fully switched to GIT, no need to check build_hash. */
if (build_hash[0] != '\0') {
printf("\tbuild revision: %s\n", build_change);
}
else {
printf("\tbuild change: %s\n", build_change);
printf("\tbuild hash: %s\n", build_hash);
}
printf("\tbuild platform: %s\n", build_platform);
printf("\tbuild type: %s\n", build_type);
printf("\tbuild c flags: %s\n", build_cflags);
@ -590,13 +599,17 @@ static void blender_crash_handler(int signum)
printf("Writing: %s\n", fname);
fflush(stdout);
BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Revision: %s\n", BLEND_VERSION_ARG,
#ifdef BUILD_DATE
build_rev
#ifndef BUILD_DATE
BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Unknown revision\n", BLEND_VERSION_ARG);
#else
"Unknown"
/* TODO(sergey): As soon as we fully switched to GIT, no need to check build_hash. */
if (build_hash[0] != '\0') {
BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Change: %s, Hash %s\n", BLEND_VERSION_ARG, build_change, build_hash);
}
else {
BLI_snprintf(header, sizeof(header), "# " BLEND_VERSION_FMT ", Revision: %s\n", BLEND_VERSION_ARG, build_change);
}
#endif
);
/* open the crash log */
errno = 0;