2011-09-07 67 views
2

我有一個用C++編寫的合理大小(大約40k行)的機器學習系統。這仍然處於積極的發展階段,我需要定期運行實驗,即使在對代碼進行更改時也是如此。可執行文件中的跟蹤代碼版本

我的實驗輸出以簡單的文本文件捕獲。在查看這些結果時,我想要做的是找出生成它的代碼的確切版本。我通常有大約5到6個實驗同時運行,每個實驗的代碼略有不同。

我想知道一些結果是通過編譯文件A的版本1,文件B的版本2等獲得的(我只需要一些標識符,「git describe」的輸出在這裏可以很好地完成)。

我的想法是在編譯二進制文件時以某種方式包含此信息。這樣,這可以與結果一起打印出來。

任何建議如何以良好的方式做到這一點。特別是,用git做這件事的好方法?

回答

3

我產生一個源文件作爲我的生成過程的一部分,看起來像這樣:

static const char version_cstr[] = "93f794f674 (" __DATE__ ")"; 
const char * version() 
{ 
    return version_cstr; 
} 

那麼它很容易進行登錄的版本上啓動。

我最初在命令行中使用了DEFINE,但這意味着每個版本都會更改所有由構建系統重新編譯的內容 - 對於大型項目來說並不好。

下面是scons的片段,我用它來生成它,也許你可以根據自己的需要進行調整。

# Lets get the version from git 
# first get the base version 
git_sha = subprocess.Popen(["git","rev-parse","--short=10","HEAD"], stdout=subprocess.PIPE).communicate()[0].strip() 
p1 = subprocess.Popen(["git", "status"], stdout=subprocess.PIPE) 
p2 = subprocess.Popen(["grep", "Changed but not updated\\|Changes to be committed"], stdin=p1.stdout,stdout=subprocess.PIPE) 
result = p2.communicate()[0].strip() 

if result!="": 
    git_sha += "[MOD]" 

print "Building version %s"%git_sha 


def version_action(target,source,env): 
    """ 
    Generate file with current version info 
    """ 
    fd=open(target[0].path,'w') 
    fd.write("static const char version_cstr[] = \"%s (\" __DATE__ \")\";\nconst char * version()\n{\n return version_cstr;\n}\n" % git_sha) 
    fd.close() 
    return 0 

build_version = env.Command('src/autogen/version.cpp', [], Action(version_action)) 
env.AlwaysBuild(build_version) 
1

您可以使用源文件$Id:$,和Git將取代,與SHA1哈希值,如果你在.gitattributes與選項「標識」添加包含這個詞組的文件(見gitattributes)。

+0

但是它在每一次構建中都會保持不變,它會在每個git操作中發生變化。 – ixe013

+0

這隻意味着OP必須定期提交,即在他進行任何實驗之前。如果他想回到某個特定版本的代碼中,這甚至是必要的,所以這是最簡單的變體。 – arne