Salome HOME
Merge branch 'ng780475/scs13189_windows'
[tools/sat.git] / src / environment.py
index 2198e2771664af58a85d6cf6b997961fcdedc36b..20a5c1eb95dc0b4f6a58873ffa657305a57909d0 100644 (file)
@@ -25,6 +25,7 @@ import src
 import src.debug as DBG
 import pprint as PP
 
+
 class Environ:
     """\
     Class to manage the environment context
@@ -65,12 +66,18 @@ class Environ:
 
     def append_value(self, key, value, sep=os.pathsep):
         """\
-        append value to key using sep
-        
+        append value to key using sep,
+        if value contains ":" or ";" then raise error
+
         :param key str: the environment variable to append
         :param value str: the value to append to key
         :param sep str: the separator string
         """
+        # check that value so no contain the system separator
+        separator=os.pathsep
+        if separator in value:
+            raise Exception("Environ append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator))
+
         # check if the key is already in the environment
         if key in self.environ:
             value_list = self.environ[key].split(sep)
@@ -99,12 +106,19 @@ class Environ:
 
     def prepend_value(self, key, value, sep=os.pathsep):
         """\
-        prepend value to key using sep
+        prepend value to key using sep,
+        if value contains ":" or ";" then raise error
         
         :param key str: the environment variable to prepend
         :param value str: the value to prepend to key
         :param sep str: the separator string
         """
+        # check that value so no contain the system separator
+        separator=os.pathsep
+        if separator in value:
+            raise Exception("Environ append key '%s' value '%s' contains forbidden character '%s'" % (key, value, separator))
+
+        # check if the key is already in the environment
         if key in self.environ:
             value_list = self.environ[key].split(sep)
             if not value in value_list:
@@ -124,7 +138,7 @@ class Environ:
         :param sep str: the separator string
         """
         if isinstance(value, list):
-            for v in value:
+            for v in reversed(value): # prepend list, first item at last to stay first
                 self.prepend_value(key, v, sep)
         else:
             self.prepend_value(key, value, sep)
@@ -157,6 +171,15 @@ class Environ:
         else:
             return ""
 
+    def get_value(self, key):
+        """\
+        Get the value of the environment variable "key"
+        This method is added for API compatibility with FileEnviron class
+        
+        :param key str: the environment variable
+        """
+        return self.get(key)
+
     def command_value(self, key, command):
         """\
         Get the value given by the system command "command" 
@@ -199,6 +222,7 @@ class SalomeEnviron:
         self.for_package = for_package
         self.enable_simple_env_script = enable_simple_env_script
         self.silent = False
+        self.has_python = False
 
     def __repr__(self):
         """easy almost exhaustive quick resume for debug print"""
@@ -245,6 +269,18 @@ class SalomeEnviron:
         """
         return self.environ.get(key)
 
+    def get_value(self, key):
+        """\
+        Get the real value of the environment variable "key"
+        This method is added for API compatibility with FileEnviron class
+        
+        :param key str: the environment variable
+        """
+        if key in self.environ:
+            return self.environ[key]
+        else:
+            return ""
+
     def set(self, key, value):
         """\
         Set the environment variable "key" to value "value"
@@ -309,7 +345,8 @@ class SalomeEnviron:
         """
         if 'finish' in dir(self.environ):
             self.environ.add_line(1)
-            self.environ.add_comment("clean all the path")
+            # what for ?
+            # self.environ.add_comment("clean all the path")
             self.environ.finish(required)
 
     def set_python_libdirs(self):
@@ -324,6 +361,7 @@ class SalomeEnviron:
           
         self.python_lib0 = self.get('PYTHON_LIBDIR0')
         self.python_lib1 = self.get('PYTHON_LIBDIR1')
+        self.has_python = True
 
     def get_names(self, lProducts):
         """\
@@ -356,13 +394,19 @@ class SalomeEnviron:
         :param logger Logger: The logger instance to display messages
         """
         
-        # add variable PRODUCT_ROOT_DIR as $workdir in APPLICATION.environ section if not present
-        try: 
-          tmp = self.cfg.APPLICATION.environ.PRODUCT_ROOT_DIR
-        except:
-          self.cfg.APPLICATION.environ.PRODUCT_ROOT_DIR = src.pyconf.Reference(self.cfg, src.pyconf.DOLLAR, "workdir")
-          DBG.write("set_application_env add default Config.APPLICATION.environ.PRODUCT_ROOT_DIR", self.cfg.APPLICATION.environ)
-          
+        if self.for_package:
+           self.set("PRODUCT_ROOT_DIR", "out_dir_Path")
+        else:
+           self.cfg.APPLICATION.environ.PRODUCT_ROOT_DIR = src.pyconf.Reference(self.cfg, src.pyconf.DOLLAR, "workdir")
+
+        # these sensitive variables are reset to avoid bad environment interactions
+        self.add_line(1)
+        self.add_comment("reset these sensitive variables to avoid bad environment interactions")
+        self.add_comment("comment these to lines if you wish a different behaviour")
+        self.set("LD_LIBRARY_PATH", "")
+        self.set("PYTHONPATH", "")
+        self.add_line(1)
+
         # Set the variables defined in the "environ" section
         if 'environ' in self.cfg.APPLICATION:
             # we write PRODUCT environment it in order to conform to 
