Salome HOME
SALOME 7.3.0 preparation
[tools/install.git] / runInstall
index 2166b2ee44db6cf6408c399e225d4a2fe7c0b34d..b7f7f210945bab4d94f077e9603471fd158294ca 100755 (executable)
@@ -2,29 +2,43 @@
 
 """
 Installation Wizard launching script.
 
 """
 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-2013 CEA
+
 """
 
 """
 
-__version__ = "1.0.1"
+__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 --- #
 
 # --- avoid "deprecation" warnings --- #
-import warnings
 warnings.filterwarnings("ignore", "", DeprecationWarning)
 
 warnings.filterwarnings("ignore", "", DeprecationWarning)
 
-# --- imports --- #
-import xmllib
-import sys, os, string, re
-import types
-import random
-
 # --- global variables --- #
 opt_parser = None
 root_path  = None
 
 # --- global variables --- #
 opt_parser = None
 root_path  = None
 
-# --- XML tags definition --- #
-__TAG__SOURCES__    = "install sources"
-__TAG__BINARIES__   = "install binaries"
-__TAG__NATIVE__     = "use native"
-__TAG__PREINSTALL__ = "not install"
+# --- actions definition --- #
+__BINARIES__   = "install_binary"
+__BUILDSRC__   = "install_source_and_build"
+__PREINSTALL__ = "try_preinstalled"
+
+# --- product type definition --- #
+__CTX__COMPONENT__    = "component"
+__CTX__PREREQUISITE__ = "prerequisite"
 
 #------------------------------------------------------------------#
 #                                                                  #
 
 #------------------------------------------------------------------#
 #                                                                  #
@@ -147,7 +161,7 @@ class ArgOption:
             msg  = "invalid type: %s : should be 'bool' or None" % self.type
             raise OptError(msg, self)
         # default
             msg  = "invalid type: %s : should be 'bool' or None" % self.type
             raise OptError(msg, self)
         # default
-        if 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)
             try:
                 if self.type == "string": self.default = str(self.default)
                 if self.type == "int":    self.default = int(self.default)
@@ -211,7 +225,7 @@ class ArgParser:
         if not args: args = sys.argv[1:]
         values = Values()
         for o in self.options:
         if not args: args = sys.argv[1:]
         values = Values()
         for o in self.options:
-            if o.default:
+            if o.default is not None:
                 setattr(values, o.dest, o.default)
             elif not hasattr(values,o.dest):
                 setattr(values, o.dest, None)
                 setattr(values, o.dest, o.default)
             elif not hasattr(values,o.dest):
                 setattr(values, o.dest, None)
@@ -349,43 +363,36 @@ class ArgParser:
 #------------------------------------------------------------------#
 
 #===================================================================
 #------------------------------------------------------------------#
 
 #===================================================================
-# class Config : general configuration options : version, OS, etc...
+# class Config : general configuration options : version, target and
+#                temporary directories, etc...
 #===================================================================
 class Config :
     """
     General configuration file options:
     - Install Wizard window caption
     - SALOME platform version
 #===================================================================
 class Config :
     """
     General configuration file options:
     - Install Wizard window caption
     - SALOME platform version
-    - Copyright and libcense info
-    - Target Linux OS 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,
     """
     def __init__(self,
                  theVersion   = None,
                  theCaption   = None,
                  theCopyright = None,
                  theLicense   = None,
-                 theOS        = 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.version   = strip(theVersion)
         self.caption   = strip(theCaption)
         self.copyright = strip(theCopyright)
         self.license   = strip(theLicense)
-        self.os        = strip(theOS)
-
-#===================================================================
-# class Path : default target, temporary directories options
-#===================================================================
-class Path :
-    """
-    Path options:
-    - default target directory
-    - default temporary directory
-    """
-    def __init__(self,
-                 theTargetdir = None,
-                 theTmpdir    = None):
+        self.platforms = strip(thePlatforms)
         self.targetdir = strip(theTargetdir)
         self.tmpdir    = strip(theTmpdir)
         self.targetdir = strip(theTargetdir)
         self.tmpdir    = strip(theTmpdir)
-        
+        self.optlibs   = strip(theOptLibs)
+
 #==============================================================
 # class Product : pre-requisite product options
 #==============================================================
 #==============================================================
 # class Product : pre-requisite product options
 #==============================================================
@@ -393,7 +400,7 @@ class Product :
     """
     Product options:
     - name, version
     """
     Product options:
     - name, version
-    - supported installation modes and the default one
+    - target Linux OS version
     - dependencies
     - required disk space
     - installation script
     - dependencies
     - required disk space
     - installation script
@@ -401,76 +408,154 @@ class Product :
     """
     def __init__(self,
                  theName,
     """
     def __init__(self,
                  theName,
+                 theType               = None,
+                 theOS                 = None,
                  theVersion            = None,
                  theVersion            = None,
-                 theInstall            = None,
-                 theSupportred         = None,
                  theDependencies       = None,
                  theDependencies       = None,
+                 theWoGuiInstallation  = None,
                  theInstalldiskspace   = None,
                  theInstalldiskspace   = None,
-                 theTemporarydiskspace = None,
                  theScript             = None,
                  thePickUpEnvironment  = None):
         self.name               = strip(theName)
                  theScript             = None,
                  thePickUpEnvironment  = None):
         self.name               = strip(theName)
+        self.type               = strip(theType)
+        self.os                 = strip(theOS)
         self.version            = strip(theVersion)
         self.version            = strip(theVersion)
-        self.install            = strip(theInstall)
-        self.supported          = strip(theSupportred)
         self.dependencies       = strip(theDependencies)
         self.dependencies       = strip(theDependencies)
+        self.woguiinst          = strip(theWoGuiInstallation)
         self.installdiskspace   = strip(theInstalldiskspace)
         self.installdiskspace   = strip(theInstalldiskspace)
-        self.temporarydiskspace = strip(theTemporarydiskspace)
         self.script             = strip(theScript)
         self.pickupEnv          = strip(thePickUpEnvironment)
         self.script             = strip(theScript)
         self.pickupEnv          = strip(thePickUpEnvironment)
-
+        self.whattodo           = __BINARIES__
+        
+    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 files parser implementation
 #===================================================================
-class ConfigParser(xmllib.XMLParser):
+class ConfigParser:
     """
     XML configuration files parser
     """
     """
     XML configuration files parser
     """
-    def __init__(self):
-        xmllib.XMLParser.__init__(self)
+    def __init__(self, is_force_src=False, pltname=None):
+        self.docElem = None
         self.products = []
         self.products = []
-        self.currentdata = []
-        self.path = None
+        self.full_prods_list = []
         self.config = None
         self.config = None
+        self.is_force_src = is_force_src
+        self.pltname = pltname
+        pass
         
         
-    def handle_data(self, data):
-        self.currentdata.append(data)
+    def parse_config(self):
+        # Parse 'config' part of the XML file
+        configElem = self.docElem.getElementsByTagName('config')[0]
         
         
-    def start_product(self, attrs):
-        if not attrs.get('name', '').strip():         return
-        if check_bool(attrs.get('disable', 'false')): return
-        aProduct = Product(attrs.get('name'),
-                           attrs.get('version',            None),
-                           attrs.get('install',            None),
-                           attrs.get('supported',          None),
-                           attrs.get('dependancies',       None),
-                           attrs.get('installdiskspace',   None),
-                           attrs.get('temporarydiskspace', None),
-                           attrs.get('script',             None),
-                           attrs.get('pickupenv',          None))
-        self.products.append(aProduct)
-        pass
-
-    def end_product(self):
-        pass
-
-    def start_config(self, attrs):
-        self.config = Config(attrs.get('version',   None),
-                             attrs.get('caption',   None),
-                             attrs.get('copyright', None),
-                             attrs.get('license',   None),
-                             attrs.get('os',        None))
+        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
     
         pass
     
-    def end_config(self):
+    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
+    
+    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
 
         pass
 
-    def start_path (self, attrs):
-        self.path = Path(attrs.get('targetdir', None),
-                         attrs.get('tempdir',   None))
-        pass
-        
-    def end_path(self):
+    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 getProduct(self, prod):
         pass
 
     def getProduct(self, prod):
@@ -479,6 +564,7 @@ class ConfigParser(xmllib.XMLParser):
                 return product
         return None
 
                 return product
         return None
 
+
 #------------------------------------------------------------------#
 #                                                                  #
 #                         SERVICE FUNCTIONS                        #
 #------------------------------------------------------------------#
 #                                                                  #
 #                         SERVICE FUNCTIONS                        #
@@ -600,15 +686,22 @@ def parse_parameters():
     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. "
     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. "
-    help_str += "If program fails to define target Linux platform or the corresponding "
-    help_str += "xml file is not provided with the Installation Wizard, then default "
-    help_str += "config.xml file is used."
     opt_parser.add_option("-f",
                           "--file",
                           action="store",
                           dest="xmlfile",
                           metavar="FILE",
                           help=help_str)
     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."
     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."
@@ -627,6 +720,23 @@ def parse_parameters():
                           dest="tmp_dir",
                           metavar="DIR",
                           help=help_str)
                           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",
     help_str  = "Prints version information and quits."
     opt_parser.add_option("-v",
                           "--version",
@@ -640,7 +750,7 @@ def parse_parameters():
     (options, args) = opt_parser.parse_args()
     if options.help:
         # print help info and quit
     (options, args) = opt_parser.parse_args()
     if options.help:
         # print help info and quit
-        print "\nSALOME Installation Wizard\n"
+        print "\nSALOME Installation Wizard (running on %s)\n" % get_os_name()
         opt_parser.print_help()
         print ""
         sys.exit(0)
         opt_parser.print_help()
         print ""
         sys.exit(0)
@@ -651,7 +761,7 @@ def parse_parameters():
         os.system(cmd)
         print ""
         sys.exit(0)
         os.system(cmd)
         print ""
         sys.exit(0)
-    return [options.xmlfile, options.target_dir, options.tmp_dir, options.gui]
+    return [options.xmlfile, options.target_dir, options.tmp_dir, options.gui, options.force_sources, options.single_dir, options.platform]
 
 #=================================================================
 # strip : removes spaces at the beginning and at the end of the 
 
 #=================================================================
 # strip : removes spaces at the beginning and at the end of the 
@@ -671,19 +781,26 @@ def strip(param):
 #=================================================================
 def get_dependencies(prods):
     """
 #=================================================================
 def get_dependencies(prods):
     """
-    Gets full list of pre-requisite products.
+    Gets a list of installed and required products.
     """
     """
-    list = []
+    prods_list = []
     for product in prods:
     for product in prods:
-        deps = product.dependencies.split(",")
-        for dep in deps:
-            if dep and not dep in list:
-                list.append( dep )
-                
-        if product and not product in list:
-            list.append( product.name )
+        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( list )
+    return " ".join( prods_list )
 
 #==============================================================
 # create_dir : creates a directory with (optional) permissions,
 
 #==============================================================
 # create_dir : creates a directory with (optional) permissions,
@@ -698,7 +815,7 @@ def create_dir(directory, access = 0777):
     directory creation; exits with error if access
     is denied.
     """
     directory creation; exits with error if access
     is denied.
     """
-    dirs = string.split(directory, "/")
+    dirs = directory.split("/")
     existing = "";
     dir = ""
     root = ""
     existing = "";
     dir = ""
     root = ""
@@ -765,7 +882,7 @@ def check_dir(dir):
 # check_disk_space : checks the disk space;
 #                    quits 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, scripts_dir, target_dir, tmp_dir):
+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.
     """
     Checks if there is enough disk space to install products.
     Quits with error if there is no enough disk space.
@@ -773,25 +890,28 @@ def check_disk_space(products, scripts_dir, target_dir, tmp_dir):
     install_space = 0
     temporary_space = 0
     for product in products:
     install_space = 0
     temporary_space = 0
     for product in products:
-        if product.install in [__TAG__NATIVE__, __TAG__PREINSTALL__]:
-            continue
-        spaces = string.split(product.installdiskspace, ',')
-        prod_space = spaces[0]
-        if (len(spaces) > 1 ) and (product.install == __TAG__SOURCES__):
-            prod_space = spaces[1]
-        install_space = install_space + string.atoi(prod_space)
-        if product.install == __TAG__SOURCES__:
-            temporary_space = max(temporary_space, string.atoi(product.temporarydiskspace))
+        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:
         msg = "There is no enough space to install the products. Stopped..."
         error_exit(msg, False)
 
     res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", target_dir, install_space))
     if res:
         msg = "There is no enough space to install the products. Stopped..."
         error_exit(msg, False)
-    
-    res = os.system("%s/%s %s %d"%(scripts_dir, "checkSize.sh", tmp_dir, temporary_space))
-    if res:
-        msg = "There is no enough space for temporary directory. Stopped..."
-        error_exit(msg, False)
     pass
  
 #===============================================================
     pass
  
 #===============================================================
@@ -814,7 +934,7 @@ def has_binaries(products):
     Returns True if some product is installed in 'binaries' mode.
     """
     for product in products:
     Returns True if some product is installed in 'binaries' mode.
     """
     for product in products:
-        if product.install == __TAG__BINARIES__:
+        if product.whattodo == __BINARIES__:
             return True
     return False
 
             return True
     return False
 
@@ -827,7 +947,7 @@ def has_sources(products):
     Returns True if some product is installed in 'sources' mode.
     """
     for product in products:
     Returns True if some product is installed in 'sources' mode.
     """
     for product in products:
-        if product.install == __TAG__SOURCES__:
+        if product.whattodo == __BUILDSRC__:
             return True
     return False
 
             return True
     return False
 
@@ -846,63 +966,211 @@ def get_tmp_dir(dir):
         if not os.path.exists( tmp_dir ):
             return tmp_dir
     return "%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+")
+        regvar2 = re.compile("([A-Za-z]+)\s+([0-9.]+)\s+.*")
+        for l in lines:
+            res = re.search(regvar, l)
+            if not res:
+                res = re.search(regvar1, l)
+            if not res:
+                res = re.search(regvar2, 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
+
+#==============================================================
+# get_os_name : gets qualified OS name
+#               For example:
+#               Mandriva 2010.0 64bit
+#===============================================================
+def get_os_name():
+    plt_name, plt_ver, plt_arch = get_os_release()
+    data = []
+    for i in plt_name, plt_ver, plt_arch:
+        if i: data.append(i)
+    return " ".join(data)
+
+#==============================================================
+# 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):
+        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 <Enter>:" % (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                         #
 #                                                                  #
 #------------------------------------------------------------------#
 #------------------------------------------------------------------#
 #                                                                  #
 #                    EXECUTION STARTS HERE                         #
 #                                                                  #
 #------------------------------------------------------------------#
-    
+
 if __name__ == "__main__":
     # get program dir
     cur_dir = get_program_path()
     # parse command line
 if __name__ == "__main__":
     # get program dir
     cur_dir = get_program_path()
     # parse command line
-    [xml_file, target_dir, tmp_dir, is_gui] = parse_parameters()
-
-    # define xml file to be used
-    if (xml_file is None):
-        plt_name = ""
-        plt_ver  = ""
-        xml_file_name = "config.xml"
-        if os.path.exists("/etc/redhat-release"):
-            # - Red Hat Linux 8.0
-            # - Red Hat Linux 9
-            # - Mandrake Linux 10.1
-            # - Scientific Linux 3.0.5
-           # - Mandriva 2006.0
-            data = open("/etc/redhat-release").readline()
-           res = re.search(r'(.*)[L|l]inux.*release\s+([\d.]*)', data)
-           if res:
-                plt_name = "".join(res.group(1).split())
-                plt_ver  = res.group(2)
-        elif os.path.exists("/etc/debian_version"):
-            # - Debian 3.1
-            plt_name = "Debian"
-            plt_ver = open("/etc/debian_version").readline().strip()
-        elif os.path.exists("/etc/mandriva-release"):
-            # - Mandriva 2006 (an additional check if above check fails)
-            data = open("/etc/mandriva-release").readline()
-           res = re.search(r'(.*)[L|l]inux.*release\s+([\d.]*)', data)
-           if res:
-                plt_name = "".join(res.group(1).split())
-                plt_ver  = res.group(2)
-        _xml_file_name = "config_%s_%s.xml"%(plt_name, plt_ver)
-        if plt_name and plt_ver and os.path.exists("%s/%s"%(cur_dir, _xml_file_name)):
-            xml_file_name = _xml_file_name
-        else:
-            msg  = "Not supported Linux platform!\n"
-            msg += "Trying to use default configuration file!"
-            warning(msg)
-
-        xml_file = "%s/%s"%(cur_dir, xml_file_name)
-
-    if not xml_file or not os.path.exists(xml_file):
-        msg = "Configuration file %s is not found!"%xml_file
-        error_exit(msg)
-
-    if not os.access(xml_file, os.R_OK):
-        msg = "There is no read access for %s file!"%xml_file
-        error_exit(msg)
+    [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)
 
     #---- GUI ----------------
 
 
     #---- GUI ----------------
 
@@ -913,41 +1181,88 @@ if __name__ == "__main__":
         if not env.has_key("LD_LIBRARY_PATH") :
             env["LD_LIBRARY_PATH"] = ""
 
         if not env.has_key("LD_LIBRARY_PATH") :
             env["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"]
 
         env["PATH"] = ".:" + env["PATH"]
 
-        cmd = "./bin/SALOME_InstallWizard --file %s"%xml_file
+        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 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))
 
     #-----  TUI ---------------------
         cmd += "&"
         sys.exit(os.system(cmd))
 
     #-----  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
 
     # parse XML file -----------
     message("Parsing XML configuration file: %s"%xml_file)
 
     # parse XML file -----------
     message("Parsing XML configuration file: %s"%xml_file)
