am f72e34eb
: Merge changes I9d3a3c16,I17b5d441,I29e27505,Ia5ca233e,I0a0b200b,I6f412ed4,I623821df,Ifec8e63e,I12d0a847,Idac551e5,I59a88027,I2498139d,I6bd93a87
* commit 'f72e34ebf49ed2a06fe9e37d134f2088e2c0c0e4': Move the old user tagged modules over to base.mk so mini and core both share them. More product debugging. build system changes for jb-aah-dev merge Fail when a non-vendor product references a vendor module. Remove support for user tags in the build system. List the user modules explicitly, and we can get rid of the support for the user tag! Dump the user tagged modules. host modules don't need LOCAL_MODULE_TAGS Don't give the user tag to host modules automatically. Add a phony "nothing" goal that reads the makefiles but doesn't try to build anything. Add tool to parse make dependency info from new --deps flag. Use a more modern -j flag. make product-graph now filtered
This commit is contained in:
@@ -41,7 +41,7 @@ function do_builds
|
||||
do
|
||||
rm -rf $TEST_BUILD_DIR/$PREFIX-$1
|
||||
make PRODUCT-$(echo $1 | sed "s/-.*//" )-installclean
|
||||
make -j6 PRODUCT-$1 dist DIST_DIR=$TEST_BUILD_DIR/$PREFIX-$1
|
||||
make -j16 PRODUCT-$1 dist DIST_DIR=$TEST_BUILD_DIR/$PREFIX-$1
|
||||
if [ $? -ne 0 ] ; then
|
||||
echo FAILED
|
||||
return
|
||||
|
68
tools/filter-product-graph.py
Executable file
68
tools/filter-product-graph.py
Executable file
@@ -0,0 +1,68 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: ts=2 sw=2 nocindent
|
||||
|
||||
import re
|
||||
import sys
|
||||
|
||||
def choose_regex(regs, line):
|
||||
for func,reg in regs:
|
||||
m = reg.match(line)
|
||||
if m:
|
||||
return (func,m)
|
||||
return (None,None)
|
||||
|
||||
def gather(included, deps):
|
||||
result = set()
|
||||
for inc in included:
|
||||
result.add(inc)
|
||||
for d in deps:
|
||||
if inc == d[1]:
|
||||
result.add(d[0])
|
||||
return result
|
||||
|
||||
def main():
|
||||
deps = []
|
||||
infos = []
|
||||
def dependency(m):
|
||||
deps.append((m.group(1), m.group(2)))
|
||||
def info(m):
|
||||
infos.append((m.group(1), m.group(2)))
|
||||
|
||||
REGS = [
|
||||
(dependency, re.compile(r'"(.*)"\s*->\s*"(.*)"')),
|
||||
(info, re.compile(r'"(.*)"(\s*\[.*\])')),
|
||||
]
|
||||
|
||||
lines = sys.stdin.readlines()
|
||||
lines = [line.strip() for line in lines]
|
||||
|
||||
for line in lines:
|
||||
func,m = choose_regex(REGS, line)
|
||||
if func:
|
||||
func(m)
|
||||
|
||||
# filter
|
||||
sys.stderr.write("argv: " + str(sys.argv) + "\n")
|
||||
if not (len(sys.argv) == 2 and sys.argv[1] == "--all"):
|
||||
targets = sys.argv[1:]
|
||||
|
||||
included = set(targets)
|
||||
prevLen = -1
|
||||
while prevLen != len(included):
|
||||
prevLen = len(included)
|
||||
included = gather(included, deps)
|
||||
|
||||
deps = [dep for dep in deps if dep[1] in included]
|
||||
infos = [info for info in infos if info[0] in included]
|
||||
|
||||
print "digraph {"
|
||||
print "graph [ ratio=.5 ];"
|
||||
for dep in deps:
|
||||
print '"%s" -> "%s"' % dep
|
||||
for info in infos:
|
||||
print '"%s"%s' % info
|
||||
print "}"
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
@@ -18,6 +18,5 @@ include $(CLEAR_VARS)
|
||||
LOCAL_SRC_FILES := fs_config.c
|
||||
LOCAL_MODULE := fs_config
|
||||
LOCAL_FORCE_STATIC_EXECUTABLE := true
|
||||
LOCAL_MODULE_TAGS := eng
|
||||
|
||||
include $(BUILD_HOST_EXECUTABLE)
|
||||
|
151
tools/parsedeps.py
Executable file
151
tools/parsedeps.py
Executable file
@@ -0,0 +1,151 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: ts=2 sw=2
|
||||
|
||||
import optparse
|
||||
import re
|
||||
import sys
|
||||
|
||||
|
||||
class Dependency:
|
||||
def __init__(self, tgt):
|
||||
self.tgt = tgt
|
||||
self.pos = ""
|
||||
self.prereqs = set()
|
||||
self.visit = 0
|
||||
|
||||
def add(self, prereq):
|
||||
self.prereqs.add(prereq)
|
||||
|
||||
|
||||
class Dependencies:
|
||||
def __init__(self):
|
||||
self.lines = {}
|
||||
self.__visit = 0
|
||||
self.count = 0
|
||||
|
||||
def add(self, tgt, prereq):
|
||||
t = self.lines.get(tgt)
|
||||
if not t:
|
||||
t = Dependency(tgt)
|
||||
self.lines[tgt] = t
|
||||
p = self.lines.get(prereq)
|
||||
if not p:
|
||||
p = Dependency(prereq)
|
||||
self.lines[prereq] = p
|
||||
t.add(p)
|
||||
self.count = self.count + 1
|
||||
|
||||
def setPos(self, tgt, pos):
|
||||
t = self.lines.get(tgt)
|
||||
if not t:
|
||||
t = Dependency(tgt)
|
||||
self.lines[tgt] = t
|
||||
t.pos = pos
|
||||
|
||||
def get(self, tgt):
|
||||
if self.lines.has_key(tgt):
|
||||
return self.lines[tgt]
|
||||
else:
|
||||
return None
|
||||
|
||||
def __iter__(self):
|
||||
return self.lines.iteritems()
|
||||
|
||||
def trace(self, tgt, prereq):
|
||||
self.__visit = self.__visit + 1
|
||||
d = self.lines.get(tgt)
|
||||
if not d:
|
||||
return
|
||||
return self.__trace(d, prereq)
|
||||
|
||||
def __trace(self, d, prereq):
|
||||
if d.visit == self.__visit:
|
||||
return d.trace
|
||||
if d.tgt == prereq:
|
||||
return [ [ d ], ]
|
||||
d.visit = self.__visit
|
||||
result = []
|
||||
for pre in d.prereqs:
|
||||
recursed = self.__trace(pre, prereq)
|
||||
for r in recursed:
|
||||
result.append([ d ] + r)
|
||||
d.trace = result
|
||||
return result
|
||||
|
||||
def help():
|
||||
print "Commands:"
|
||||
print " dep TARGET Print the prerequisites for TARGET"
|
||||
print " trace TARGET PREREQ Print the paths from TARGET to PREREQ"
|
||||
|
||||
|
||||
def main(argv):
|
||||
opts = optparse.OptionParser()
|
||||
opts.add_option("-i", "--interactive", action="store_true", dest="interactive",
|
||||
help="Interactive mode")
|
||||
(options, args) = opts.parse_args()
|
||||
|
||||
deps = Dependencies()
|
||||
|
||||
filename = args[0]
|
||||
print "Reading %s" % filename
|
||||
|
||||
if True:
|
||||
f = open(filename)
|
||||
for line in f:
|
||||
line = line.strip()
|
||||
if len(line) > 0:
|
||||
if line[0] == '#':
|
||||
pos,tgt = line.rsplit(":", 1)
|
||||
pos = pos[1:].strip()
|
||||
tgt = tgt.strip()
|
||||
deps.setPos(tgt, pos)
|
||||
else:
|
||||
(tgt,prereq) = line.split(':', 1)
|
||||
tgt = tgt.strip()
|
||||
prereq = prereq.strip()
|
||||
deps.add(tgt, prereq)
|
||||
f.close()
|
||||
|
||||
print "Read %d dependencies. %d targets." % (deps.count, len(deps.lines))
|
||||
while True:
|
||||
line = raw_input("target> ")
|
||||
if not line.strip():
|
||||
continue
|
||||
split = line.split()
|
||||
cmd = split[0]
|
||||
if len(split) == 2 and cmd == "dep":
|
||||
tgt = split[1]
|
||||
d = deps.get(tgt)
|
||||
if d:
|
||||
for prereq in d.prereqs:
|
||||
print prereq.tgt
|
||||
elif len(split) == 3 and cmd == "trace":
|
||||
tgt = split[1]
|
||||
prereq = split[2]
|
||||
if False:
|
||||
print "from %s to %s" % (tgt, prereq)
|
||||
trace = deps.trace(tgt, prereq)
|
||||
if trace:
|
||||
width = 0
|
||||
for g in trace:
|
||||
for t in g:
|
||||
if len(t.tgt) > width:
|
||||
width = len(t.tgt)
|
||||
for g in trace:
|
||||
for t in g:
|
||||
if t.pos:
|
||||
print t.tgt, " " * (width-len(t.tgt)), " #", t.pos
|
||||
else:
|
||||
print t.tgt
|
||||
print
|
||||
else:
|
||||
help()
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
main(sys.argv)
|
||||
except KeyboardInterrupt:
|
||||
print
|
||||
except EOFError:
|
||||
print
|
||||
|
160
tools/product_debug.py
Executable file
160
tools/product_debug.py
Executable file
@@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Copyright (C) 2012 The Android Open Source Project
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
import os
|
||||
import re
|
||||
import sys
|
||||
|
||||
def break_lines(key, val):
|
||||
# these don't get split
|
||||
if key in ("PRODUCT_MODEL"):
|
||||
return (key,val)
|
||||
return (key, "\n".join(val.split()))
|
||||
|
||||
def split_line(line):
|
||||
words = line.split("=", 1)
|
||||
if len(words) == 1:
|
||||
return (words[0], "")
|
||||
else:
|
||||
return (words[0], words[1])
|
||||
|
||||
def sort_lines(text):
|
||||
lines = text.split()
|
||||
lines.sort()
|
||||
return "\n".join(lines)
|
||||
|
||||
def parse_variables(lines):
|
||||
return [split_line(line) for line in lines if line.strip()]
|
||||
|
||||
def render_variables(variables):
|
||||
variables = dict(variables)
|
||||
del variables["FILE"]
|
||||
variables = list(variables.iteritems())
|
||||
variables.sort(lambda a, b: cmp(a[0], b[0]))
|
||||
return ("<table id='variables'>"
|
||||
+ "\n".join([ "<tr><th>%(key)s</th><td>%(val)s</td></tr>" % { "key": key, "val": val }
|
||||
for key,val in variables])
|
||||
+"</table>")
|
||||
|
||||
def linkify_inherit(variables, text, func_name):
|
||||
groups = re.split("(\\$\\(call " + func_name + ",.*\\))", text)
|
||||
result = ""
|
||||
for i in range(0,len(groups)/2):
|
||||
i = i * 2
|
||||
result = result + groups[i]
|
||||
s = groups[i+1]
|
||||
href = s.split(",", 1)[1].strip()[:-1]
|
||||
href = href.replace("$(SRC_TARGET_DIR)", "build/target")
|
||||
href = ("../" * variables["FILE"].count("/")) + href + ".html"
|
||||
result = result + "<a href=\"%s\">%s</a>" % (href,s)
|
||||
result = result + groups[-1]
|
||||
return result
|
||||
|
||||
def render_original(variables, text):
|
||||
text = linkify_inherit(variables, text, "inherit-product")
|
||||
text = linkify_inherit(variables, text, "inherit-product-if-exists")
|
||||
return text
|
||||
|
||||
def read_file(fn):
|
||||
f = file(fn)
|
||||
text = f.read()
|
||||
f.close()
|
||||
return text
|
||||
|
||||
def main(argv):
|
||||
# read the variables
|
||||
lines = sys.stdin.readlines()
|
||||
variables = parse_variables(lines)
|
||||
|
||||
# format the variables
|
||||
variables = [break_lines(key,val) for key,val in variables]
|
||||
|
||||
# now it's a dict
|
||||
variables = dict(variables)
|
||||
|
||||
sorted_vars = (
|
||||
"PRODUCT_COPY_FILES",
|
||||
"PRODUCT_PACKAGES",
|
||||
"PRODUCT_LOCALES",
|
||||
"PRODUCT_FACTORY_RAMDISK_MODULES",
|
||||
"PRODUCT_PROPERTY_OVERRIDES",
|
||||
)
|
||||
|
||||
for key in sorted_vars:
|
||||
variables[key] = sort_lines(variables[key])
|
||||
|
||||
# the original file
|
||||
original = read_file(variables["FILE"])
|
||||
|
||||
# formatting
|
||||
values = dict(variables)
|
||||
values.update({
|
||||
"variables": render_variables(variables),
|
||||
"original": render_original(variables, original),
|
||||
})
|
||||
print """<html>
|
||||
|
||||
|
||||
<head>
|
||||
<title>%(FILE)s</title>
|
||||
<style type="text/css">
|
||||
body {
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
padding-bottom: 20px;
|
||||
}
|
||||
#variables {
|
||||
border-collapse: collapse;
|
||||
}
|
||||
#variables th, #variables td {
|
||||
vertical-align: top;
|
||||
text-align: left;
|
||||
border-top: 1px solid #c5cdde;
|
||||
border-bottom: 1px solid #c5cdde;
|
||||
padding: 2px 10px 2px 10px;
|
||||
}
|
||||
#variables th {
|
||||
font-size: 10pt;
|
||||
background-color: #e2ecff
|
||||
}
|
||||
#variables td {
|
||||
background-color: #ebf2ff;
|
||||
white-space: pre;
|
||||
font-size: 10pt;
|
||||
}
|
||||
#original {
|
||||
background-color: #ebf2ff;
|
||||
border-top: 1px solid #c5cdde;
|
||||
border-bottom: 1px solid #c5cdde;
|
||||
padding: 2px 10px 2px 10px;
|
||||
white-space: pre;
|
||||
font-size: 10pt;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<h1>%(FILE)s</h1>
|
||||
<a href="#Original">Original</a>
|
||||
<a href="#Variables">Variables</a>
|
||||
<h2><a name="Original"></a>Original</h2>
|
||||
<div id="original">%(original)s</div>
|
||||
<h2><a name="Variables"></a>Variables</h2>
|
||||
%(variables)s
|
||||
</body>
|
||||
</html>
|
||||
""" % values
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(sys.argv)
|
Reference in New Issue
Block a user