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