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     groupsAttribList = groupsAttrib.split(',')
     61     for group in groups:
     62         if group in groupsAttribList:
     63             return True
     64     return False
     65 
     66 def getPDKDirs(manifest, groups):
     67     subdirs = []
     68     handler = ManifestHandler()
     69     f = open(manifest, 'r')
     70     for line in f:
     71         [path, groupsAttrib] = handler.getAttribs(line)
     72         if isInGroups(groupsAttrib, groups):
     73             subdirs.append(path)
     74     f.close()
     75     return subdirs
     76 
     77 def create_symbolic_link(src_top, dest_top, dir_name):
     78     src_full = src_top + "/" + dir_name
     79     dest_full = dest_top + "/" + dir_name
     80     #print "create symbolic link from " + dest_full + " to " + src_full
     81     # remove existing link first to prevent recursive loop
     82     os.system("rm -rf " + dest_full)
     83     os.system("ln -s " + src_full + " " + dest_full)
     84 
     85 # The only file not from manifest.
     86 copy_files_list = [ "Makefile" ]
     87 MOUNT_FILE = 'mount_pdk.sh'
     88 UMOUNT_FILE = 'umount_pdk.sh'
     89 SH_HEADER = "#!/bin/bash\n#Auto-generated file, do not edit!\n"
     90 
     91 def main(argv):
     92     manifestFile = ".repo/manifest.xml"
     93     groups = ["pdk"]
     94     if len(argv) < 2:
     95         print "create_pdk_tree.py target_dir [-m manifest] [-a dir_to_add] pdk_groups"
     96         print " ex) create_pdk_tree.py ../tmp grouper"
     97         print " -a option is to include a directory which does not belong to specified group"
     98         print "   multiple -a options can be specified like -a frameworks/base -a external/aaa"
     99         print " Note that pdk group is included by default"
    100         print " Do not create target_dir under the current source tree. This will cause build error."
    101         sys.exit(1)
    102     targetDir = argv[1]
    103     argc = 2
    104     subdirs = []
    105     if len(argv) > 2:
    106         if argv[2] == "-m":
    107             manifestFile = argv[3]
    108             argc += 2
    109     while argc < len(argv):
    110         if argv[argc] == "-a":
    111             argc += 1
    112             subdirs.append(argv[argc])
    113         else:
    114             groups.append(argv[argc])
    115         argc += 1
    116     sourceDir = os.path.abspath('.')
    117     targetDir = os.path.abspath(targetDir)
    118 
    119     p = subprocess.Popen("mount", stdout = subprocess.PIPE)
    120     targetMounted = False
    121     for line in p.stdout:
    122         if targetDir in line:
    123             targetMounted = True
    124     p.stdout.close()
    125 
    126     if targetMounted:
    127         print "target dir already mounted"
    128         if os.path.exists(targetDir + '/' + UMOUNT_FILE):
    129             print "Use existing file", UMOUNT_FILE, "to unmount"
    130             sys.exit(1)
    131         else:
    132             print "Will create scripts, but may need manual unmount"
    133 
    134     subdirs += getPDKDirs(manifestFile, groups)
    135     print subdirs
    136     os.system("mkdir -p " + targetDir)
    137     mountf = open(targetDir + '/' + MOUNT_FILE, 'w+')
    138     mountf.write(SH_HEADER)
    139     umountf = open(targetDir + '/' + UMOUNT_FILE, 'w+')
    140     umountf.write(SH_HEADER)
    141     for subdir in subdirs:
    142         os.system("mkdir -p " + targetDir + '/' + subdir)
    143         mountf.write("mount --bind " + sourceDir + "/" + subdir + " " + targetDir + "/" + subdir + \
    144                         "\n")
    145         umountf.write("umount " + targetDir + "/" + subdir + "\n")
    146     for file_name in copy_files_list:
    147         create_symbolic_link(sourceDir, targetDir, file_name)
    148     mountf.close()
    149     umountf.close()
    150     os.system("chmod 700 " + targetDir + '/' + MOUNT_FILE)
    151     os.system("chmod 700 " + targetDir + '/' + UMOUNT_FILE)
    152 
    153 if __name__ == '__main__':
    154     main(sys.argv)
    155