@@ -375,15 +419,6 @@ class SalomeEnviron:
                 self.load_cfg_environment(self.cfg.APPLICATION.environ.launch)
             self.add_line(1)
 
-        # If there is an "environ_script" section, load the scripts
-        if 'environ_script' in self.cfg.APPLICATION:
-            for pscript in self.cfg.APPLICATION.environ_script:
-                self.add_comment("script %s" % pscript)
-                sname = pscript.replace(" ", "_")
-                self.run_env_script("APPLICATION_%s" % sname,
-                                self.cfg.APPLICATION.environ_script[pscript],
-                                logger)
-                self.add_line(1)       
 
     def set_salome_minimal_product_env(self, product_info, logger):
         """\
@@ -439,16 +474,21 @@ class SalomeEnviron:
                 lib_path = os.path.join(envcompo_root_dir, 'lib', 'salome')
                 l_binpath_libpath.append( (bin_path, lib_path) )
 
+
         if src.get_property_in_product_cfg(pi, "fhs"):
             lib_path = os.path.join(env_root_dir, 'lib')
-            pylib1_path = os.path.join(env_root_dir, self.python_lib0)
-            pylib2_path = os.path.join(env_root_dir, self.python_lib1)
             bin_path = os.path.join(env_root_dir, 'bin')
+            if self.has_python:
+            # if the application doesn't include python, we don't need these two lines
+                pylib1_path = os.path.join(env_root_dir, self.python_lib0)
+                pylib2_path = os.path.join(env_root_dir, self.python_lib1)
         else:
             lib_path = os.path.join(env_root_dir, 'lib', 'salome')
-            pylib1_path = os.path.join(env_root_dir, self.python_lib0, 'salome')
-            pylib2_path = os.path.join(env_root_dir, self.python_lib1, 'salome')
             bin_path = os.path.join(env_root_dir, 'bin', 'salome')
+            if self.has_python:
+            # if the application doesn't include python, we don't need these two lines
+                pylib1_path = os.path.join(env_root_dir, self.python_lib0, 'salome')
+                pylib2_path = os.path.join(env_root_dir, self.python_lib1, 'salome')
 
         # Construct the paths to prepend to PATH and LD_LIBRARY_PATH and 
         # PYTHONPATH
@@ -462,8 +502,12 @@ class SalomeEnviron:
                 else :
                     self.prepend('LD_LIBRARY_PATH', lib_path)
 
-            l = [ bin_path, lib_path, pylib1_path, pylib2_path ]
-            self.prepend('PYTHONPATH', l)
+            l = [ bin_path, lib_path ]
+            if not src.product.product_is_wheel(pi):
+                if self.has_python:
+                    l.append(pylib1_path)
+                    l.append(pylib2_path)
+                self.prepend('PYTHONPATH', l)
 
     def set_cpp_env(self, product_info):
         """\
@@ -489,10 +533,10 @@ class SalomeEnviron:
                 else :
                     self.prepend('LD_LIBRARY_PATH', lib_path)
 
-            l = [ bin_path, lib_path,
-                  os.path.join(env_root_dir, self.python_lib0),
-                  os.path.join(env_root_dir, self.python_lib1)
-                ]
+            l = [ bin_path, lib_path ]
+            if self.has_python:
+                l.append(os.path.join(env_root_dir, self.python_lib0))
+                l.append(os.path.join(env_root_dir, self.python_lib1))
             self.prepend('PYTHONPATH', l)
 
     def load_cfg_environment(self, cfg_env):
@@ -548,6 +592,25 @@ class SalomeEnviron:
         # Get the informations corresponding to the product
         pi = src.product.get_product_config(self.cfg, product)
         
