lutin/bin/lutin

472 lines
18 KiB
Python
Executable File

#!/usr/bin/python
# -*- coding: utf-8 -*-
##
## @author Edouard DUPIN
##
## @copyright 2012, Edouard DUPIN, all right reserved
##
## @license MPL v2.0 (see license file)
##
# for path inspection:
import sys
import os
import copy
from realog import debug as debug
import lutin
import death.Arguments as arguments
import death.ArgElement as arg_element
import lutin.host as host
import lutin.module as module
import lutin.target as target
import lutin.env as env
import lutin.multiprocess as multiprocess
import lutin.tools as tools
import lutin.host as lutinHost
import lutin.tools as lutinTools
myArgs = arguments.Arguments()
myArgs.add("h", "help", desc="Display this help")
myArgs.add("H", "HELP", desc="Display this help (with all compleate information)")
myArgs.add("", "version", desc="Display the application version")
myArgs.add_section("option", "Can be set one time in all case")
myArgs.add("v", "verbose", list=[["0","None"],["1","error"],["2","warning"],["3","info"],["4","debug"],["5","verbose"],["6","extreme_verbose"]], desc="display makefile debug level (verbose) default =2")
myArgs.add("C", "color", desc="Display makefile output in color")
myArgs.add("B", "force-build", desc="Force the rebuild without checking the dependency")
myArgs.add("P", "pretty", desc="Print the debug has pretty display")
myArgs.add("j", "jobs", haveParam=True, desc="Specifies the number of jobs (commands) to run simultaneously")
myArgs.add("d", "depth", haveParam=True, desc="Depth of the search of sub element lutin_*.py (default=" + str(env.get_parse_depth()) + ")")
myArgs.add("s", "force-strip", desc="Force the stripping of the compile elements")
myArgs.add("o", "force-optimisation", desc="Force optimisation of the build")
myArgs.add("w", "warning", desc="Store warning in a file build file")
myArgs.add("i", "isolate-system", desc="Isolate system build (copy header of c and c++ system lib to not include unneeded external libs) EXPERIMENTAL (archlinux)")
myArgs.add("K", "ccache", desc="Enable the ccache interface")
myArgs.add_section("properties", "keep in the sequency of the cible")
myArgs.add("t", "target", haveParam=True, desc="Select a target (by default the platform is the computer that compile this) To know list : 'lutin.py --list-target'")
myArgs.add("c", "compilator", list=[["clang",""],["gcc",""]], desc="Compile with clang or Gcc mode (by default " + lutinHost.HOST_DEFAULT_COMPILATOR + " will be used)")
myArgs.add("", "compilator-version", haveParam=True, desc="With travis we need to specify the name of the version if we want to compile with gcc 4.9 ==> --compilator-version=4.9")
myArgs.add("m", "mode", list=[["debug",""],["release",""]], desc="Compile in release or debug mode (default release)")
myArgs.add("a", "arch", list=[["auto","Automatic choice"],["arm","Arm processer"],["x86","Generic PC : AMD/Intel"],["ppc","Power PC"]], desc="Architecture to compile")
myArgs.add("b", "bus", list=[["auto","Automatic choice"],["32","32 bits"],["64","64 bits"]], desc="Adressing size (Bus size)")
myArgs.add("p", "package", desc="Disable the package generation (usefull when just compile for test on linux ...)")
myArgs.add("g", "gcov", desc="Enable code coverage intrusion in code")
myArgs.add("", "simulation", desc="Simulater mode (availlable only for IOS)")
myArgs.add("", "list-target", desc="List all availlables targets ==> for auto completion")
myArgs.add("", "list-module", desc="List all availlables module ==> for auto completion")
myArgs.add_section("cible", "generate in order set")
localArgument = myArgs.parse()
"""
display the help of this makefile
"""
def usage(full=False):
color = debug.get_color_set()
# generic argument displayed :
myArgs.display()
print(" All target can finish with '?clean' '?dump' '?gcov' ... ?action (@ can replace ?)" )
print(" " + color['green'] + "all" + color['default'])
print(" build all (only for the current selected board) (bynary and packages)")
print(" " + color['green'] + "clean" + color['default'])
print(" clean all (same as previous)")
print(" " + color['green'] + "dump" + color['default'])
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(" Parse all the code of the library with the gcov resolution")
listOfAllModule = module.list_all_module_with_desc()
for mod in listOfAllModule:
data_print = " "
if full == False:
if mod["type"] != None \
and mod["type"][:6] == "BINARY":
data_print += color['blue']
if mod["sub-type"] == "":
data_print += "* "
elif mod["sub-type"] == "TEST":
data_print += "T "
elif mod["sub-type"] == "TOOLS":
data_print += "U "
elif mod["sub-type"] == "SAMPLE":
data_print += "S "
else:
data_print += " "
elif mod["type"] != None \
and mod["type"] == "PACKAGE":
data_print += color['red'] + "# "
elif mod["type"] != None \
and mod["type"][:7] == "LIBRARY":
data_print += color['yellow'] + " "
else:
data_print += color['default'] + " "
else:
data_print += color['green']
data_print += mod["name"] + color['default']
if full == False:
data_print += "\r\t\t\t\t\t\t\t"
if mod["license"] != None \
and mod["license"] != "":
data_print += color['yellow'] + " [" + mod["license"] + "]" + color['default']
if mod["version"] != None \
and mod["version"] != []:
version_ID = tools.version_to_string(mod["version"])
data_print += color['blue'] + " (" + version_ID + ")" + color['default']
"""
if mod["compagny-type"] != "" \
and mod["compagny-name"] != "":
data_print += color['purple'] + " " + mod["compagny-type"] + "/" + mod["compagny-name"] + color['default']
elif mod["compagny-name"] != "":
data_print += color['purple'] + " " + mod["compagny-name"] + color['default']
"""
print(data_print)
if mod["description"] != "":
print(" " + mod["description"])
if full == True:
if mod["type"] != None \
and mod["type"] != "":
print(" Type: " + mod["type"])
if mod["sub-type"] != None \
and mod["sub-type"] != "":
print(" Sub-Type: " + mod["sub-type"])
if mod["version"] != None \
and mod["version"] != []:
version_ID = ""
for id in mod["version"]:
if len(version_ID) != 0:
if type(id) == str:
version_ID+="-"
else:
version_ID+="."
version_ID += str(id)
print(" version: " + color['blue'] + version_ID + color['default'])
if mod["compagny-type"] != None \
and mod["compagny-name"] != None \
and mod["compagny-type"] != "" \
and mod["compagny-name"] != "":
print(" compagny: " + color['purple'] + mod["compagny-type"] + "/" + mod["compagny-name"] + color['default'])
elif mod["compagny-name"] != None \
and mod["compagny-name"] != "":
print(" compagny: " + color['purple'] + mod["compagny-name"] + color['default'])
if mod["license"] != None \
and mod["license"] != "":
print(" license: " + color['yellow'] + mod["license"] + color['default'])
if mod["maintainer"] != None \
and mod["maintainer"] != []:
print(" maintainers:")
for elem in mod["maintainer"]:
print(" " + str(elem))
print(" ex simple 1: " + sys.argv[0])
print(" ex simple 2: " + sys.argv[0] + " -t Windows")
print(" ex multiple platform : " + sys.argv[0] + " all --target=Android all -t Windows -m debug all")
print(" ex complex arguments : " + sys.argv[0] + " -cclang -mdebug zeus-package-base?build?run%zeus-launcher:--srv=user:--elog-level=5")
print(" ex gcov: " + sys.argv[0] + " -cgcc --gcov -mdebug etk-test?build?run etk?gcov")
print(" ex gcov with output: " + sys.argv[0] + " -cgcc --gcov -mdebug etk-test?build?run etk?gcov:output")
exit(0)
##
## @brief Display the version of this package.
##
def version():
color = debug.get_color_set()
import pkg_resources
print("version: " + str(pkg_resources.get_distribution('lutin').version))
foldername = os.path.dirname(__file__)
print("source folder is: " + foldername)
exit(0)
def check_boolean(value):
if value == "" \
or value == "1" \
or value == "true" \
or value == "True" \
or value == True:
return True
return False
# preparse the argument to get the verbose element for debug mode
def parseGenericArg(argument, active):
debug.extreme_verbose("parse arg : " + argument.get_option_name() + " " + argument.get_arg() + " active=" + str(active))
if argument.get_option_name() == "help":
if active == False:
usage()
return True
if argument.get_option_name() == "version":
if active == False:
version()
return True
if argument.get_option_name() == "HELP":
if active == False:
usage(True)
return True
if argument.get_option_name() == "list-module":
if active == False:
list_of_module = module.list_all_module()
retValue = ""
for moduleName in list_of_module:
if retValue != "":
retValue += " "
retValue += moduleName
print(retValue)
exit(0)
return True
if argument.get_option_name() == "list-target":
if active == False:
list_of_target = target.list_all_target()
retValue = ""
for targetName in list_of_target:
if retValue != "":
retValue += " "
retValue += targetName
print(retValue)
exit(0)
return True
elif argument.get_option_name()=="jobs":
if active == True:
multiprocess.set_core_number(int(argument.get_arg()))
return True
elif argument.get_option_name()=="depth":
if active == True:
env.set_parse_depth(int(argument.get_arg()))
return True
elif argument.get_option_name()=="ccache":
if active == True:
if check_boolean(argument.get_arg()) == True:
env.set_ccache(True)
else:
env.set_ccache(False)
return True
elif argument.get_option_name() == "verbose":
if active == True:
debug.set_level(int(argument.get_arg()))
return True
elif argument.get_option_name() == "color":
if active == True:
if check_boolean(argument.get_arg()) == True:
debug.enable_color()
else:
debug.disable_color()
return True
elif argument.get_option_name() == "force-build":
if active == True:
if check_boolean(argument.get_arg()) == True:
env.set_force_mode(True)
else:
env.set_force_mode(False)
return True
elif argument.get_option_name() == "pretty":
if active == True:
if check_boolean(argument.get_arg()) == True:
env.set_print_pretty_mode(True)
else:
env.set_print_pretty_mode(False)
return True
elif argument.get_option_name() == "force-optimisation":
if active == True:
if check_boolean(argument.get_arg()) == True:
env.set_force_optimisation(True)
else:
env.set_force_optimisation(False)
return True
elif argument.get_option_name() == "isolate-system":
if active == True:
if check_boolean(argument.get_arg()) == True:
env.set_isolate_system(True)
else:
env.set_isolate_system(False)
return True
elif argument.get_option_name() == "force-strip":
if active == True:
if check_boolean(argument.get_arg()) == True:
env.set_force_strip_mode(True)
else:
env.set_force_strip_mode(False)
return True
elif argument.get_option_name() == "warning":
if active == True:
if check_boolean(argument.get_arg()) == True:
env.set_warning_mode(True)
else:
env.set_warning_mode(False)
return True
return False
# open configuration of lutin:
config_file_name = "lutinConfig.py"
config_file = os.path.join(tools.get_run_path(), config_file_name)
if os.path.isfile(config_file) == True:
sys.path.append(os.path.dirname(config_file))
debug.debug("Find basic configuration file: '" + config_file + "'")
# the file exist, we can open it and get the initial configuration:
configuration_file = __import__(config_file_name[:-3])
if "get_exclude_path" in dir(configuration_file):
data = configuration_file.get_exclude_path()
debug.debug(" get default config 'get_exclude_path' val='" + str(data) + "'")
env.set_exclude_search_path(data)
if "get_parsing_depth" in dir(configuration_file):
data = configuration_file.get_parsing_depth()
debug.debug(" get default config 'get_parsing_depth' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("depth", str(data)), True)
if "get_ccache" in dir(configuration_file):
data = configuration_file.get_ccache()
debug.debug(" get default config 'get_ccache' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("ccache", str(data)), True)
if "get_default_jobs" in dir(configuration_file):
data = configuration_file.get_default_jobs()
debug.debug(" get default config 'get_default_jobs' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("jobs", str(data)), True)
if "get_default_color" in dir(configuration_file):
data = configuration_file.get_default_color()
debug.debug(" get default config 'get_default_color' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("color", str(data)), True)
if "get_default_debug_level" in dir(configuration_file):
data = configuration_file.get_default_debug_level()
debug.debug(" get default config 'get_default_debug_level' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("verbose", str(data)), True)
if "get_default_print_pretty" in dir(configuration_file):
data = configuration_file.get_default_print_pretty()
debug.debug(" get default config 'get_default_print_pretty' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("pretty", str(data)), True)
if "get_default_force_optimisation" in dir(configuration_file):
data = configuration_file.get_default_force_optimisation()
debug.debug(" get default config 'get_default_force_optimisation' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("force-optimisation", str(data)), True)
if "get_default_isolate_system" in dir(configuration_file):
data = configuration_file.get_default_isolate_system()
debug.debug(" get default config 'get_default_isolate_system' val='" + str(data) + "'")
parseGenericArg(arg_element.ArgElement("isolate-system", str(data)), True)
# parse default unique argument:
for argument in localArgument:
parseGenericArg(argument, True)
# initialize the system ...
lutin.init()
#available target : Linux / MacOs / Windows / Android ...
targetName = host.OS
config = {
"compilator":lutinHost.HOST_DEFAULT_COMPILATOR,
"mode":"release",
"bus-size":"auto",
"arch":"auto",
"generate-package":True,
"simulation":False,
"gcov":False,
"compilator-version":""
}
# load the default target :
my_target = None
actionDone=False
# parse all argument
for argument in localArgument:
if parseGenericArg(argument, False) == True:
continue
elif argument.get_option_name() == "compilator-version":
config["compilator-version"] = argument.get_arg()
elif argument.get_option_name() == "package":
config["generate-package"]=False
elif argument.get_option_name() == "simulation":
config["simulation"]=True
elif argument.get_option_name() == "gcov":
config["gcov"]=True
elif argument.get_option_name() == "bus":
config["bus-size"]=argument.get_arg()
elif argument.get_option_name() == "arch":
config["arch"]=argument.get_arg()
elif argument.get_option_name() == "compilator":
if config["compilator"] != argument.get_arg():
debug.debug("change compilator ==> " + argument.get_arg())
config["compilator"] = argument.get_arg()
#remove previous target
my_target = None
elif argument.get_option_name() == "target":
# No check input ==> this will be verify automaticly chen the target will be loaded
if targetName != argument.get_arg():
targetName = argument.get_arg()
debug.debug("change target ==> '" + targetName + "' & reset mode : gcc&release")
#reset properties by defauult:
config = {
"compilator":lutinHost.HOST_DEFAULT_COMPILATOR,
"mode":"release",
"bus-size":"auto",
"arch":"auto",
"generate-package":True,
"simulation":False,
"gcov":False,
"compilator-version":""
}
#remove previous target
my_target = None
elif argument.get_option_name() == "mode":
if config["mode"] != argument.get_arg():
config["mode"] = argument.get_arg()
debug.debug("change mode ==> " + config["mode"])
#remove previous target
my_target = None
else:
argument_value = argument.get_arg()
debug.debug("something request : '" + argument_value + "'")
if argument.get_option_name() != "":
debug.warning("Can not understand argument : '" + argument.get_option_name() + "'")
usage()
break;
name2 = argument_value.replace("@", "?")
gettedElement = name2.split("?")
module_name = gettedElement[0]
action_list = gettedElement[1:]
if len(action_list) == 0:
action_list = "build"
debug.debug("requested: '" + module_name + "' ? actions:'" + str(action_list) + "'")
multiple_module_list = []
if module_name[-1] == "*":
base_name = module_name[:-1]
for mod in module.list_all_module():
if mod[:len(base_name)] == base_name:
debug.verbose("need do it for: " + mod);
multiple_module_list.append(mod)
else:
multiple_module_list.append(module_name)
debug.debug("Will do: '" + str(multiple_module_list) + "' ? actions:'" + str(action_list) + "'")
for module_name in multiple_module_list:
#load the target if needed :
if my_target == None:
my_target = target.load_target(targetName, copy.deepcopy(config))
my_target.build(module_name, actions=action_list)
actionDone=True
# if no action done : we do "all" ...
if actionDone==False:
#load the target if needed :
if my_target == None:
my_target = target.load_target(targetName, config)
my_target.build("all")
# stop all started threads;
multiprocess.un_init()