X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=runInstall;h=70bfc6c47c4ea60d983f5601fc599020c4c9fee5;hb=d64a019a9eab3aa74d6f432c67439c06c129591e;hp=2f81342139fa2f57b02e0127b677b87a251bcb20;hpb=eb87ab81ad0bcc615fdd5c7c02401da7470e9d1f;p=tools%2Finstall.git diff --git a/runInstall b/runInstall index 2f81342..70bfc6c 100755 --- a/runInstall +++ b/runInstall @@ -1,587 +1,1393 @@ #!/usr/bin/env python -import xmllib -import sys, os, string, re - -#============================================================== -# get_help_info -#============================================================== -def get_help_info() : - str = "\nPAL/SALOME Installation Wizard\n\n" - str = str + "\tUsage : \n\tInstall [-g|b] [-f ] [-t ] [-tmp ]\n" - str = str + "\n" - str = str + " -g Runs the Installation Wizard in the GUI mode.\n" - str = str + " In this case only is taken into account \n" - str = str + " from the parameters list. This key is default.\n" - str = str + "\n" - str = str + " -b Runs the Installation Wizard in the batch mode.\n" - str = str + " All the found parameters are taken in to account.\n" - str = str + "\n" - str = str + " -f The configuration file to be parsed by the Installation Wizard.\n" - str = str + " If this parameter is missed then the script tries to define\n" - str = str + " the Red Hat version and use the corresponding xml. For example,\n" - str = str + " for Red Hat 8.0 config_RedHat8_0.xml file is supposed to be used\n" - str = str + " by default. If the appropriate xml file is not found, the config.xml\n" - str = str + " is used by default.\n" - str = str + "\n" - str = str + " -t The target directory the products to be installed to.\n" - str = str + " This parameter overloads the target directory described in the\n" - str = str + " configuration file.\n" - str = str + "\n" - str = str + " -tmp The directory which should be used for the temporary files.\n" - str = str + " This parameter overloads the temporary directory described in the\n" - str = str + " configuration file.\n" - str = str + "\n" - str = str + " -h Prints help information.\n" - return str - -#============================================================== -# error_exit -#============================================================== -def error_exit (str = ""): - import sys - if len(str): res = "\n" + str + "\n" - else : res = "" - print res + \ - get_help_info() - sys.exit(1); +""" +Installation Wizard launching script. + +This script is the part of the SALOME installation procedure. +Author : Vadim SANDLER, Open CASCADE SAS (vadim.sandler@opencascade.com) +Created : Thu Dec 18 12:01:00 2002 +Copyright : 2002-2008 CEA + +""" + +__version__ = "1.1.5" + +# --- imports --- # +import sys +try: + import xml.sax, xml.dom.minidom + import os, re + import types + import random + import warnings +except Exception, an_exc: + sys.exit("Error: %s! Please check the installed Python package." % str(an_exc)) + pass + +# --- avoid "deprecation" warnings --- # +warnings.filterwarnings("ignore", "", DeprecationWarning) + +# --- global variables --- # +opt_parser = None +root_path = None + +# --- actions definition --- # +__BINARIES__ = "install_binary" +__BUILDSRC__ = "install_source_and_build" +__PREINSTALL__ = "try_preinstalled" + +# --- product type definition --- # +__CTX__COMPONENT__ = "component" +__CTX__PREREQUISITE__ = "prerequisite" + +#------------------------------------------------------------------# +# # +# COMMAND LINE ARGUMENTS PARSER # +# # +#------------------------------------------------------------------# +#=================================================================== +# class OptBaseError : base parse error +#=================================================================== +class OptBaseError(Exception): + """ + Base option parsing exception class + """ + def __init__(self, msg): + self.msg = msg + def __str__ (self): + return self.msg -#============================================================== -# Cheks whether the passed parameter is a key. -#============================================================== -def is_key ( val ): - import re - if val is not None : - return re.match(r'^-[a-zA-Z]', val) - return 0 +#=================================================================== +# class OptError : bad option error +#=================================================================== +class OptError(OptBaseError): + """ + Bad option exception class + """ + def __init__ (self, msg, option): + self.msg = msg + self.option = option + def __str__ (self): + if self.option: + opt_prs = "" + if self.option.short_opt and self.option.long_opt: + opt_prs = "%s/%s"%(self.option.short_opt,self.option.long_opt) + elif self.option.short_opt: + opt_prs = "%s"%(self.option.short_opt) + elif self.option.long_opt: + opt_prs = "%s"%(self.option.long_opt) + return "option %s: %s"%(opt_prs, self.msg) + return self.msg -#============================================================== -# From the list of parameters extracts value following 'key' -#============================================================== -def extract_parameter ( key, args ) : - import sys - length = len(args); - if ( length == 0 ) : return None - - found = 0; - - for i in range(0, length-1): - if args[i] == key : - if ( is_key ( args[i+1]) ) : - print " No value after key ", key - sys.exit(1); - - value = args[i+1] - if ( i < length - 2 and is_key ( args[i+2] ) == 0 ) : #control that only one value follows key - #(not a list). In this case params are correct. - print "Too much values after key ", key - sys.exit(1); - - found = 1; break; - - if (found) : - return value - - return None +#=================================================================== +# class ArgError : bad option argument error +#=================================================================== +class ArgError(OptBaseError): + """ + Bad argument exception class + """ + pass +#=================================================================== +# class ValError : bad command line parameter error +#=================================================================== +class ValError(OptBaseError): + """ + Bad parameter exception class + """ + pass -#=============================================================== -# Extracts list of values following specified 'key' from 'args[]' -#=============================================================== -def extract_list (key, args) : +#=================================================================== +# class ArgOption : command line option +#=================================================================== +class ArgOption: + """ + Option class + """ + attrs = ["short_opt", "long_opt", "dest", "action", "type", "default", "metavar", "help"] + actions = ["store", "store_true", "store_false"] + types = ["string", "int", "float", "bool"] + def __init__(self, *args, **kwargs): + # set defaults + for attr in self.attrs: setattr(self, attr, None) + # parse arguments + for i in range(len(args)): + if i > len(self.attrs)-1: + msg = "Wrong number of parameters is given (maximum is %d)" % len(self.attrs) + raise OptBaseError(msg) + setattr(self, self.attrs[i], args[i]) + for arg in kwargs: + if arg not in self.attrs: + msg = "Invalid argument: %s" % arg + raise OptBaseError(msg) + setattr(self, arg, kwargs[arg]) + # check short option key + if self.short_opt and \ + not re.match("^-[a-zA-Z]$",self.short_opt): + msg = "invalid short option key; " + msg += "should be of the form -x (x is letter)" + raise OptError(msg, self) + # check long option key + if self.long_opt and \ + not re.match("^--[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*$",self.long_opt): + msg = "invalid long option key; " + msg += "should be of the form --word[[-word]...] " + msg += "(word is letters and digits sequence)" + raise OptError(msg, self) + # check that at least one option key is defined + if not self.short_opt and not self.long_opt: + msg = "invalid option; neither short nor long option key is defined" + raise OptError(msg, self) + # destination + if not self.dest and self.long_opt: + self.dest = self.long_opt[2:].replace('-','_') + if not self.dest and self.short_opt: + self.dest = self.short_opt[1:] + # action + if not self.action: + self.action = "store" + if self.action not in self.actions: + msg = "invalid action: %s" % self.action + raise OptError(msg, self) + # type + if not self.type: + if self.action in ["store_true","store_false"]: self.type = "bool" + else: self.type = "string" + if self.type not in self.types: + msg = "invalid type: %s" % self.type + raise OptError(msg, self) + if self.action in ["store_true","store_false"] and self.type != "bool": + msg = "invalid type: %s : should be 'bool' or None" % self.type + raise OptError(msg, self) + # default + if self.default is not None: + try: + if self.type == "string": self.default = str(self.default) + if self.type == "int": self.default = int(self.default) + if self.type == "float": self.default = float(self.default) + if self.type == "bool": self.default = boolean(self.default) + except : + msg = "invalid default value type: should be %s" % self.type + raise OptError(msg, self) + pass + # metavar + if not self.metavar: + self.metavar = self.dest.upper() + # help + if not self.help: + self.help = "" + pass - lenght = len(args) - if ( args is None or lenght == 0 ): - error_exit() + def to_string(self): + """ + Returns string representation of the option + """ + opts = [] + opt = self.short_opt + if opt and self.action == "store" and self.metavar: opt += " %s" % self.metavar + if opt: opts.append(opt) + opt = self.long_opt + if opt and self.action == "store" and self.metavar: opt += "=%s" % self.metavar + if opt: opts.append(opt) + return (", ").join(opts) + +#=================================================================== +# class Values : resulting option values +#=================================================================== +class Values: + """ + Values class + """ + def __init__(self): + pass + +#=================================================================== +# class ArgParser : command line arguments parser +#=================================================================== +class ArgParser: + """ + Arguments parser class + """ + def __init__(self): + self.options = [] + pass - list=[] - found = 0 + def add_option(self, *args, **kwargs): + """Register an option""" + o = ArgOption(*args, **kwargs) + self._check_option(o) + self.options.append(o) + pass - for i in range(0, length) : - if args[i] == key : - if (is_key ( args[i+1])) : - error_exit(); - - for i in range (i+1, lenght): - if is_key(args[i]) : break - list.append(args[i]) - found =1; break - - return list; #empty list is returned if no values after key + def parse_args(self, args = None): + """Parse an arguments""" + if not args: args = sys.argv[1:] + values = Values() + for o in self.options: + if o.default is not None: + setattr(values, o.dest, o.default) + elif not hasattr(values,o.dest): + setattr(values, o.dest, None) + try: + (values, args) = self._process_args(values, args) + except (ArgError, ValError), e: + self._error(e.msg) + + return (values, args) + + def print_usage(self): + """Print usage""" + print "usage: %s [options]" % os.path.basename(sys.argv[0]) + pass + def print_help(self): + """Print help""" + self.print_usage() + print "" + olen = 0 + _maxwidth, _indent = 79, 2 + if len(self.options): + for option in self.options: + if olen < len(option.to_string()): olen = len(option.to_string()) + print "options:" + for option in self.options: + strings = [] + for hs in option.help.split("\n"): + s = "" + for w in hs.split(): + if len("%s %s" % (s,w)) > _maxwidth: + strings.append(s.strip()); s = "" + s = "%s %s" % (s,w) + if s.strip(): strings.append(s.strip()) + if not strings: strings[:0] = [""] + print "%s%s%s" % (option.to_string(), " "*(_indent+olen-len(option.to_string())), strings[0]) + for i in range(1, len(strings)): + print "%s%s" % (" "*(olen+_indent), strings[i]) + pass + + def _check_option(self, option): + o = self._get_option(option.short_opt) + if not o: o = self._get_option(option.long_opt) + if o: + msg = "option conflicts with previously defined option(s)" + raise OptError(msg, option) + pass -#============================================================== -# Method find the $key in the list and return 1 if success -# and 0 otherwise. -#============================================================== -def find_key (key, argv) : + def _get_option(self, opt_key): + if opt_key: + for o in self.options: + if opt_key in [o.short_opt, o.long_opt]: return o + return None + + def _error(self, msg): + self.print_usage() + sys.exit("\n%s: error: %s\n" % (os.path.basename(sys.argv[0]), msg)) + pass - if (not is_key(key)) : return 0 + def _check_value(self, option, value): + o = self._get_option(option) + try: + if o.type == "string": return str(value) + if o.type == "int": return int(value) + if o.type == "float": return float(value) + if o.type == "bool": return boolean(value) + except: + msg = "invalid value type for option %s: %s; " % (option, value) + msg += "should be %s" % o.type + raise ValError(msg) + raise OptBaseError("unknown error") + + def _process_args(self, values, args): + res_args = [] + cur_opt = None + rargs = [] + for index in range(len(args)): + a = args[index] + if cur_opt and cur_opt[1].action == "store": + setattr(values, cur_opt[1].dest, self._check_value(cur_opt[0], a)) + cur_opt = None + continue + if a == "-": + rargs = args[index+1:] + break + elif re.match("^-[a-zA-Z].*", a): + for i in range(1,len(a)): + if cur_opt and cur_opt[1].action == "store": + setattr(values, cur_opt[1].dest, self._check_value(cur_opt[0], a[i:])) + cur_opt = None + break + o = self._get_option("-%s"%a[i]) + if not o: + raise ArgError("no such option: -%s"%a[i]) + if o.action == "store_true": + setattr(values, o.dest, True) + elif o.action == "store_false": + setattr(values, o.dest, False) + else: + cur_opt = ("-%s"%a[i], o) + pass + elif re.match("^--[a-zA-Z][a-zA-Z0-9]*(-[a-zA-Z0-9]+)*", a): + oname = ("%s="%a).split("=")[0] + ovalue = ("%s="%a).split("=")[1] + o = self._get_option(oname) + if not o: + raise ArgError("no such option: %s" % oname) + if o.action == "store_true": + if ovalue: + raise ValError("option %s does not take a value" % oname) + setattr(values, o.dest, True) + elif o.action == "store_false": + if ovalue: + raise ValError("option %s does not take a value" % oname) + setattr(values, o.dest, False) + else: + if ovalue: + setattr(values, o.dest, self._check_value(oname, ovalue)) + else: + cur_opt = (oname, o) + pass + elif a.startswith("-"): + raise ArgError("bad formatted option: %s" % a) + else: + rargs = args[index:] + break + if cur_opt and cur_opt[1].action == "store": + raise ValError("option %s requires value" % cur_opt[0]) + return (values, rargs) + +#------------------------------------------------------------------# +# # +# XML CONFIGURATION FILES PARSER # +# # +#------------------------------------------------------------------# - for simbol in argv : - if simbol == key: - return 1 - return 0 +#=================================================================== +# class Config : general configuration options : version, target and +# temporary directories, etc... +#=================================================================== +class Config : + """ + General configuration file options: + - Install Wizard window caption + - SALOME platform version + - Copyright and license info + - Default target and temporary directories + - List of optional libraries for Salome + """ + def __init__(self, + theVersion = None, + theCaption = None, + theCopyright = None, + theLicense = None, + thePlatforms = None, + theTargetdir = None, + theTmpdir = None, + theOptLibs = None): + self.version = strip(theVersion) + self.caption = strip(theCaption) + self.copyright = strip(theCopyright) + self.license = strip(theLicense) + self.platforms = strip(thePlatforms) + self.targetdir = strip(theTargetdir) + self.tmpdir = strip(theTmpdir) + self.optlibs = strip(theOptLibs) #============================================================== -# Parse the list of parameters +# class Product : pre-requisite product options #============================================================== -def parse_parameters (args) : - - if find_key('-h', args) : - print get_help_info(); - import sys - sys.exit(0) +class Product : + """ + Product options: + - name, version + - target Linux OS version + - dependencies + - required disk space + - installation script + - etc... + """ + def __init__(self, + theName, + theType = None, + theOS = None, + theVersion = None, + theDependencies = None, + theWoGuiInstallation = None, + theInstalldiskspace = None, + theScript = None, + thePickUpEnvironment = None): + self.name = strip(theName) + self.type = strip(theType) + self.os = strip(theOS) + self.version = strip(theVersion) + self.dependencies = strip(theDependencies) + self.woguiinst = strip(theWoGuiInstallation) + self.installdiskspace = strip(theInstalldiskspace) + self.script = strip(theScript) + self.pickupEnv = strip(thePickUpEnvironment) + self.whattodo = __BINARIES__ - xmlfile = extract_parameter("-f", args) - target_dir = extract_parameter("-t", args) - tmp_dir = extract_parameter("-tmp", args) - if find_key('-b', args): - is_gui = 0 - else : is_gui = 1 - return [xmlfile, target_dir, tmp_dir, is_gui] - - -#================================================================= -# The first algorithm to create the dependencies list by their level -#================================================================= -def get_next_level(list, products): + def setMode(self, mode): + if mode not in [__BINARIES__, __BUILDSRC__, __PREINSTALL__]: + return + self.whattodo = mode + return + +#=================================================================== +# class ConfigParser : XML files parser implementation +#=================================================================== +class ConfigParser: + """ + XML configuration files parser + """ + def __init__(self, is_force_src=False, pltname=None): + self.docElem = None + self.products = [] + self.full_prods_list = [] + self.config = None + self.is_force_src = is_force_src + self.pltname = pltname + pass + + def parse_config(self): + # Parse 'config' part of the XML file + configElem = self.docElem.getElementsByTagName('config')[0] + + self.config = Config(configElem.getAttribute('version').strip(), + configElem.getAttribute('caption').strip(), + configElem.getAttribute('copyright').strip(), + configElem.getAttribute('license').strip(), + configElem.getAttribute('platforms').strip(), + configElem.getAttribute('targetdir').strip(), + configElem.getAttribute('tempdir').strip(), + configElem.getAttribute('optionallibs').strip()) + if not self.pltname and self.config.platforms: + self.pltname = self.config.platforms.split(",")[0].strip() + pass - import re - result = [] - expr = "(" + list[0].name - for i in range(1, len(list)): - expr = expr + "|"+ list[i].name + def parse_dependencies(self): + # Parse 'dependencies' part of the XML file + depsMap = {} + depsElem = self.docElem.getElementsByTagName('dependencies')[0] + for prodElem in depsElem.getElementsByTagName('product'): + prodName = prodElem.getAttribute('name').strip() + if not prodName: continue + depsList = [] + for depElem in prodElem.getElementsByTagName('dep'): + depsList.append(depElem.firstChild.data) + pass + depsMap[prodName] = depsList + pass + return depsMap - expr = expr + ")$" - #expr=re.compile(expr) - - for product in products: - deps = re.sub(r'\s+', "", product.dependencies) - if re.search(expr, deps): - result.append(product) + def parse_product(self): + # Parse 'products' part of the XML file + depsMap = self.parse_dependencies() + prodsElem = self.docElem.getElementsByTagName('products')[0] + sal_prods_list = []; req_prods_list = [] + modules_list = []; prereqs_list = [] + for prodElem in prodsElem.getElementsByTagName('product'): + prodName = prodElem.getAttribute('name').strip() + if not prodName: continue + instElems = prodElem.getElementsByTagName('installation') + instElem = None + for node in instElems: + if not self.pltname or self.pltname == node.getAttribute('os').strip(): + instElem = node + break + pass + if not instElem: continue + if check_bool(str(instElem.getAttribute('disable').strip())): continue + depsList = [] + if prodName in depsMap: depsList = depsMap[prodName] + aProduct = Product(prodName, + prodElem.getAttribute('type').strip(), + instElem.getAttribute('os').strip(), + instElem.getAttribute('version').strip(), + depsList, + instElem.getAttribute('woguimode').strip(), + instElem.getAttribute('installdiskspace').strip(), + instElem.getAttribute('script').strip(), + instElem.getAttribute('pickupenv').strip()) + if self.is_force_src: + aProduct.setMode(__BUILDSRC__) + pass + if prodElem.getAttribute('type').strip() == "component": + sal_prods_list.append(aProduct) + # fill an ordered modules list ----------- + modules_list.append(prodName) + modules_list.append(prodName + "_src") + pass + else: #prerequisite + req_prods_list.append(aProduct) + # fill an ordered prerequisites list ----------- + prereqs_list.append(prodName) + #AKL: prerequisite sources and temp files are removed, by default. + # So, there is no need to make sources environment + #if aProduct.whattodo == __BUILDSRC__: prereqs_list.append(prodName + "_src") + pass + pass + self.products.extend( req_prods_list ) + self.products.extend( sal_prods_list ) + if len(self.products) != 0: + gcc_product = Product("gcc", + __CTX__PREREQUISITE__, + self.products[0].os, + "", + [], + None, + "0,0,0", + "gcc-common.sh", + "") + gcc_product.setMode(__PREINSTALL__) + self.products.insert(0, gcc_product) + prereqs_list.insert(0, gcc_product.name) + pass + self.full_prods_list.extend( prereqs_list ) + self.full_prods_list.extend( modules_list ) + pass - return result + def parse(self, xml_file): + filehandle = open(xml_file) + sax_parser = xml.sax.make_parser() + doc = xml.dom.minidom.parse(filehandle, sax_parser) + filehandle.close() + self.docElem = doc.documentElement + self.parse_config() + self.parse_product() + pass -def create_levels(prods): - import copy - - products = copy.deepcopy(prods) - - result = {} - import re - #1. find the products with empty lists of dependencies - list = [] - for product in products: - if len(re.sub(r'\s', "", product.dependencies)) == 0 : - list.append(product) + def getProduct(self, prod): + for product in self.products: + if product.name == prod: + return product + return None - if len(list) == 0 : - raise RuntimeError, "Products that depend on nothing are not found" - # remove the first level products from the common list of products - for product in list : - products.remove(product) +#------------------------------------------------------------------# +# # +# SERVICE FUNCTIONS # +# # +#------------------------------------------------------------------# - ind = 0; - result[0] = list +#============================================================== +# message: prints diagnostic information +#============================================================== +def message(msg): + """ + Prints diagnostic information. + """ + if msg.strip(): + print ">>>", msg + pass - while (len(products)) : - res = get_next_level(list, products) - if len(res) == 0 : - raise RuntimeError, "Empty list of products is found" +#============================================================== +# warning: prints warning +#============================================================== +def warning(msg): + """ + Prints warning. + """ + if msg.strip(): + print "" + print msg + print "" + pass - for product in res : - products.remove(product) +#============================================================== +# error_exit : prints (optionally) error string, then prints +# help information and quits +#============================================================== +def error_exit(msg = "", print_help = True): + """ + Prints (optionally) error string, + then prints help information and quits. + """ + # print error message + if len(msg.strip()): + print "" + print msg + print "" + # print help information + if print_help: + global opt_parser + if opt_parser: + opt_parser.print_help() + print "" + # cleaning + clean_all() + # quit + sys.exit(1); + pass - ind = ind +1 - result[ind] = res - list = res - - str = "" - for i in result.keys(): - for product in result[i]: - str = str + product.name + " " +#============================================================== +# boolean : Converts string to boolean value. +#============================================================== +def boolean(val): + """ + Converts string to boolean value if possible. + Raises exception if wrong string is used. + """ + if isinstance(val, types.StringType): + if val.strip().lower() in ["true", "yes", "ok"] : return True + elif val.strip().lower() in ["false", "no", "cancel"] : return False + else: raise TypeError("invalid boolean value") + return bool(val) - return str; - #================================================================= -# The second algorithm +# check_bool : checks boolean value: yes/no, true/false, 1/0 #================================================================= -def get_dependencies_set(prods) : - import copy - import re - - products = copy.deepcopy(prods) - deps = "" - list = [] - - while (len(products)) : - - tmplist = [] - #find the products with empty list of dependencies - for product in products: - product.dependencies = re.sub(r'\s+$', "", product.dependencies) - product.dependencies = re.sub(r'^\s+', "", product.dependencies) - - if len(product.dependencies) == 0 : - tmplist.append(product); - deps = deps + " " + product.name - - list.append(tmplist) - - #remove the products names from other products dependencies - for item in tmplist: - products.remove(item) - - regexpr1 = "((^|,(\s+)?)"+item.name+"$|^"+item.name+"(\s+)?,(\s+)?)" - regexpr2 = ",(\s+)?"+item.name+"(\s+)?,(\s+)?" +def check_bool(val): + """ + Checks boolean value. + """ + try: + return boolean(val) + except: + pass + return False - for product in products: - product.dependencies = re.sub(r'\s+$', "", product.dependencies) - product.dependencies = re.sub(r'^\s+', "", product.dependencies) +#============================================================== +# clean_all : performs system cleaning before exiting +#============================================================== +def clean_all(): + """ + Performs system cleaning before exiting. + """ + global root_path + remove_dir(root_path) + pass - product.dependencies = re.sub(regexpr1, "", product.dependencies) - product.dependencies = re.sub(regexpr2, ",", product.dependencies) +#============================================================== +# parse_parameters : parses command line arguments +#============================================================== +def parse_parameters(): + """ + Parses command line arguments. + """ + global opt_parser + opt_parser = ArgParser() + + help_str = "Runs the Installation Wizard in the GUI mode [default].\n" + opt_parser.add_option("-g", + "--gui", + action="store_true", + dest="gui", + default=True, + help=help_str) + help_str = "Runs the Installation Wizard in the TUI mode." + opt_parser.add_option("-b", + "--batch", + action="store_false", + dest="gui", + help=help_str) + help_str = "The configuration xml file.\n" + help_str += "If this parameter is missing, then the program tries to define the " + help_str += "Linux platform and use the corresponding xml file. For example, " + help_str += "for Red Hat 8.0 config_RedHat_8.0.xml file is used in this case. " + opt_parser.add_option("-f", + "--file", + action="store", + dest="xmlfile", + metavar="FILE", + help=help_str) + help_str = "The platform specification.\n" + help_str += "This option can be used in conjunction with --file option in order" + help_str += "to specify Linux platform name when XML file contains installation" + help_str += "options for several platforms." + opt_parser.add_option("-p", + "--platform", + action="store", + dest="platform", + metavar="PLT", + help=help_str) + help_str = "The target directory the products to be installed to.\n" + help_str += "When used this parameter overrides the default target directory " + help_str += "defined in the configuration xml file." + opt_parser.add_option("-d", + "--target", + action="store", + dest="target_dir", + metavar="DIR", + help=help_str) + help_str = "The directory to be used for temporary files.\n" + help_str += "When used this parameter overrides the default temporary directory " + help_str += "defined in the configuration xml file." + opt_parser.add_option("-t", + "--tmp", + action="store", + dest="tmp_dir", + metavar="DIR", + help=help_str) + help_str = "Force all products to be installed from sources \n" + help_str += "including SALOME modules.\n" + help_str += "If this option is used all the default installation modes are ignored." + opt_parser.add_option("-a", + "--all-from-sources", + action="store_true", + dest="force_sources", + default=False, + help=help_str) + help_str = "Install all SALOME binaries packages to one directory.\n" + help_str += "This option is ignored when --all-from-sources (-a) option is used." + opt_parser.add_option("-s", + "--single-directory", + action="store_true", + dest="single_dir", + default=False, + help=help_str) + help_str = "Prints version information and quits." + opt_parser.add_option("-v", + "--version", + action="store_true", + help=help_str) + help_str = "Prints this help and quits." + opt_parser.add_option("-h", + "--help", + action="store_true", + help=help_str) + (options, args) = opt_parser.parse_args() + if options.help: + # print help info and quit + print "\nSALOME Installation Wizard\n" + opt_parser.print_help() + print "" + sys.exit(0) + if options.version: + # print version info and quit + print "" + cmd = "./bin/SALOME_InstallWizard --version" + os.system(cmd) + print "" + sys.exit(0) + return [options.xmlfile, options.target_dir, options.tmp_dir, options.gui, options.force_sources, options.single_dir, options.platform] - return deps +#================================================================= +# strip : removes spaces at the beginning and at the end of the +# if it is of string type +#================================================================= +def strip(param): + """ + Removes spaces at the beginning and at the end + of the given parameter. + """ + if type(param) == types.StringType: + return param.strip() + return param +#================================================================= +# get_dependencies : extract products dependencies +#================================================================= +def get_dependencies(prods): + """ + Gets a list of installed and required products. + """ + prods_list = [] + for product in prods: + for dep in product.dependencies: + if dep and dep not in prods_list: + prods_list.append( dep ) + dep_name = dep + if product.whattodo == __BUILDSRC__: + dep_name = dep + "_src" + if dep_name not in parser.full_prods_list: + msg = "Prerequisite '%s' is required for '%s' product,\n"%(dep, product.name) + msg += "but the first one is absent in the list of products to be installed!\n" + msg += "Please check your XML file." + warning(msg) + + if product.name and product.name not in prods_list: + prods_list.append( product.name ) + + return " ".join( prods_list ) + #============================================================== -# Creates dir, returns the part of path that existed early. -# Access may be defined. +# create_dir : creates a directory with (optional) permissions, +# returns the part of path that existed before +# directory creation; exits with error if access +# is denied #============================================================== -def create_dir (directory, access = 0777): - import string, os - dirs = string.split(directory, "/") - existing = ""; dir = "" +def create_dir(directory, access = 0777): + """ + Creates a directory with (optional) permissions, + returns the part of path that existed before + directory creation; exits with error if access + is denied. + """ + dirs = directory.split("/") + existing = ""; + dir = "" root = "" - for item in dirs: - if len(item) == 0: continue - dir = dir + "/"+item + for subdir in dirs: + if len(subdir) == 0: continue + dir = "%s/%s"%(dir, subdir) if os.path.exists(dir): existing = dir else: - os.mkdir(dir, access ) - #root= existing + "/"+item - if dir == existing + "/"+item : + try: + os.mkdir(dir, access) + except: + error_exit("Can't create directory: %s.\nAccess is denied."%directory) + if dir == "%s/%s"%(existing, subdir): root = dir - #else : root = existing - return root #============================================================== -# class Product +# substituteVars : performes environment variables substistution +# the given string; if varibale is not defined +# it is substituted by the empty string #============================================================== - -class Product : - def __init__(self, theName, - theVersion = None, - theInstall = None, - theSupportred = None, - theDisable = None, - theDependencies = None, - theInstalldiskspace = None, - theTemporarydiskspace = None, - theScript = None, - thePickUpEnvironment = None): - - - self.name = theName - self.version = theVersion - self.install = theInstall - self.supported = theSupportred - self.disable = theDisable - self.dependencies = theDependencies - self.installdiskspace = theInstalldiskspace - self.temporarydiskspace = theTemporarydiskspace - self.script = theScript - self.pickupEnv = thePickUpEnvironment - -#=================================================================== -# class Config -#=================================================================== -class Config : - def __init__(self, theVersion='', theCaption='', theCopyright='', theLicense='', theOS=''): - self.version = theVersion - self.caption = theCaption - self.copyright = theCopyright - self.license = theLicense - self.os = theOS - - -#=================================================================== -# class Path -#=================================================================== -class Path : - def __init__(self, theTargetdir=".", theTmpdir="."): - self.targetdir = theTargetdir - self.tmpdir = theTmpdir - - -#=================================================================== -# class ConfigParser -#=================================================================== -class ConfigParser(xmllib.XMLParser): - def __init__(self): - xmllib.XMLParser.__init__(self) - self.products = [] - self.currentdata = [] - self.path = None - self.config = None - - def handle_data(self, data): - self.currentdata.append(data) - - def start_product(self, attrs): - aProduct = Product(attrs['name'], - attrs['version'], - attrs['install'], - attrs['supported'], - attrs['disable'], - attrs['dependancies'], - attrs['installdiskspace'], - attrs['temporarydiskspace'], - attrs['script']) - - if attrs.has_key( 'pickupenv' ): - aProduct.pickupEnv = attrs['pickupenv'] - - self.products.append(aProduct) - - def end_product(self): - pass - - def start_config(self, attrs): - self.config = Config(attrs['version'], - attrs['caption'], - attrs['copyright'], - attrs['license'], - attrs['os']) - def end_config(self): - pass - - def start_path (self, attrs): - self.path = Path(attrs['targetdir'], - attrs['tempdir']) - print self.path.tmpdir - - def end_path(self): - pass - - def getProduct(self, prod): - for product in self.products: - if product.name == prod: - return product - return None +def substituteVars(str): + """ + Performes environment variables substistution. + """ + str = os.path.expanduser(str) + str = os.path.expandvars(str) + return str #================================================================ -# get the path using file name +# get_program_path : gets program's directory path +# (and performs 'cd' command there) #================================================================ -def get_current_path(file_name): - path = "."; where = string.rfind(file_name,'/'); - if (where != -1): - path = (file_name)[: where] - os.chdir(path); - path = os.getcwd() + "/" - return path +def get_program_path(): + """ + Returns the program directory path + (and make this directory current). + """ + path = os.path.dirname(sys.argv[0]) + if path: + os.chdir(path) + return os.getcwd() #================================================================ -# checks dir existing +# check_dir : checks directory existence #================================================================ def check_dir(dir): - if (os.path.islink(dir)) : - native_dir = os.readlink(dir) - if not os.path.exists(native_dir) : - print "Bad link " + native_dir + " to directory " + native_dir + ". The last does not exist." - return 0 # problem - else : + """ + Checks directory existence. + """ + if (os.path.islink(dir)): + realpath = os.path.realpath(dir) + if not os.path.exists(realpath): + msg = "Invalid link %s.\nThe directory %s a link points to does not exist. Stopped..."%(dir,realpath) + error_exit(msg, False) + else: if not os.path.exists(dir): - print "Directory " + dir + " does not exist" - return 0 - return 1 + msg = "Directory %s does not exist. Stopped..."%dir + error_exit(msg, False) + pass #=============================================================== -# Checks the disk space. Exit from interpreter if there is no -# enough disk space. +# check_disk_space : checks the disk space; +# quits if there is no enough disk space #=============================================================== -def check_disk_space(products, script_dir, target_dir, tmp_dir): - import re, string, os +def check_disk_space(products, scripts_dir, target_dir, tmp_dir, is_force_src=False): + """ + Checks if there is enough disk space to install products. + Quits with error if there is no enough disk space. + """ install_space = 0 temporary_space = 0 - for product in products : - product.install = re.sub(r'^\s+', "", product.install) - product.install = re.sub(r'\s+$', "", product.install) - - if product.disable == "true" or product.install == "use native": - continue - spaces = string.split( product.installdiskspace,',') - prod_space = spaces[0] - if (len(spaces) == 2 ) and (product.install == "install binaries") : - prod_space = spaces[1] - install_space = install_space + string.atoi(prod_space) - temporary_space = temporary_space + string.atoi(product.temporarydiskspace) - res = os.system(scripts_dir + "checkSize.sh" + " " + target_dir + " " + str(install_space)) - if res: - print "There is no enough space to install the products." - return 0 - - res = os.system(scripts_dir + "checkSize.sh" + " " + tmp_dir + " " + str(temporary_space)) + for product in products: + prod_space = 0 + try: + spaces = product.installdiskspace.split(',') + prod_space = int( spaces[0] ) + if product.whattodo == __BINARIES__: + prod_space = int( spaces[0] ) + if product.type == __CTX__COMPONENT__: + prod_space += int( spaces[1] ) + else: + if product.type == __CTX__PREREQUISITE__: + prod_space = int( spaces[0] ) + else: + prod_space = int( spaces[2] ) + except: + pass + install_space = install_space + prod_space + pass + + res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", target_dir, install_space)) if res: - print "There is no enough space for tmp directory." - return 0 - - return 1 + msg = "There is no enough space to install the products. Stopped..." + error_exit(msg, False) + pass +#=============================================================== +# remove_dir : removes temporary directory +#=============================================================== +def remove_dir(path): + """ + Removes temporary directory. + """ + if path and os.path.exists(path): + os.system("rm -rf " + path) + pass -#================================================================ -# main -#================================================================ - -if __name__ == "__main__": - - cur_dir = get_current_path(sys.argv[0]) - - [xml_file, target_dir, tmp_dir, is_gui] = parse_parameters(sys.argv) - - # define xml file ----------------- - if (xml_file is None) : - xml_file_name = "config.xml" - if os.path.exists("/proc/version"): - data = open("/proc/version").readline() - res = re.search(r'Red\s+Hat\s+\w+(\s+)?(\d[.]\d)', data) - if res is not None: - num = re.sub("[.]", "_", (res.groups())[1]) - filename = "config_RedHat" + num+ ".xml" - if (os.path.exists(cur_dir + filename)): - xml_file_name = filename - - xml_file = cur_dir + xml_file_name - if xml_file is None or not os.path.exists(xml_file): - error_exit("No xml file is found try to run with options -f ") +#============================================================== +# has_binaries : returns True if some product is installed from +# binaries +#=============================================================== +def has_binaries(products): + """ + Returns True if some product is installed in 'binaries' mode. + """ + for product in products: + if product.whattodo == __BINARIES__: + return True + return False + +#============================================================== +# has_sources : returns True if some product is installed from +# sources +#=============================================================== +def has_sources(products): + """ + Returns True if some product is installed in 'sources' mode. + """ + for product in products: + if product.whattodo == __BUILDSRC__: + return True + return False + +#============================================================== +# get_tmp_dir : gets temporary directory name +#=============================================================== +def get_tmp_dir(dir): + """ + Gets temporary directory path. + """ + max_attempts = 100 + dir_prefix="INSTALLWORK" + range_bottom = 0; range_top = 999999 + for i in xrange(max_attempts): + tmp_dir = "%s/%s%d"%(dir, dir_prefix, random.randint(range_bottom,range_top)) + if not os.path.exists( tmp_dir ): + return tmp_dir + return "%s/%s%d"%(dir, dir_prefix, random.randint(range_bottom,range_top)) + +#============================================================== +# get_os_release : gets OS release; the OS name, version and +# architecture +# For example: +# RedHat, 8.0; Mandriva, 2006.0, 64 +#=============================================================== +def get_os_release(): + filename = "/etc/issue" + # --- + plt_name = "unknown" + plt_ver = "" + plt_arch = "" + if os.path.exists(filename): + # --- + f = open(filename) + lines = f.readlines() + f.close() + # --- + regvar = re.compile("(.*)\s+[^\s]*[R|r]elease[^\s]*\s+([\d.]*)") + regvar1 = re.compile("(.*)\s+[^\s]*[L|l][I|i][N|n][U|u][X|x][^\s]*(.*)\s+([\d.]*)\s+") + for l in lines: + res = re.search(regvar, l) + if not res: + res = re.search(regvar1, l) + if res: + plt_name = " ".join(" ".join(res.groups()[:len(res.groups())-1]).split()) + # workaround for Mandrake and other platforms + plt_name = plt_name.replace("Linux", "").replace("linux", "").replace("LINUX", "").strip() + # workaround for SuSe + plt_name = plt_name.replace("Welcome to", "").strip() + # --- + plt_name = " ".join(plt_name.split()) + plt_ver = res.group(len(res.groups())) + if re.search(r'x86_64', l): + plt_arch = "64bit" + pass + # workaround for Red Hat Enterprise + if not plt_arch: + try: + import platform + if platform.machine() == "x86_64": + plt_arch = "64bit" + pass + pass + except: + pass + pass + break + pass + pass + + return plt_name, plt_ver, plt_arch + +#============================================================== +# check_xml_file : checks XML file existence and readability +#=============================================================== +def check_xml_file(xml_file): + """ + Checks XML file existence and readability. + """ + if not os.path.isfile(xml_file): + msg = "Configuration file %s is not found!"%xml_file + error_exit(msg, False) if not os.access(xml_file, os.R_OK): - print "There is no acceess to read "+ xml_file - sys.exit(1) + msg = "There is no read access for %s file!"%xml_file + error_exit(msg, False) + pass + +#============================================================== +# get_supported_plts : gets map of supported Linux platforms and +# corresponding configuration files +#=============================================================== +def get_supported_platforms(xml_file=None): + """ + Gets map of supported Linux platforms and + corresponding configuration files. + """ + platforms_map = {} + if xml_file: + xml_file_list = [xml_file] + pass + else: + xml_file_list = filter(lambda i: i.endswith(".xml"), os.listdir(get_program_path())) + while 'config.xml' in xml_file_list: xml_file_list.remove('config.xml') + if os.path.exists(os.path.join(get_program_path(), 'config.xml')): + xml_file_list.append('config.xml') + xml_file_list = [os.path.abspath(i) for i in xml_file_list] + pass + for an_xml_file in xml_file_list: # XML files parsing + check_xml_file(an_xml_file) + parser = ConfigParser() + parser.parse(an_xml_file) + if parser.config.platforms is not None: + for plt in parser.config.platforms.split(","): + if not plt or plt in platforms_map.keys(): continue + platforms_map[strip(plt)] = an_xml_file + pass + pass + pass + return platforms_map + +#============================================================== +# Print menu with list of supported platform +# and return user choice +#=============================================================== +def select_platform(all_platforms): + platforms = all_platforms.keys() + platforms.sort() + pltname = None + while not pltname: + print "Please, select any platform from the list below." + print "--------------------------" + for idx in range(len(platforms)): + print " %2d. %s" % (idx+1, " ".join(platforms[idx].split("_"))) + print " 0. Exit" + print "--------------------------" + print "Type your choice (%d-%d) and press :" % (0, len(platforms)), + try: + idx = raw_input() + except: + sys.exit(1) + try: + idx = int(idx) + except: + warning("Invalid input!") + pass + if idx == 0: sys.exit(0) + if idx > 0 and idx <= len(platforms): + pltname = platforms[idx-1] + else: + warning("Invalid input!") + pass + return pltname, all_platforms[pltname] + +#============================================================== +# Check existence of required libraries in system and +# warn user if some ones are absent +#=============================================================== +def check_not_found_libs(filepath, optlibs): + a_file = open(filepath, 'r') + nf_mand_libs = list() + nf_opt_libs = list() + pref_opt_libs = optlibs.split(",") + for line in a_file: + line = line.strip() + if not line: + continue + line = line.split(" ")[0] + if line in nf_mand_libs or line in nf_opt_libs: + continue + is_optional = False; + for opt_lib in pref_opt_libs: + if line.lower().startswith(opt_lib.lower().strip()): + is_optional = True + break + if is_optional: + nf_opt_libs.append(line) + else: + nf_mand_libs.append(line) + pass + + msg = "=== WARNING: Some libraries are absent! ===\n" + if nf_mand_libs: + msg += "One or several MANDATORY libraries listed below are not found. SALOME may not work properly.\n\t" + msg += "\n\t".join(nf_mand_libs) + msg += "\n" + if nf_opt_libs: + msg += "One or several OPTIONAL libraries listed below are not found. This does not affect on the correct work of SALOME platform.\n\t" + msg += "\n\t".join(nf_opt_libs) + if nf_mand_libs or nf_opt_libs: + print msg + a_file.close() + pass + +#------------------------------------------------------------------# +# # +# EXECUTION STARTS HERE # +# # +#------------------------------------------------------------------# + +if __name__ == "__main__": + # parse command line + [xml_file, target_dir, tmp_dir, is_gui, is_force_src, is_single_dir, pltname] = parse_parameters() + if xml_file: xml_file = os.path.abspath(xml_file) + if target_dir: target_dir = os.path.abspath(target_dir) + if tmp_dir: tmp_dir = os.path.abspath(tmp_dir) + # get program dir + cur_dir = get_program_path() #---- GUI ---------------- + if is_gui : env = os.environ if not env.has_key("PATH") : env["PATH"] = "" if not env.has_key("LD_LIBRARY_PATH") : - env["LD_LIBRARY_PATH"]= "" + env["LD_LIBRARY_PATH"] = "" + + env["LD_LIBRARY_PATH"] = "./bin/lib:" + ".:" + env["LD_LIBRARY_PATH"] + env["PATH"] = ".:" + env["PATH"] + + cmd = "./bin/SALOME_InstallWizard" + if xml_file is not None: + cmd += " --file %s"%xml_file + if pltname is not None: + cmd += " --platform %s"%pltname + if target_dir is not None: + cmd += " --target %s"%target_dir + if tmp_dir is not None: + cmd += " --tmp %s"%tmp_dir + if is_force_src: + cmd += " --all-from-sources" + if is_single_dir: + cmd += " --single-directory" + cmd += "&" + sys.exit(os.system(cmd)) - env["LD_LIBRARY_PATH"] = ".:" + env["LD_LIBRARY_PATH"] - env["PATH"] = ".:"+ env["PATH"] + #----- TUI --------------------- + # + # define xml file to be used + # + # get current Linux platform + plt_name, plt_ver, plt_arch = get_os_release() + data = [] + for i in plt_name, plt_ver, plt_arch: + if i: data.append(i) + full_plt_name = " ".join(data) + # get all supported platforms + all_platforms = get_supported_platforms(xml_file) + if all_platforms: + if pltname: + # platform name is specified in the command line + if pltname in all_platforms: + # if specified platform is supported, choose the corresponding XML file for use + xml_file = all_platforms[pltname] + else: + # if specified platform is NOT supported, print warning message + # and prompt user to choose another platform + msg = "Specified platform is not supported: %s" % (pltname) + warning(msg) + pltname, xml_file = select_platform(all_platforms) + pass + pass + elif full_plt_name in all_platforms: + # if current platform is supported, choose the corresponding XML file for use + pltname = full_plt_name + xml_file = all_platforms[pltname] + else: + if xml_file and len(all_platforms) == 1: + # XML file is specified and contains only one platform definition + xml_file = all_platforms.values()[0] + pltname = all_platforms.keys()[0] + else: + # current Linux platform is not supported, print warning message + # and prompt user to choose platform from the list + warning("Not supported Linux platform: %s."%" ".join(data)) + pltname, xml_file = select_platform(all_platforms) + pass + pass + else: + # current Linux platform is not supported, exit + if pltname: + msg = "Not supported Linux platform: %s."%pltname + else: + msg = "Not supported Linux platform: %s."%" ".join(data) + error_exit(msg, False) + pass - sys.exit(os.system("cd " + cur_dir + "; ./bin/SALOME_InstallWizard " + xml_file +"&")) - - + # parse XML file ----------- + message("Parsing XML configuration file: %s"%xml_file) + parser = ConfigParser(is_force_src, pltname) + parser.parse(xml_file) - #----- TUI --------------------- + # source directory map + bin_dir = "" + if parser.config.platforms: + bin_dir += "/%s"%"_".join( parser.pltname.split() ) + subdir = { __BINARIES__ : "BINARIES" + bin_dir, + __BUILDSRC__ : "SOURCES", + __PREINSTALL__ : ""} - #print xml_file, target_dir, tmp_dir, is_gui - - filehandle = open(xml_file) - data = filehandle.read() - filehandle.close() - parser = ConfigParser() - parser.feed(data) - parser.close() - - # definitions : - # map - what_to_do = { "install sources":"install_source", - "install binaries":"install_binary", - "use native":"try_native"} - # define tmp dir ----------- - if tmp_dir is None: - tmp_dir = parser.path.tmpdir - root_path = "" - if not os.path.exists(tmp_dir): - print "Creating " + tmp_dir; root_path = create_dir(tmp_dir) ; - import random - tmp_dir = tmp_dir + "/INSTALLWORK" + str(random.randint(10000,100000)) - create_dir(tmp_dir,0755) - if not os.path.exists(tmp_dir): - error_exit("There is no tmp directory " + tmp_dir + ". Use -tmp key to set directory or correct xml file\n\n") + # check scripts directory ----------- + scripts_dir = "%s/%s"%(cur_dir, "config_files") + check_dir(scripts_dir) - if not os.access(tmp_dir, os.W_OK) : - str = "We have no write permissions for directory " + tmp_dir + ". Use -tmp key to set directory or correct xml file" - error_exit(str) - - # define target dir -------- + # check products archives directories ----------- + has_bin = has_binaries(parser.products) + has_src = has_sources(parser.products) + source_dir = "%s/%s"%(cur_dir, "Products") + + if has_src or has_bin: + check_dir(source_dir) + + if has_src: + check_dir("%s/%s"%(source_dir,subdir[__BUILDSRC__])) + + if has_bin: + check_dir("%s/%s"%(source_dir,subdir[__BINARIES__])) + + # check/create target dir ----------- if target_dir is None: - target_dir = parser.path.targetdir + target_dir = parser.config.targetdir + target_dir = substituteVars(target_dir) + + message("Creating target directory: " + target_dir) + create_dir(target_dir, 0755) if not os.path.exists(target_dir): - print "Creating " + target_dir; create_dir(target_dir, 0755) - if not os.path.exists(target_dir): - error_exit("There is no target directory " + target_dir + ". Use -t key to set directory or correct xml file\n\n") + error_exit("Invalid target directory: " + target_dir) if not os.access(target_dir, os.W_OK) : - str = "We have no write permissions for directory " + target_dir + ". Use -t key to set directory or correct xml file" - error_exit(str) - + error_exit("There is no write permissions for the directory: " + target_dir) - # define products dir ------------ - source_dir = cur_dir + "Products" ; - if not check_dir(source_dir): - if len(root_path) and os.path.exists(root_path): - os.system("rm -r -f "+ root_path) - sys.exit(1) - - subdir = {"install sources" : "SOURCES", - "install binaries" : "BINARIES/"+parser.config.os, - "use native": ""} - - - # define scripts dir ------------ - scripts_dir = cur_dir + "config_files/" - if not check_dir(scripts_dir): - if len(root_path) and os.path.exists(root_path): - os.system("rm -r -f "+ root_path) - sys.exit(1) - os.chdir(scripts_dir) + # check/create temporary dir ----------- + if tmp_dir is None: + tmp_dir = parser.config.tmpdir + if not tmp_dir: + tmp_dir = "/tmp" + tmp_dir = substituteVars(tmp_dir) + tmp_dir = get_tmp_dir(tmp_dir) + + message("Creating temporary directory: " + tmp_dir) + root_path = create_dir(tmp_dir, 0755) + + if not os.path.exists(tmp_dir): + error_exit("Invalid temporary directory: " + tmp_dir) - list_of_dep = create_levels(parser.products) - #list_of_dep = get_dependencies_set(parser.products) + if not os.access(tmp_dir, os.W_OK) : + error_exit("There is no write permissions for the directory: " + tmp_dir) + + # check available disk space ----------- + message("Checking available disk space") + check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir, is_force_src) - if check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir) : + # change current directory ----------- + os.chdir(scripts_dir) - # install products - for product in parser.products : + # get dependencies list ----------- + list_of_dep = get_dependencies(parser.products) + products_string = " ".join(parser.full_prods_list) - if product.disable == "true": continue + # don't remove sources and tmp files, by default ----------- + rm_src_tmp = "FALSE" - cmd = scripts_dir + product.script + " " + \ - what_to_do[product.install]+ " " + \ - tmp_dir + " " + \ - source_dir + "/" + subdir[product.install] + " " + \ - target_dir + " " + \ - '"' + list_of_dep + '"' + " " + \ - product.name + # starting ----------- + message("Starting ...") + + # install products ----------- + for product in parser.products: + # remove only prerequisites temporary files + if product.type == __CTX__PREREQUISITE__ or \ + (product.type == __CTX__COMPONENT__ and product.whattodo == __BUILDSRC__): + rm_src_tmp = "TRUE" + message("... processing %s ..."%product.name) + cmd = '%s/%s %s %s %s/%s %s "%s" %s "%s" %s/%s %s %s/%s' % ( + scripts_dir, product.script, + product.whattodo, + tmp_dir, + source_dir, subdir[product.whattodo], + target_dir, + products_string, + product.name, + products_string, + source_dir, subdir[__BUILDSRC__], + rm_src_tmp, + source_dir, subdir[__BINARIES__] + ) + # install all modules with GUI + if product.woguiinst is not None and product.woguiinst != "": + cmd += ' TRUE' + # use single directory or not + if product.whattodo == __BINARIES__ and product.type == __CTX__COMPONENT__ and is_single_dir: + cmd += ' TRUE' + res = os.system(cmd) + rm_src_tmp = "FALSE" + pass + # pickup environment ----------- + message("Creating environment files") + for product in parser.products : + if check_bool(product.pickupEnv): + cmd = '%s/%s pickup_env %s %s/%s %s "%s" %s "%s" %s/%s %s %s/%s' % ( + scripts_dir, product.script, + tmp_dir, + source_dir, subdir[product.whattodo], + target_dir, + products_string, + product.name, + products_string, + source_dir, subdir[__BUILDSRC__], + rm_src_tmp, + source_dir, subdir[__BINARIES__] + ) + # install all modules with GUI + if product.woguiinst is not None and product.woguiinst != "": + cmd += ' TRUE' + # use single directory or not + if product.whattodo == __BINARIES__ and product.type == __CTX__COMPONENT__ and is_single_dir: + cmd += ' TRUE' res = os.system(cmd) - if res : break; - - # pickup environment - for product in parser.products : - - if product.disable == "true": continue - - if product.pickupEnv == "true": - cmd = scripts_dir + product.script + " " + \ - "pickup_env " + \ - tmp_dir + " " + \ - source_dir + "/" + subdir[product.install] + " " + \ - target_dir + " " + \ - '"' + list_of_dep + '"' + " " + \ - product.name - - res = os.system(cmd) - - if len(root_path) and os.path.exists(root_path): - os.system("rm -r -f "+ root_path) + pass + pass + + if not is_force_src: + if is_single_dir: + # modify *.la files, if --single-directory option was pointed ----------- + message("Modifying of *.la files of SALOME modules...") + cmd = '%s/modifyLaFiles.sh modify_la_files %s' % (scripts_dir, target_dir) + res = os.system(cmd) + else: + # check that all required libraries are in system + message("Check existence of Fortran and other required libraries...") + cmd = '%s/checkFortran.sh find_libraries %s > %s/not_found_libs.txt' % (scripts_dir, target_dir, tmp_dir) + if os.system(cmd): + check_not_found_libs("%s/not_found_libs.txt" % (tmp_dir), parser.config.optlibs) + + # clean temporary directory ----------- + message("Cleaning temporary directory") + clean_all() + + # finishing ----------- + message("Finished!") + pass