+        # skip compile time products at run time 
+        if not self.forBuild:
+            if src.product.product_is_compile_time(pi):
+                return
+
+        # skip mesa products (if any) at run time, 
+        # unless use_mesa property was activated
+        if not self.forBuild:
+            if not ("APPLICATION" in self.cfg  and
+                    "properties" in self.cfg.APPLICATION  and
+                    "use_mesa" in self.cfg.APPLICATION.properties  and
+                    self.cfg.APPLICATION.properties.use_mesa == "yes") :
+                if ("properties" in pi and
+                    "is_mesa" in pi.properties  and
+                    pi.properties.is_mesa == "yes") :
+                    logger.write(_("Skip mesa product %s\n") % pi.name, 4)
+                    return
+               
+        
         if self.for_package:
             pi.install_dir = os.path.join("out_dir_Path",
                                           self.for_package,
@@ -571,6 +634,12 @@ class SalomeEnviron:
             self.set_salome_minimal_product_env(pi, logger)
             self.set_salome_generic_product_env(pi)
         
+        # use variable LICENCE_FILE to communicate the licence file name to the environment script
+        licence_file_name = src.product.product_has_licence(pi, self.cfg.PATHS.LICENCEPATH)
+        if licence_file_name:
+            logger.write("licence file found for product %s : %s\n" % (pi.name, licence_file_name), 5) 
+            self.set("LICENCE_FILE", licence_file_name)
+
         if src.product.product_is_cpp(pi):
             # set a specific environment for cpp modules
             self.set_salome_minimal_product_env(pi, logger)
@@ -584,7 +653,7 @@ class SalomeEnviron:
                     source_dir_save = pi.source_dir
                     name_save = pi.name
                     pi.install_dir = os.path.join(self.cfg.APPLICATION.workdir,
-                                                  "INSTALL",
+                                                  config.INTERNAL.config.install_dir,
                                                   pi.component_name)
                     if self.for_package:
                         pi.install_dir = os.path.join("out_dir_Path",
@@ -639,10 +708,22 @@ class SalomeEnviron:
             pyproduct = imp.load_source(product_info.name + "_env_script",
                                         env_script)
             if not native:
-                pyproduct.set_env(self,
-                                  product_info.install_dir,
-                                  product_info.version)
+                if self.forBuild and "set_env_build" in dir(pyproduct):
+                    pyproduct.set_env_build(self,
+                                            product_info.install_dir,
+                                            product_info.version)
+                elif (not self.forBuild) and "set_env_launch" in dir(pyproduct):
+                    pyproduct.set_env_launch(self,
+                                            product_info.install_dir,
+                                            product_info.version)
+                else:
+                    # at least this one is mandatory,
+                    # if set_env_build and set_env_build are not defined
+                    pyproduct.set_env(self,
+                                      product_info.install_dir,
+                                      product_info.version)
             else:
+                # not mandatory, if set_nativ_env not defined, we do nothing
                 if "set_nativ_env" in dir(pyproduct):
                     pyproduct.set_nativ_env(self)
         except:
@@ -719,13 +800,18 @@ class SalomeEnviron:
         """
         DBG.write("set_full_environ for", env_info)
         # DBG.write("set_full_environ config", self.cfg.APPLICATION.environ, True)
+
         # set product environ
         self.set_application_env(logger)
 
-        self.set_python_libdirs()
+        if "Python" in env_info:
+            self.set_a_product("Python", logger)
+            self.set_python_libdirs()
 
         # set products
         for product in env_info:
+            if product == "Python":
+                continue
             self.set_a_product(product, logger)
 
 class FileEnvWriter:
@@ -812,9 +898,9 @@ class FileEnvWriter:
                               src.printcolors.printcLabel(filename.name), 3)
 
         # create then env object
-        tmp = src.fileEnviron.get_file_environ(filename, 
-                                               "cfgForPy", 
-                                               {})
+        tmp = src.fileEnviron.get_file_environ(filename, "cfgForPy", {})
+        # DBG.write("fileEnviron.get_file_environ %s" % filename, tmp, True)
+
         # environment for launch
         env = SalomeEnviron(self.config,
                             tmp,
@@ -823,19 +909,22 @@ class FileEnvWriter:
                             enable_simple_env_script = with_commercial)
         env.silent = self.silent
 
+        DBG.write("write_cfgForPy_file", self.config.APPLICATION.environ)
+
         if self.env_info is not None:
             env.set_full_environ(self.logger, self.env_info)
+            DBG.write("set_full_environ", self.env_info)
+
         else:
             # set env from PRODUCT
             env.set_application_env(self.logger)
 
             # The list of products to launch
             lProductsName = env.get_names(self.config.APPLICATION.products.keys())
-            env.set( "SALOME_MODULES",    ','.join(lProductsName))
+            env.set("SALOME_MODULES", ','.join(lProductsName))
 
             # set the products
-            env.set_products(self.logger,
-                            src_root=self.src_root)
+            env.set_products(self.logger, src_root=self.src_root)
 
         # Add the additional environment if it is not empty
         if len(additional_env) != 0: