Home | History | Annotate | Download | only in build
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 2011-2012 The Android Open Source Project
      4 #
      5 # Licensed under the Apache License, Version 2.0 (the "License");
      6 # you may not use this file except in compliance with the License.
      7 # You may obtain a copy of the License at
      8 #
      9 #      http://www.apache.org/licenses/LICENSE-2.0
     10 #
     11 # Unless required by applicable law or agreed to in writing, software
     12 # distributed under the License is distributed on an "AS IS" BASIS,
     13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14 # See the License for the specific language governing permissions and
     15 # limitations under the License.
     16 #
     17 
     18 import datetime
     19 import os
     20 import re
     21 import sys
     22 import subprocess
     23 
     24 try:
     25     import hashlib
     26     sha1 = hashlib.sha1
     27 except ImportError, e:
     28     import sha
     29     sha1 = sha.sha
     30 
     31 def get_repo_revision(repo_dir):
     32     if not os.path.exists(os.path.join(repo_dir, '.git')):
     33         return 'Unknown (not git)'
     34 
     35     # Get the HEAD revision
     36     proc = subprocess.Popen(['git', 'log', '-1', '--format=%H'],
     37                             stdout=subprocess.PIPE,
     38                             stderr=subprocess.PIPE,
     39                             cwd=repo_dir)
     40     out, err = proc.communicate()
     41     proc.wait()
     42 
     43     rev_sha1 = out.strip()
     44 
     45     # Working Directory Modified
     46     proc = subprocess.Popen(['git', 'status'],
     47                             stdout=subprocess.PIPE,
     48                             stderr=subprocess.PIPE,
     49                             cwd=repo_dir)
     50     out, err = proc.communicate()
     51     proc.wait()
     52 
     53     if out.find('(working directory clean)') == -1:
     54       mod = ' modified'
     55     else:
     56       mod = ''
     57 
     58     return rev_sha1 + mod + ' (git)'
     59 
     60 def compute_sha1(path, global_hasher = None):
     61     f = open(path, 'rb')
     62     hasher = sha1()
     63     while True:
     64         buf = f.read(512)
     65         hasher.update(buf)
     66         if global_hasher:
     67             global_hasher.update(buf)
     68         if len(buf) < 512:
     69             break
     70     f.close()
     71     return hasher.hexdigest()
     72 
     73 def compute_sha1_list(paths):
     74     hasher = sha1()
     75     sha1sums = []
     76     for path in paths:
     77         sha1sums.append(compute_sha1(path, hasher))
     78     return (hasher.hexdigest(), sha1sums)
     79 
     80 def quote_str(s):
     81     result = '"'
     82     for c in s:
     83         if c == '\\':
     84             result += '\\\\'
     85         elif c == '\r':
     86             result += '\\r'
     87         elif c == '\n':
     88             result += '\\n'
     89         elif c == '\t':
     90             result += '\\t'
     91         elif c == '\"':
     92             result += '\\"'
     93         elif c == '\'':
     94             result += '\\\''
     95         else:
     96             result += c
     97     result += '"'
     98     return result
     99 
    100 def main():
    101     # Check Argument
    102     if len(sys.argv) < 2:
    103         print >> sys.stderr, 'USAGE:', sys.argv[0], '[REPO] [LIBs]'
    104         sys.exit(1)
    105 
    106     # Record Build Time
    107     build_time = datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S')
    108 
    109     # Repository Directory (For build revision)
    110     repo_dir = sys.argv[1]
    111     build_rev = get_repo_revision(repo_dir)
    112 
    113     # Compute SHA1
    114     lib_list = list(set(sys.argv[2:]))
    115     lib_list.sort()
    116     build_sha1, sha1sum_list = compute_sha1_list(lib_list)
    117 
    118     # Build file list string
    119     lib_list_str = ''
    120     for i, path in enumerate(lib_list):
    121         lib_list_str += '   %s %s\n' % (sha1sum_list[i], path)
    122 
    123     # Print the automatically generated code
    124     print """/* Automatically generated file (DON'T MODIFY) */
    125 
    126 /* Repository directory: %s */
    127 
    128 /* File list:
    129 %s*/
    130 
    131 #include "bcc/Config/BuildInfo.h"
    132 
    133 using namespace bcc;
    134 
    135 const char* BuildInfo::GetBuildTime() {
    136   return %s;
    137 }
    138 
    139 const char *BuildInfo::GetBuildRev() {
    140   return %s;
    141 }
    142 
    143 const char *BuildInfo::GetBuildSourceBlob() {
    144   return %s;
    145 }
    146 
    147 """ % (os.path.abspath(repo_dir),
    148        lib_list_str,
    149        quote_str(build_time),
    150        quote_str(build_rev),
    151        quote_str(build_sha1))
    152 
    153 if __name__ == '__main__':
    154     main()
    155