X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=src%2Fcompilation.py;h=b8b8ce0cf8150b24ff76340da35da6ebbb019baf;hb=f0c1fa827be3842a11b6b9520b2bef2542780e58;hp=009a0b81d4358b2434a0714376a30ec5960445f0;hpb=2f38beaea8436fdb26d4f2516340cf33361d0b95;p=tools%2Fsat.git diff --git a/src/compilation.py b/src/compilation.py index 009a0b8..b8b8ce0 100644 --- a/src/compilation.py +++ b/src/compilation.py @@ -19,6 +19,8 @@ import os import subprocess import sys +import shutil +import glob import src @@ -33,7 +35,12 @@ C_COMPILE_ENV_LIST = ["CC", class Builder: """Class to handle all construction steps, like cmake, configure, make, ... """ - def __init__(self, config, logger, product_info, options = src.options.OptResult(), debug_mode=False, check_src=True): + def __init__(self, + config, + logger, + product_info, + options = src.options.OptResult(), + check_src=True): self.config = config self.logger = logger self.options = options @@ -42,20 +49,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 - - if not self.source_dir.exists() and check_src: - raise src.SatException(_("No sources found for product %(product)s in %(source_dir)s" % \ - { "product": self.product_info.name, "source_dir": self.source_dir } )) - - """ - # check that required modules exist - for dep in self.product_info.depend: - assert dep in self.config.TOOLS.src.product_info, "UNDEFINED product: %s" % dep - dep_info = self.config.TOOLS.src.product_info[dep] - if 'install_dir' in dep_info and not os.path.exists(dep_info.install_dir): - raise src.SatException(_("Module %s is required") % dep) - """ + 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. @@ -83,15 +82,21 @@ class Builder: self.log('\n', 4) # add products in depend and opt_depend list recursively - environ_info = src.product.get_product_dependencies(self.config, self.product_info) + environ_info = src.product.get_product_dependencies(self.config, + self.product_info) + #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) @@ -109,18 +114,30 @@ 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), @@ -128,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: @@ -150,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: @@ -163,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) @@ -174,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: @@ -212,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' @@ -225,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: @@ -233,23 +253,18 @@ 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" + command = command + " /p:Configuration=Debug /p:Platform=x64 " else: - command = command + " /p:Configuration=Release" + command = command + " /p:Configuration=Release /p:Platform=x64 " command = command + " ALL_BUILD.vcxproj" self.log_command(command) @@ -259,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: @@ -268,15 +284,14 @@ CC=\\"hack_libtool\\"%g" libtool''' ## # Runs 'make install'. def install(self): - if self.config.VARS.dist_name=="Win": + if src.architecture.is_windows(): command = 'msbuild INSTALL.vcxproj' if self.debug_mode: - command = command + " /p:Configuration=Debug" + command = command + " /p:Configuration=Debug /p:Platform=x64 " else: - command = command + " /p:Configuration=Release" + command = command + " /p:Configuration=Release /p:Platform=x64 " else : command = 'make install' - self.log_command(command) res = subprocess.call(command, @@ -285,32 +300,63 @@ CC=\\"hack_libtool\\"%g" libtool''' env=self.build_environ.environ.environ, stdout=self.logger.logTxtFile, stderr=subprocess.STDOUT) + + res_check=self.check_install() + if res_check > 0 : + self.log_command("Error in sat check install - some files are not installed!") + self.put_txt_log_in_appli_log_dir("makeinstall") + res+=res_check if res == 0: return res else: return 1 + # this function checks wether a list of file patterns (specified by check_install keyword) + # exixts after the make install. The objective is to ensure the installation is complete. + # patterns are given relatively to the install dir of the product + def check_install(self): + res=0 + if "check_install" in self.product_info: + self.log_command("Check installation of files") + for pattern in self.product_info.check_install: + # pattern is given relatively to the install dir + complete_pattern=os.path.join(self.product_info.install_dir, pattern) + self.log_command(" -> check %s" % complete_pattern) + # expansion of pattern : takes into account environment variables and unix shell rules + list_of_path=glob.glob(os.path.expandvars(complete_pattern)) + if not list_of_path: + # we expect to find at least one entry, if not we consider the test failed + res+=1 + self.logger.write("Error, sat check install failed for file pattern %s\n" % complete_pattern, 1) + self.log_command("Error, sat check install failed for file pattern %s" % complete_pattern) + return res + ## # 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 /p:Configuration=Release /p:Platform=x64 ' else : - if self.use_autotools : - command = 'make check' - else : - command = 'make test' - - self.log_command(command) + if self.product_info.build_source=="autotools" : + cmd = 'make check' + else: + 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: @@ -318,7 +364,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 @@ -351,7 +400,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() @@ -375,26 +425,34 @@ CC=\\"hack_libtool\\"%g" libtool''' ## # Performs a build with a script. - def do_python_script_build(self, script): + def do_python_script_build(self, script, nb_proc): # script found - self.logger.write(_("Compile %(module)s using script %(script)s\n") % \ - { 'module': self.module, 'script': src.printcolors.printcLabel(script) }, 4) + self.logger.write(_("Compile %(product)s using script %(script)s\n") % \ + { 'product': self.product_info.name, + 'script': src.printcolors.printcLabel(script) }, 4) try: import imp - pymodule = imp.load_source(self.product + "_compile_script", script) + product = self.product_info.name + pymodule = imp.load_source(product + "_compile_script", script) + self.nb_proc = nb_proc retcode = pymodule.compil(self.config, self, self.logger) except: __, exceptionValue, exceptionTraceback = sys.exc_info() - print(exceptionValue) + self.logger.write(str(exceptionValue), 1) import traceback 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("APPLICATION_NAME", self.config.APPLICATION.name) 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,12 +462,13 @@ CC=\\"hack_libtool\\"%g" libtool''' self.build_environ.set("DIST_NAME", self.config.VARS.dist_name) 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): - # 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 + def do_batch_script_build(self, script, nb_proc): if src.architecture.is_windows(): make_options = "/maxcpucount:%s" % nb_proc @@ -418,24 +477,60 @@ 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) + res_check=self.check_install() + if res_check > 0 : + self.log_command("Error in sat check install - some files are not installed!") + + self.put_txt_log_in_appli_log_dir("script") + res += res_check 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) + 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"]: - return self.do_batch_script_build(script) + return self.do_batch_script_build(script, nb_proc) if extension == "py": - return self.do_python_script_build(script) + 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 /LOGS// + + :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()) +