Salome HOME
sat #8594 : extension des logs de sat log --last_compile au make check
[tools/sat.git] / src / compilation.py
index c0460027f65b99453d560105cea7813d8e9f77b9..4da9566e68f24b437560f944f8b7c58808ebe2ff 100644 (file)
@@ -19,6 +19,7 @@
 import os
 import subprocess
 import sys
+import shutil
 
 import src
 
@@ -38,7 +39,6 @@ class Builder:
                  logger,
                  product_info,
                  options = src.options.OptResult(),
-                 debug_mode=False,
                  check_src=True):
         self.config = config
         self.logger = logger
@@ -48,7 +48,12 @@ class Builder:
         self.source_dir = src.Path(self.product_info.source_dir)
         self.install_dir = src.Path(self.product_info.install_dir)
         self.header = ""
-        self.debug_mode = debug_mode
+        self.debug_mode = False
+        if "debug" in self.product_info and self.product_info.debug == "yes":
+            self.debug_mode = True
+        self.verbose_mode = False
+        if "verbose" in self.product_info and self.product_info.verbose == "yes":
+            self.verbose_mode = True
 
     ##
     # Shortcut method to log in log file.
@@ -81,12 +86,16 @@ class Builder:
         #environ_info.append(self.product_info.name)
 
         # create build environment
-        self.build_environ = src.environment.SalomeEnviron(self.config, src.environment.Environ(dict(os.environ)), True)
+        self.build_environ = src.environment.SalomeEnviron(self.config,
+                                      src.environment.Environ(dict(os.environ)),
+                                      True)
         self.build_environ.silent = (self.config.USER.output_verbose_level < 5)
         self.build_environ.set_full_environ(self.logger, environ_info)
         
         # create runtime environment
-        self.launch_environ = src.environment.SalomeEnviron(self.config, src.environment.Environ(dict(os.environ)), False)
+        self.launch_environ = src.environment.SalomeEnviron(self.config,
+                                      src.environment.Environ(dict(os.environ)),
+                                      False)
         self.launch_environ.silent = True # no need to show here
         self.launch_environ.set_full_environ(self.logger, environ_info)
 
@@ -104,18 +113,31 @@ class Builder:
         cmake_option = options
         # cmake_option +=' -DCMAKE_VERBOSE_MAKEFILE=ON -DSALOME_CMAKE_DEBUG=ON'
         if 'cmake_options' in self.product_info:
-            cmake_option += " %s " % " ".join(self.product_info.cmake_options.split())
+            cmake_option += " %s " % " ".join(
+                                        self.product_info.cmake_options.split())
 
         # add debug option
         if self.debug_mode:
             cmake_option += " -DCMAKE_BUILD_TYPE=Debug"
         else :
             cmake_option += " -DCMAKE_BUILD_TYPE=Release"
+
+        # add verbose option if specified in application for this product.
+        if self.verbose_mode:
+            cmake_option += " -DCMAKE_VERBOSE_MAKEFILE=ON"
+
+        # In case CMAKE_GENERATOR is defined in environment, 
+        # use it in spite of automatically detect it
+        if 'cmake_generator' in self.config.APPLICATION:
+            cmake_option += " -DCMAKE_GENERATOR=%s" \
+                                       % self.config.APPLICATION.cmake_generator
         
         command = ("cmake %s -DCMAKE_INSTALL_PREFIX=%s %s" %
                             (cmake_option, self.install_dir, self.source_dir))
 
         self.log_command(command)
+        # for key in sorted(self.build_environ.environ.environ.keys()):
+            # print key, "  ", self.build_environ.environ.environ[key]
         res = subprocess.call(command,
                               shell=True,
                               cwd=str(self.build_dir),
@@ -123,6 +145,7 @@ class Builder:
                               stdout=self.logger.logTxtFile,
                               stderr=subprocess.STDOUT)
 
+        self.put_txt_log_in_appli_log_dir("cmake")
         if res == 0:
             return res
         else:
@@ -145,7 +168,7 @@ class Builder:
                               env=self.build_environ.environ.environ,
                               stdout=self.logger.logTxtFile,
                               stderr=subprocess.STDOUT)
-
+        self.put_txt_log_in_appli_log_dir("build_configure")
         if res == 0:
             return res
         else:
@@ -158,7 +181,8 @@ class Builder:
         if 'configure_options' in self.product_info:
             options += " %s " % self.product_info.configure_options
 
-        command = "%s/configure --prefix=%s" % (self.source_dir, str(self.install_dir))
+        command = "%s/configure --prefix=%s" % (self.source_dir,
+                                                str(self.install_dir))
 
         command = command + " " + options
         self.log_command(command)
@@ -169,7 +193,8 @@ class Builder:
                               env=self.build_environ.environ.environ,
                               stdout=self.logger.logTxtFile,
                               stderr=subprocess.STDOUT)
-
+        
+        self.put_txt_log_in_appli_log_dir("configure")
         if res == 0:
             return res
         else:
@@ -207,7 +232,7 @@ CC=\\"hack_libtool\\"%g" libtool'''
 
     ##
     # Runs make to build the module.
-    def make(self, nb_proc, make_opt):
+    def make(self, nb_proc, make_opt=""):
 
         # make
         command = 'make'
@@ -220,7 +245,7 @@ CC=\\"hack_libtool\\"%g" libtool'''
                               env=self.build_environ.environ.environ,
                               stdout=self.logger.logTxtFile,
                               stderr=subprocess.STDOUT)
-
+        self.put_txt_log_in_appli_log_dir("make")
         if res == 0:
             return res
         else:
@@ -228,19 +253,14 @@ CC=\\"hack_libtool\\"%g" libtool'''
     
     ##
     # Runs msbuild to build the module.
-    def wmake(self, opt_nb_proc = None):
-        nbproc = self.get_nb_proc(opt_nb_proc)
+    def wmake(self,nb_proc, opt_nb_proc = None):
 
-        hh = 'MSBUILD /m:%s' % str(nbproc)
+        hh = 'MSBUILD /m:%s' % str(nb_proc)
         if self.debug_mode:
             hh += " " + src.printcolors.printcWarning("DEBUG")
-        self.log_step(hh)
-
         # make
         command = 'msbuild'
-        if self.options.makeflags:
-            command = command + " " + self.options.makeflags
-        command = command + " /maxcpucount:" + str(nbproc)
+        command = command + " /maxcpucount:" + str(nb_proc)
         if self.debug_mode:
             command = command + " /p:Configuration=Debug"
         else:
@@ -254,7 +274,8 @@ CC=\\"hack_libtool\\"%g" libtool'''
                               env=self.build_environ.environ.environ,
                               stdout=self.logger.logTxtFile,
                               stderr=subprocess.STDOUT)
-
+        
+        self.put_txt_log_in_appli_log_dir("make")
         if res == 0:
             return res
         else:
@@ -280,7 +301,8 @@ CC=\\"hack_libtool\\"%g" libtool'''
                               env=self.build_environ.environ.environ,
                               stdout=self.logger.logTxtFile,
                               stderr=subprocess.STDOUT)
-
+        
+        self.put_txt_log_in_appli_log_dir("makeinstall")
         if res == 0:
             return res
         else:
@@ -288,24 +310,29 @@ CC=\\"hack_libtool\\"%g" libtool'''
 
     ##
     # Runs 'make_check'.
-    def check(self):
+    def check(self, command=""):
         if src.architecture.is_windows():
-            command = 'msbuild RUN_TESTS.vcxproj'
+            cmd = 'msbuild RUN_TESTS.vcxproj'
         else :
             if self.product_info.build_source=="autotools" :
-                command = 'make check'
+                cmd = 'make check'
             else:
-                command = 'make test'
-            
-        self.log_command(command)
+                cmd = 'make test'
+        
+        if command:
+            cmd = command
+        
+        self.log_command(cmd)
+        self.log_command("For more detailed logs, see test logs in %s" % self.build_dir)
 
