148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien#!/usr/bin/env python 2ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# 3ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# Copyright (C) 2011-2012 The Android Open Source Project 4ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# 5ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# Licensed under the Apache License, Version 2.0 (the "License"); 6ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# you may not use this file except in compliance with the License. 7ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# You may obtain a copy of the License at 8ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# 9ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# http://www.apache.org/licenses/LICENSE-2.0 10ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# 11ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# Unless required by applicable law or agreed to in writing, software 12ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# distributed under the License is distributed on an "AS IS" BASIS, 13ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# See the License for the specific language governing permissions and 15ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# limitations under the License. 16ddf5661793de8fb4e16906b7f7822972fcb13c6dZonr Chang# 1748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 1848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chienimport datetime 1948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chienimport os 2048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chienimport re 2148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chienimport sys 2248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chienimport subprocess 2348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 241c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandlertry: 251c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler import hashlib 261c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler sha1 = hashlib.sha1 271c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandlerexcept ImportError, e: 281c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler import sha 291c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler sha1 = sha.sha 301c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler 3148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chiendef get_repo_revision(repo_dir): 3248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien if not os.path.exists(os.path.join(repo_dir, '.git')): 3348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien return 'Unknown (not git)' 3448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 353bfcd866e752a77e42b93dea1754417e5c466472Logan Chien # Get the HEAD revision 3648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien proc = subprocess.Popen(['git', 'log', '-1', '--format=%H'], 3748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien stdout=subprocess.PIPE, 3848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien stderr=subprocess.PIPE, 3948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien cwd=repo_dir) 4048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien out, err = proc.communicate() 4148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien proc.wait() 4248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 433bfcd866e752a77e42b93dea1754417e5c466472Logan Chien rev_sha1 = out.strip() 443bfcd866e752a77e42b93dea1754417e5c466472Logan Chien 453bfcd866e752a77e42b93dea1754417e5c466472Logan Chien # Working Directory Modified 463bfcd866e752a77e42b93dea1754417e5c466472Logan Chien proc = subprocess.Popen(['git', 'status'], 473bfcd866e752a77e42b93dea1754417e5c466472Logan Chien stdout=subprocess.PIPE, 483bfcd866e752a77e42b93dea1754417e5c466472Logan Chien stderr=subprocess.PIPE, 493bfcd866e752a77e42b93dea1754417e5c466472Logan Chien cwd=repo_dir) 503bfcd866e752a77e42b93dea1754417e5c466472Logan Chien out, err = proc.communicate() 513bfcd866e752a77e42b93dea1754417e5c466472Logan Chien proc.wait() 523bfcd866e752a77e42b93dea1754417e5c466472Logan Chien 5376bb588a309ba11c1b6a3c2af3b97f784f29a833Logan Chien if out.find('(working directory clean)') == -1: 541c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler mod = ' modified' 551c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler else: 561c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler mod = '' 573bfcd866e752a77e42b93dea1754417e5c466472Logan Chien 583bfcd866e752a77e42b93dea1754417e5c466472Logan Chien return rev_sha1 + mod + ' (git)' 5948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 6048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chiendef compute_sha1(path, global_hasher = None): 6148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien f = open(path, 'rb') 621c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler hasher = sha1() 6348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien while True: 6448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien buf = f.read(512) 6548dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien hasher.update(buf) 6648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien if global_hasher: 6748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien global_hasher.update(buf) 6848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien if len(buf) < 512: 6948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien break 7048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien f.close() 7148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien return hasher.hexdigest() 7248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 7348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chiendef compute_sha1_list(paths): 741c13147fd7d2294a0f34a569fe36660b6b056a91Daniel Sandler hasher = sha1() 7548dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien sha1sums = [] 7648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien for path in paths: 7748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien sha1sums.append(compute_sha1(path, hasher)) 7848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien return (hasher.hexdigest(), sha1sums) 7948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 8048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chiendef quote_str(s): 8148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result = '"' 8248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien for c in s: 8348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien if c == '\\': 8448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result += '\\\\' 8548dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien elif c == '\r': 8648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result += '\\r' 8748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien elif c == '\n': 8848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result += '\\n' 8948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien elif c == '\t': 9048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result += '\\t' 9148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien elif c == '\"': 9248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result += '\\"' 9348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien elif c == '\'': 9448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result += '\\\'' 9548dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien else: 9648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result += c 9748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien result += '"' 9848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien return result 9948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 10048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chiendef main(): 10148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien # Check Argument 10248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien if len(sys.argv) < 2: 10348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien print >> sys.stderr, 'USAGE:', sys.argv[0], '[REPO] [LIBs]' 10448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien sys.exit(1) 10548dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 10648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien # Record Build Time 10748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien build_time = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') 10848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 10948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien # Repository Directory (For build revision) 11048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien repo_dir = sys.argv[1] 11148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien build_rev = get_repo_revision(repo_dir) 11248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 11348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien # Compute SHA1 11448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien lib_list = list(set(sys.argv[2:])) 11548dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien lib_list.sort() 11648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien build_sha1, sha1sum_list = compute_sha1_list(lib_list) 11748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 11848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien # Build file list string 11948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien lib_list_str = '' 12048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien for i, path in enumerate(lib_list): 12148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien lib_list_str += ' %s %s\n' % (sha1sum_list[i], path) 12248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 12348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien # Print the automatically generated code 12448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien print """/* Automatically generated file (DON'T MODIFY) */ 12548dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 12648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien/* Repository directory: %s */ 12748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 12848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien/* File list: 12948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien%s*/ 13048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 1317a5d423014e1cc95e34764b3ddf8e80ace3509b8Zonr Chang#include "bcc/Config/BuildInfo.h" 13248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 1337a5d423014e1cc95e34764b3ddf8e80ace3509b8Zonr Changusing namespace bcc; 13448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 1357a5d423014e1cc95e34764b3ddf8e80ace3509b8Zonr Changconst char* BuildInfo::GetBuildTime() { 13648dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien return %s; 13748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien} 13848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 1397a5d423014e1cc95e34764b3ddf8e80ace3509b8Zonr Changconst char *BuildInfo::GetBuildRev() { 14044d991658dbd5b80648a3944f1760ad19bbcac09Zonr Chang return %s; 14148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien} 14248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 1437a5d423014e1cc95e34764b3ddf8e80ace3509b8Zonr Changconst char *BuildInfo::GetBuildSourceBlob() { 1447a5d423014e1cc95e34764b3ddf8e80ace3509b8Zonr Chang return %s; 145aa72a210b0f73671b01984020a74360c10427e31Stephen Hines} 146aa72a210b0f73671b01984020a74360c10427e31Stephen Hines 14748dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien""" % (os.path.abspath(repo_dir), 14848dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien lib_list_str, 14948dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien quote_str(build_time), 15048dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien quote_str(build_rev), 15148dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien quote_str(build_sha1)) 15248dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien 15348dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chienif __name__ == '__main__': 15448dc01db0b865b73f41cef53bcb72f65fd027af4Logan Chien main() 155