-    filehandle = open(xml_file)
-    data = filehandle.read()
-    filehandle.close()
-    parser = ConfigParser()
-    parser.feed(data)
-    parser.close()
-
-    # actions map
-    what_to_do = { __TAG__SOURCES__    : "install_source",
-                   __TAG__BINARIES__   : "install_binary",
-                   __TAG__NATIVE__     : "try_native",
-                   __TAG__PREINSTALL__ : "try_preinstalled"}
+    parser = ConfigParser(is_force_src, pltname)
+    parser.parse(xml_file)
+
     # source directory map
     bin_dir = ""
     # source directory map
     bin_dir = ""
-    if parser.config.os:
-        bin_dir += "/%s"%parser.config.os
-    subdir = { __TAG__SOURCES__    : "SOURCES",
-               __TAG__BINARIES__   : "BINARIES" + bin_dir,
-               __TAG__NATIVE__     : "",
-               __TAG__PREINSTALL__ : ""}
+    if parser.config.platforms:
+        bin_dir += "/%s"%"_".join( parser.pltname.split() )
+    subdir = { __BINARIES__   : "BINARIES" + bin_dir,
+               __BUILDSRC__   : "SOURCES",
+               __PREINSTALL__ : ""}
 
     # check scripts directory -----------
     scripts_dir = "%s/%s"%(cur_dir, "config_files")
 
     # check scripts directory -----------
     scripts_dir = "%s/%s"%(cur_dir, "config_files")