-        res = subprocess.call(command,
+        res = subprocess.call(cmd,
                               shell=True,
                               cwd=str(self.build_dir),
                               env=self.launch_environ.environ.environ,
                               stdout=self.logger.logTxtFile,
                               stderr=subprocess.STDOUT)
 
+        self.put_txt_log_in_appli_log_dir("makecheck")
         if res == 0:
             return res
         else:
@@ -313,7 +340,10 @@ CC=\\"hack_libtool\\"%g" libtool'''
       
     ##
     # Performs a default build for this module.
-    def do_default_build(self, build_conf_options="", configure_options="", show_warning=True):
+    def do_default_build(self,
+                         build_conf_options="",
+                         configure_options="",
+                         show_warning=True):
         use_autotools = False
         if 'use_autotools' in self.product_info:
             uc = self.product_info.use_autotools
@@ -346,7 +376,8 @@ CC=\\"hack_libtool\\"%g" libtool'''
 
         if use_autotools:
             if not self.prepare(): return self.get_result()
-            if not self.build_configure(build_conf_options): return self.get_result()
+            if not self.build_configure(
+                                   build_conf_options): return self.get_result()
             if not self.configure(configure_options): return self.get_result()
             if not self.make(): return self.get_result()
             if not self.install(): return self.get_result()
@@ -388,12 +419,15 @@ CC=\\"hack_libtool\\"%g" libtool'''
             traceback.print_tb(exceptionTraceback)
             traceback.print_exc()
             retcode = 1
+        finally:
+            self.put_txt_log_in_appli_log_dir("script")
 
         return retcode
 
     def complete_environment(self, make_options):
         assert self.build_environ is not None
-        # pass additional variables to environment (may be used by the build script)
+        # pass additional variables to environment 
+        # (may be used by the build script)
         self.build_environ.set("SOURCE_DIR", str(self.source_dir))
         self.build_environ.set("INSTALL_DIR", str(self.install_dir))
         self.build_environ.set("PRODUCT_INSTALL", str(self.install_dir))
@@ -404,6 +438,10 @@ CC=\\"hack_libtool\\"%g" libtool'''
         self.build_environ.set("DIST_VERSION", self.config.VARS.dist_version)
         self.build_environ.set("DIST", self.config.VARS.dist)
         self.build_environ.set("VERSION", self.product_info.version)
+        # if product is in hpc mode, set SAT_HPC to 1 
+        # in order for the compilation script to take it into account
+        if src.product.product_is_hpc(self.product_info):
+            self.build_environ.set("SAT_HPC", "1")
 
     def do_batch_script_build(self, script, nb_proc):
 
@@ -414,23 +452,28 @@ CC=\\"hack_libtool\\"%g" libtool'''
 
         self.log_command("  " + _("Run build script %s\n") % script)
         self.complete_environment(make_options)
+        
         res = subprocess.call(script, 
                               shell=True,
                               stdout=self.logger.logTxtFile,
                               stderr=subprocess.STDOUT,
-                              cwd=str(self.build_dir), 
+                              cwd=str(self.build_dir),
                               env=self.build_environ.environ.environ)
 
+        self.put_txt_log_in_appli_log_dir("script")
         if res == 0:
             return res
         else:
             return 1
     
-    def do_script_build(self, script):
+    def do_script_build(self, script, number_of_proc=0):
         # define make options (may not be used by the script)
-        nb_proc = src.get_cfg_param(self.product_info,"nb_proc", 0)
-        if nb_proc == 0: 
-            nb_proc = self.config.VARS.nb_proc
+        if number_of_proc==0:
+            nb_proc = src.get_cfg_param(self.product_info,"nb_proc", 0)
+            if nb_proc == 0: 
+                nb_proc = self.config.VARS.nb_proc
+        else:
+            nb_proc = min(number_of_proc, self.config.VARS.nb_proc)
             
         extension = script.split('.')[-1]
         if extension in ["bat","sh"]:
@@ -439,4 +482,25 @@ CC=\\"hack_libtool\\"%g" libtool'''
             return self.do_python_script_build(script, nb_proc)
         
         msg = _("The script %s must have .sh, .bat or .py extension." % script)
-        raise src.SatException(msg)
\ No newline at end of file
+        raise src.SatException(msg)
+    
+    def put_txt_log_in_appli_log_dir(self, file_name):
+        '''Put the txt log (that contain the system logs, like make command
+           output) in the directory <APPLICATION DIR>/LOGS/<product_name>/
+    
+        :param file_name Str: the name of the file to write
+        '''
+        if self.logger.logTxtFile == sys.__stdout__:
+            return
+        dir_where_to_put = os.path.join(self.config.APPLICATION.workdir,
+                                        "LOGS",
+                                        self.product_info.name)
+        file_path = os.path.join(dir_where_to_put, file_name)
+        src.ensure_path_exists(dir_where_to_put)
+        # write the logTxtFile copy it to the destination, and then recreate 
+        # it as it was
+        self.logger.logTxtFile.close()
+        shutil.move(self.logger.txtFilePath, file_path)
+        self.logger.logTxtFile = open(str(self.logger.txtFilePath), 'w')
+        self.logger.logTxtFile.write(open(file_path, "r").read())
+