Home | History | Annotate | Download | only in build
      1 #!/usr/bin/env python
      2 #
      3 # Copyright (C) 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 # prepare_pdk_tree.py target_dir [-m manifest] pdk_groups
     19 # Ex: prepare_pdk_tree.py ../tmp/pdk grouper
     20 # create mount_pdk.sh and umount_pdk.sh, which mounts/umounts pdk sources.
     21 
     22 import os
     23 import re
     24 import sys
     25 import subprocess
     26 
     27 
     28 class ManifestHandler(object):
     29 
     30     def __init__(self):
     31         # current pattern
     32         self.current = 0
     33         self.patterns = [re.compile('path=\"([^\"]*)\".*groups=\"([^\"]*)\"'), \
     34                          re.compile('groups=\"([^\"]*)\".*path=\"([^\"]*)\"')]
     35 
     36     def getAttribs(self, line):
     37         attrib = [None, None] # list of path, groups
     38         m = self.patterns[self.current].search(line)
     39         # if match fails, try both pattens and change default one
     40         # if match founds
     41         if m is None:
     42             notCurrent = 1 - self.current
     43             mOther = self.patterns[notCurrent].search(line)
     44             if mOther is not None:
     45                 # toggle
     46                 self.current = notCurrent
     47                 m = mOther
     48         if m is not None:
     49             if (self.current == 0):
     50                 attrib[0] = m.group(1)
     51                 attrib[1] = m.group(2)
     52             else:
     53                 attrib[0] = m.group(2)
     54                 attrib[1] = m.group(1)
     55         return attrib
     56 
     57 def isInGroups(groupsAttrib, groups):
     58     if groupsAttrib is None:
     59         return False
     60     for group in groups:
     61         if group in groupsAttrib:
     62             return True
     63     return False
     64 
     65 def getPDKDirs(manifest, groups):
     66     subdirs = []
     67     handler = ManifestHandler()
     68     f = open(manifest, 'r')
     69     for line in f:
     70         [path, groupsAttrib] = handler.getAttribs(line)
     71         if isInGroups(groupsAttrib, groups):
     72             subdirs.append(path)
     73     f.close()
     74     return subdirs
     75 
     76 def create_symbolic_link(src_top, dest_top, dir_name):
     77     src_full = src_top + "/" + dir_name
     78     dest_full = dest_top + "/" + dir_name
     79     #print "create symbolic link from " + dest_full + " to " + src_full
     80     # remove existing link first to prevent recursive loop
     81     os.system("rm -rf " + dest_full)
     82     os.system("ln -s " + src_full + " " + dest_full)
     83 
     84 # The only file not from manifest.
     85 copy_files_list = [ "Makefile" ]
     86 MOUNT_FILE = 'mount_pdk.sh'
     87 UMOUNT_FILE = 'umount_pdk.sh'
     88 SH_HEADER = "#!/bin/bash\n#Auto-generated file, do not edit!\n"
     89 
     90 def main(argv):
     91     manifestFile = ".repo/manifest.xml"
     92     groups = ["pdk"]
     93     if len(argv) < 2:
     94         print "create_pdk_tree.py target_dir [-m manifest] [-a dir_to_add] pdk_groups"
     95         print " ex) create_pdk_tree.py ../tmp grouper"
     96         print " -a option is to include a directory which does not belong to specified group"
     97         print "   multiple -a options can be specified like -a frameworks/base -a external/aaa"
     98         print " Note that pdk group is included by default"
     99         print " Do not create target_dir under the current source tree. This will cause build error."
    100         sys.exit(1)
    101     targetDir = argv[1]
    102     argc = 2
    103     subdirs = []
    104     if len(argv) > 2:
    105         if argv[2] == "-m":
    106             manifestFile = argv[3]
    107             argc += 2
    108     while argc < len(argv):
    109         if argv[argc] == "-a":
    110             argc += 1
    111             subdirs.append(argv[argc])
    112         else:
    113             groups.append(argv[argc])
    114         argc += 1
    115     sourceDir = os.path.abspath('.')
    116     targetDir = os.path.abspath(targetDir)
    117 
    118     p = subprocess.Popen("mount", stdout = subprocess.PIPE)
    119     targetMounted = False
    120     for line in p.stdout:
    121         if targetDir in line:
    122             targetMounted = True
    123     p.stdout.close()
    124 
    125     if targetMounted:
    126         print "target dir already mounted"
    127         if os.path.exists(targetDir + '/' + UMOUNT_FILE):
    128             print "Use existing file", UMOUNT_FILE, "to unmount"
    129             sys.exit(1)
    130         else:
    131             print "Will create scripts, but may need manual unmount"
    132 
    133     subdirs += getPDKDirs(manifestFile, groups)
    134     print subdirs
    135     os.system("mkdir -p " + targetDir)
    136     mountf = open(targetDir + '/' + MOUNT_FILE, 'w+')
    137     mountf.write(SH_HEADER)
    138     umountf = open(targetDir + '/' + UMOUNT_FILE, 'w+')
    139     umountf.write(SH_HEADER)
    140     for subdir in subdirs:
    141         os.system("mkdir -p " + targetDir + '/' + subdir)
    142         mountf.write("mount --bind " + sourceDir + "/" + subdir + " " + targetDir + "/" + subdir + \
    143                         "\n")
    144         umountf.write("umount " + targetDir + "/" + subdir + "\n")
    145     for file_name in copy_files_list:
    146         create_symbolic_link(sourceDir, targetDir, file_name)
    147     mountf.close()
    148     umountf.close()
    149     os.system("chmod 700 " + targetDir + '/' + MOUNT_FILE)
    150     os.system("chmod 700 " + targetDir + '/' + UMOUNT_FILE)
    151 
    152 if __name__ == '__main__':
    153     main(sys.argv)
    154