@@ -962,14 +1277,14 @@ if __name__ == "__main__":
         check_dir(source_dir)
 
     if has_src:
         check_dir(source_dir)
 
     if has_src:
-        check_dir("%s/%s"%(source_dir,subdir[__TAG__SOURCES__]))
+        check_dir("%s/%s"%(source_dir,subdir[__BUILDSRC__]))
 
     if has_bin:
 
     if has_bin:
-        check_dir("%s/%s"%(source_dir,subdir[__TAG__BINARIES__]))
+        check_dir("%s/%s"%(source_dir,subdir[__BINARIES__]))
 
     # check/create target dir -----------
     if target_dir is None:
 
     # 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)
     target_dir = substituteVars(target_dir)
 
     message("Creating target directory: " + target_dir)
@@ -983,7 +1298,7 @@ if __name__ == "__main__":
 
     # check/create temporary dir -----------
     if tmp_dir is None:
 
     # check/create temporary dir -----------
     if tmp_dir is None:
-        tmp_dir = parser.path.tmpdir
+        tmp_dir = parser.config.tmpdir
     if not tmp_dir:
         tmp_dir = "/tmp"
     tmp_dir = substituteVars(tmp_dir)
     if not tmp_dir:
         tmp_dir = "/tmp"
     tmp_dir = substituteVars(tmp_dir)
@@ -1000,44 +1315,89 @@ if __name__ == "__main__":
         
     # check available disk space -----------
     message("Checking available disk space")
         
     # check available disk space -----------
     message("Checking available disk space")
-    check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir)
+    check_disk_space(parser.products, scripts_dir, target_dir, tmp_dir, is_force_src)
 
     # change current directory -----------
     os.chdir(scripts_dir)
 
     # get dependencies list -----------
     list_of_dep = get_dependencies(parser.products)
 
     # change current directory -----------
     os.chdir(scripts_dir)
 
     # get dependencies list -----------
     list_of_dep = get_dependencies(parser.products)
+    products_string = " ".join(parser.full_prods_list)
+
+    # don't remove sources and tmp files, by default -----------
+    rm_src_tmp = "FALSE"
 
     # starting -----------
     message("Starting ...")
     
     # install products -----------
     for product in parser.products:
 
     # 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)
         message("... processing %s ..."%product.name)
-        cmd = '%s/%s %s %s %s/%s %s "%s" %s'%(scripts_dir,
-                                              product.script,
-                                              what_to_do[product.install],
-                                              tmp_dir,
-                                              source_dir,
-                                              subdir[product.install],
-                                              target_dir,
-                                              list_of_dep,
-                                              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)
         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):
 
     # 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'%(scripts_dir,
-                                                          product.script,
-                                                          tmp_dir,
-                                                          source_dir,
-                                                          subdir[product.install],
-                                                          target_dir,
-                                                          list_of_dep,
-                                                          product.name)
+            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)
+            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)
             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 temporary directory -----------
     message("Cleaning temporary directory")