1#!/usr/bin/env python 2 3import datetime 4import os 5import re 6import sys 7import subprocess 8 9try: 10 import hashlib 11 sha1 = hashlib.sha1 12except ImportError, e: 13 import sha 14 sha1 = sha.sha 15 16def get_repo_revision(repo_dir): 17 if not os.path.exists(os.path.join(repo_dir, '.git')): 18 return 'Unknown (not git)' 19 20 # Get the HEAD revision 21 proc = subprocess.Popen(['git', 'log', '-1', '--format=%H'], 22 stdout=subprocess.PIPE, 23 stderr=subprocess.PIPE, 24 cwd=repo_dir) 25 out, err = proc.communicate() 26 proc.wait() 27 28 rev_sha1 = out.strip() 29 30 # Working Directory Modified 31 proc = subprocess.Popen(['git', 'status'], 32 stdout=subprocess.PIPE, 33 stderr=subprocess.PIPE, 34 cwd=repo_dir) 35 out, err = proc.communicate() 36 proc.wait() 37 38 if out.find('(working directory clean)') == -1: 39 mod = ' modified' 40 else: 41 mod = '' 42 43 return rev_sha1 + mod + ' (git)' 44 45def compute_sha1(path, global_hasher = None): 46 f = open(path, 'rb') 47 hasher = sha1() 48 while True: 49 buf = f.read(512) 50 hasher.update(buf) 51 if global_hasher: 52 global_hasher.update(buf) 53 if len(buf) < 512: 54 break 55 f.close() 56 return hasher.hexdigest() 57 58def compute_sha1_list(paths): 59 hasher = sha1() 60 sha1sums = [] 61 for path in paths: 62 sha1sums.append(compute_sha1(path, hasher)) 63 return (hasher.hexdigest(), sha1sums) 64 65def quote_str(s): 66 result = '"' 67 for c in s: 68 if c == '\\': 69 result += '\\\\' 70 elif c == '\r': 71 result += '\\r' 72 elif c == '\n': 73 result += '\\n' 74 elif c == '\t': 75 result += '\\t' 76 elif c == '\"': 77 result += '\\"' 78 elif c == '\'': 79 result += '\\\'' 80 else: 81 result += c 82 result += '"' 83 return result 84 85def main(): 86 # Check Argument 87 if len(sys.argv) < 2: 88 print >> sys.stderr, 'USAGE:', sys.argv[0], '[REPO] [LIBs]' 89 sys.exit(1) 90 91 # Record Build Time 92 build_time = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') 93 94 # Repository Directory (For build revision) 95 repo_dir = sys.argv[1] 96 build_rev = get_repo_revision(repo_dir) 97 98 # Compute SHA1 99 lib_list = list(set(sys.argv[2:])) 100 lib_list.sort() 101 build_sha1, sha1sum_list = compute_sha1_list(lib_list) 102 103 # Build file list string 104 lib_list_str = '' 105 for i, path in enumerate(lib_list): 106 lib_list_str += ' %s %s\n' % (sha1sum_list[i], path) 107 108 # Print the automatically generated code 109 print """/* Automatically generated file (DON'T MODIFY) */ 110 111/* Repository directory: %s */ 112 113/* File list: 114%s*/ 115 116#ifdef __cplusplus 117extern "C" { 118#endif 119 120char const *bccGetBuildTime() { 121 return %s; 122} 123 124char const *bccGetBuildRev() { 125 return %s; 126} 127 128char const *bccGetBuildSHA1() { 129 return %s; 130} 131 132#ifdef __cplusplus 133} 134#endif 135 136""" % (os.path.abspath(repo_dir), 137 lib_list_str, 138 quote_str(build_time), 139 quote_str(build_rev), 140 quote_str(build_sha1)) 141 142if __name__ == '__main__': 143 main() 144