[DEV] add a dependency graph generator
lutin dependency:LD ; dot -Tsvg dependency.dot -o dependency.svg ; firefox dependency.svg
This commit is contained in:
parent
f2060d4c97
commit
44dbcdd56d
45
bin/lutin
45
bin/lutin
@ -69,6 +69,15 @@ def usage(full=False):
|
|||||||
print(" clean all (same as previous)")
|
print(" clean all (same as previous)")
|
||||||
print(" " + color['green'] + "dump" + color['default'])
|
print(" " + color['green'] + "dump" + color['default'])
|
||||||
print(" Dump all the module dependency and properties")
|
print(" Dump all the module dependency and properties")
|
||||||
|
print(" " + color['green'] + "dependency" + color['default'])
|
||||||
|
print(" generate a file dependency.dot that represent all the dependency link")
|
||||||
|
print(" Select what in included: 'dependency:LPBDK'")
|
||||||
|
print(" L: Library")
|
||||||
|
print(" P: Pre-build")
|
||||||
|
print(" D: Data")
|
||||||
|
print(" B: Binary")
|
||||||
|
print(" K: Package")
|
||||||
|
print(" eg: lutin dependency:LD ; dot -Tsvg dependency.dot -o dependency.svg ; firefox dependency.svg")
|
||||||
print(" " + color['green'] + "gcov" + color['default'])
|
print(" " + color['green'] + "gcov" + color['default'])
|
||||||
print(" Parse all the code of the library with the gcov resolution")
|
print(" Parse all the code of the library with the gcov resolution")
|
||||||
listOfAllModule = module.list_all_module_with_desc()
|
listOfAllModule = module.list_all_module_with_desc()
|
||||||
@ -169,18 +178,18 @@ def check_boolean(value):
|
|||||||
def parseGenericArg(argument, active):
|
def parseGenericArg(argument, active):
|
||||||
debug.extreme_verbose("parse arg : " + argument.get_option_name() + " " + argument.get_arg() + " active=" + str(active))
|
debug.extreme_verbose("parse arg : " + argument.get_option_name() + " " + argument.get_arg() + " active=" + str(active))
|
||||||
if argument.get_option_name() == "help":
|
if argument.get_option_name() == "help":
|
||||||
if active==False:
|
if active == False:
|
||||||
usage()
|
usage()
|
||||||
return True
|
return True
|
||||||
if argument.get_option_name() == "HELP":
|
if argument.get_option_name() == "HELP":
|
||||||
if active==False:
|
if active == False:
|
||||||
usage(True)
|
usage(True)
|
||||||
return True
|
return True
|
||||||
if argument.get_option_name() == "list-module":
|
if argument.get_option_name() == "list-module":
|
||||||
if active==False:
|
if active == False:
|
||||||
listOfModule = module.list_all_module()
|
list_of_module = module.list_all_module()
|
||||||
retValue = ""
|
retValue = ""
|
||||||
for moduleName in listOfModule:
|
for moduleName in list_of_module:
|
||||||
if retValue != "":
|
if retValue != "":
|
||||||
retValue += " "
|
retValue += " "
|
||||||
retValue += moduleName
|
retValue += moduleName
|
||||||
@ -188,10 +197,10 @@ def parseGenericArg(argument, active):
|
|||||||
exit(0)
|
exit(0)
|
||||||
return True
|
return True
|
||||||
if argument.get_option_name() == "list-target":
|
if argument.get_option_name() == "list-target":
|
||||||
if active==False:
|
if active == False:
|
||||||
listOfTarget = target.list_all_target()
|
list_of_target = target.list_all_target()
|
||||||
retValue = ""
|
retValue = ""
|
||||||
for targetName in listOfTarget:
|
for targetName in list_of_target:
|
||||||
if retValue != "":
|
if retValue != "":
|
||||||
retValue += " "
|
retValue += " "
|
||||||
retValue += targetName
|
retValue += targetName
|
||||||
@ -199,61 +208,61 @@ def parseGenericArg(argument, active):
|
|||||||
exit(0)
|
exit(0)
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name()=="jobs":
|
elif argument.get_option_name()=="jobs":
|
||||||
if active==True:
|
if active == True:
|
||||||
multiprocess.set_core_number(int(argument.get_arg()))
|
multiprocess.set_core_number(int(argument.get_arg()))
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name()=="depth":
|
elif argument.get_option_name()=="depth":
|
||||||
if active==True:
|
if active == True:
|
||||||
env.set_parse_depth(int(argument.get_arg()))
|
env.set_parse_depth(int(argument.get_arg()))
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name() == "verbose":
|
elif argument.get_option_name() == "verbose":
|
||||||
if active==True:
|
if active == True:
|
||||||
debug.set_level(int(argument.get_arg()))
|
debug.set_level(int(argument.get_arg()))
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name() == "color":
|
elif argument.get_option_name() == "color":
|
||||||
if active==True:
|
if active == True:
|
||||||
if check_boolean(argument.get_arg()) == True:
|
if check_boolean(argument.get_arg()) == True:
|
||||||
debug.enable_color()
|
debug.enable_color()
|
||||||
else:
|
else:
|
||||||
debug.disable_color()
|
debug.disable_color()
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name() == "force-build":
|
elif argument.get_option_name() == "force-build":
|
||||||
if active==True:
|
if active == True:
|
||||||
if check_boolean(argument.get_arg()) == True:
|
if check_boolean(argument.get_arg()) == True:
|
||||||
env.set_force_mode(True)
|
env.set_force_mode(True)
|
||||||
else:
|
else:
|
||||||
env.set_force_mode(False)
|
env.set_force_mode(False)
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name() == "pretty":
|
elif argument.get_option_name() == "pretty":
|
||||||
if active==True:
|
if active == True:
|
||||||
if check_boolean(argument.get_arg()) == True:
|
if check_boolean(argument.get_arg()) == True:
|
||||||
env.set_print_pretty_mode(True)
|
env.set_print_pretty_mode(True)
|
||||||
else:
|
else:
|
||||||
env.set_print_pretty_mode(False)
|
env.set_print_pretty_mode(False)
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name() == "force-optimisation":
|
elif argument.get_option_name() == "force-optimisation":
|
||||||
if active==True:
|
if active == True:
|
||||||
if check_boolean(argument.get_arg()) == True:
|
if check_boolean(argument.get_arg()) == True:
|
||||||
env.set_force_optimisation(True)
|
env.set_force_optimisation(True)
|
||||||
else:
|
else:
|
||||||
env.set_force_optimisation(False)
|
env.set_force_optimisation(False)
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name() == "isolate-system":
|
elif argument.get_option_name() == "isolate-system":
|
||||||
if active==True:
|
if active == True:
|
||||||
if check_boolean(argument.get_arg()) == True:
|
if check_boolean(argument.get_arg()) == True:
|
||||||
env.set_isolate_system(True)
|
env.set_isolate_system(True)
|
||||||
else:
|
else:
|
||||||
env.set_isolate_system(False)
|
env.set_isolate_system(False)
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name() == "force-strip":
|
elif argument.get_option_name() == "force-strip":
|
||||||
if active==True:
|
if active == True:
|
||||||
if check_boolean(argument.get_arg()) == True:
|
if check_boolean(argument.get_arg()) == True:
|
||||||
env.set_force_strip_mode(True)
|
env.set_force_strip_mode(True)
|
||||||
else:
|
else:
|
||||||
env.set_force_strip_mode(False)
|
env.set_force_strip_mode(False)
|
||||||
return True
|
return True
|
||||||
elif argument.get_option_name() == "warning":
|
elif argument.get_option_name() == "warning":
|
||||||
if active==True:
|
if active == True:
|
||||||
if check_boolean(argument.get_arg()) == True:
|
if check_boolean(argument.get_arg()) == True:
|
||||||
env.set_warning_mode(True)
|
env.set_warning_mode(True)
|
||||||
else:
|
else:
|
||||||
|
101
lutin/module.py
101
lutin/module.py
@ -1285,6 +1285,107 @@ class Module:
|
|||||||
print('-----------------------------------------------')
|
print('-----------------------------------------------')
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
def check_rules(self, type, rules):
|
||||||
|
if ( ( type == 'LIBRARY' \
|
||||||
|
or type == 'LIBRARY_DYNAMIC' \
|
||||||
|
or type == 'LIBRARY_STATIC' ) \
|
||||||
|
and "L" not in rules ) \
|
||||||
|
or ( type == 'DATA' \
|
||||||
|
and "D" not in rules ) \
|
||||||
|
or ( type == 'PREBUILD'\
|
||||||
|
and "P" not in rules ) \
|
||||||
|
or ( type == 'PACKAGE'\
|
||||||
|
and "K" not in rules) \
|
||||||
|
or ( ( type == 'BINARY' \
|
||||||
|
or type == 'BINARY_SHARED' \
|
||||||
|
or type == 'BINARY_STAND_ALONE')\
|
||||||
|
and "B" not in rules ) :
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
# TODO: Add to simplify the display the possibility to check if an element already depend in dependency of an element ???
|
||||||
|
def dependency_generate(self, target, tmp_file, step, rules):
|
||||||
|
debug.print_element("dot", "dependency.dot", "<<<", self._name)
|
||||||
|
if self.check_rules(self._type, rules) == True:
|
||||||
|
return
|
||||||
|
if step == 1:
|
||||||
|
if self._type == 'DATA':
|
||||||
|
tmp_file.write(' node [\n');
|
||||||
|
tmp_file.write(' shape=Mdiamond;\n');
|
||||||
|
tmp_file.write(' style=filled;\n');
|
||||||
|
tmp_file.write(' color=red;\n');
|
||||||
|
tmp_file.write(' ];\n');
|
||||||
|
elif self._type == 'PREBUILD':
|
||||||
|
tmp_file.write(' node [\n');
|
||||||
|
tmp_file.write(' shape=square;\n');
|
||||||
|
tmp_file.write(' style=filled;\n');
|
||||||
|
tmp_file.write(' color=gray;\n');
|
||||||
|
tmp_file.write(' ];\n');
|
||||||
|
elif self._type == 'LIBRARY' \
|
||||||
|
or self._type == 'LIBRARY_DYNAMIC' \
|
||||||
|
or self._type == 'LIBRARY_STATIC':
|
||||||
|
tmp_file.write(' node [\n');
|
||||||
|
tmp_file.write(' shape=ellipse;\n');
|
||||||
|
tmp_file.write(' style=filled;\n');
|
||||||
|
tmp_file.write(' color=lightblue;\n');
|
||||||
|
tmp_file.write(' ];\n');
|
||||||
|
elif self._type == 'BINARY' \
|
||||||
|
or self._type == 'BINARY_SHARED' \
|
||||||
|
or self._type == 'BINARY_STAND_ALONE':
|
||||||
|
tmp_file.write(' node [\n');
|
||||||
|
tmp_file.write(' shape=rectangle;\n');
|
||||||
|
tmp_file.write(' style=filled;\n');
|
||||||
|
tmp_file.write(' color=green;\n');
|
||||||
|
tmp_file.write(' ];\n');
|
||||||
|
elif self._type == 'PACKAGE':
|
||||||
|
return
|
||||||
|
tmp_file.write(' ' + copy.deepcopy(self._name).replace('-','_')+ ';\n');
|
||||||
|
else:
|
||||||
|
for elem in self._depends:
|
||||||
|
debug.verbose("add depend on: " + elem);
|
||||||
|
tmp_module = None
|
||||||
|
try:
|
||||||
|
tmp_module = target.get_module(elem)
|
||||||
|
except:
|
||||||
|
target.load_if_needed(elem, optionnal=True)
|
||||||
|
try:
|
||||||
|
tmp_module = target.get_module(elem)
|
||||||
|
except:
|
||||||
|
debug.verbose(" ==> get error");
|
||||||
|
if tmp_module == None:
|
||||||
|
debug.verbose(" ==> notFound");
|
||||||
|
continue
|
||||||
|
if self.check_rules(tmp_module._type, rules) == True:
|
||||||
|
debug.verbose(" ==> not in rules");
|
||||||
|
continue
|
||||||
|
tmp_file.write(' ' + copy.deepcopy(self._name).replace('-','_') + ' -> ' + copy.deepcopy(elem).replace('-','_') + ';\n');
|
||||||
|
for elem in self._depends_optionnal:
|
||||||
|
elem = elem[0]
|
||||||
|
debug.verbose("add depend on: " + elem);
|
||||||
|
tmp_module = None
|
||||||
|
try:
|
||||||
|
tmp_module = target.get_module(elem)
|
||||||
|
except:
|
||||||
|
target.load_if_needed(elem, optionnal=True)
|
||||||
|
try:
|
||||||
|
tmp_module = target.get_module(elem)
|
||||||
|
except:
|
||||||
|
debug.verbose(" ==> get error");
|
||||||
|
if tmp_module == None:
|
||||||
|
debug.verbose(" ==> notFound");
|
||||||
|
continue
|
||||||
|
if self.check_rules(tmp_module._type, rules) == True:
|
||||||
|
debug.verbose(" ==> not in rules");
|
||||||
|
continue
|
||||||
|
tmp_file.write(' ' + copy.deepcopy(self._name).replace('-','_') + ' -> ' + copy.deepcopy(elem).replace('-','_') + ';\n');
|
||||||
|
"""
|
||||||
|
tmp_file.write(' module_' + self._name.replace('-','_') + ' {\n');
|
||||||
|
tmp_file.write(' style=filled;\n');
|
||||||
|
tmp_file.write(' color=blue;\n');
|
||||||
|
tmp_file.write(' label="' + self._name + '";\n');
|
||||||
|
tmp_file.write(' }\n');
|
||||||
|
"""
|
||||||
|
|
||||||
##
|
##
|
||||||
## @brief Get packaging property variable
|
## @brief Get packaging property variable
|
||||||
## @param[in] self (handle) Class handle
|
## @param[in] self (handle) Class handle
|
||||||
|
@ -653,11 +653,42 @@ class Target:
|
|||||||
for mod in self.module_list:
|
for mod in self.module_list:
|
||||||
mod.display()
|
mod.display()
|
||||||
return
|
return
|
||||||
|
if name[:10] == "dependency":
|
||||||
|
if len(name) > 10:
|
||||||
|
rules = name.split(":")[1]
|
||||||
|
else:
|
||||||
|
rules = "LBDPK"
|
||||||
|
# L for library
|
||||||
|
# B for binary
|
||||||
|
# D for Data
|
||||||
|
# P for prebuild
|
||||||
|
# K for package
|
||||||
|
debug.print_element("dot", "", "---", "dependency.dot")
|
||||||
|
self.load_all()
|
||||||
|
tmp_file = open("dependency.dot", 'w')
|
||||||
|
tmp_file.write('digraph G {\n')
|
||||||
|
tmp_file.write(' rankdir=\"LR\";\n')
|
||||||
|
for mod in self.module_list:
|
||||||
|
mod.dependency_generate(self, tmp_file, 1, rules)
|
||||||
|
# TODO : do it better ==> system library hook (do a oad of all avillable system library)
|
||||||
|
tmp_file.write(' node [\n');
|
||||||
|
tmp_file.write(' shape=square;\n');
|
||||||
|
tmp_file.write(' style=filled;\n');
|
||||||
|
tmp_file.write(' color=gray;\n');
|
||||||
|
tmp_file.write(' ];\n');
|
||||||
|
# TODO : End hook
|
||||||
|
for mod in self.module_list:
|
||||||
|
mod.dependency_generate(self, tmp_file, 2, rules)
|
||||||
|
tmp_file.write('}\n')
|
||||||
|
tmp_file.flush()
|
||||||
|
tmp_file.close()
|
||||||
|
debug.print_element("dot", "", "---", "dependency.dot")
|
||||||
|
return
|
||||||
if name == "all":
|
if name == "all":
|
||||||
debug.info("build all")
|
debug.info("build all")
|
||||||
self.load_all()
|
self.load_all()
|
||||||
for mod in self.module_list:
|
for mod in self.module_list:
|
||||||
if self._name=="Android":
|
if self._name == "Android":
|
||||||
if mod.get_type() == "PACKAGE":
|
if mod.get_type() == "PACKAGE":
|
||||||
mod.build(self, None)
|
mod.build(self, None)
|
||||||
else:
|
else:
|
||||||
|
Loading…
Reference in New Issue
Block a user