X-Git-Url: http://git.salome-platform.org/gitweb/?a=blobdiff_plain;f=commands%2Fcompile.py;h=9b51a87a56dd1e509874736f264133dbcb82eb10;hb=11c99a29802614c1c09c32e7c803959bfcc3c721;hp=6124d4ef23687be1bf7fdce8032de548354557b4;hpb=2a37842fde62715421e07793706b2563ad4dcf94;p=tools%2Fsat.git diff --git a/commands/compile.py b/commands/compile.py index 6124d4e..9b51a87 100644 --- a/commands/compile.py +++ b/commands/compile.py @@ -19,6 +19,7 @@ import os import src +import src.debug as DBG # Compatibility python 2/3 for input function # input stays input for python 3 and input = raw_input for python 2 @@ -30,24 +31,32 @@ except NameError: # Define all possible option for the compile command : sat compile parser = src.options.Options() parser.add_option('p', 'products', 'list2', 'products', - _('products to configure. This option can be' - ' passed several time to configure several products.')) + _('Optional: products to compile. This option can be' + ' passed several time to compile several products.')) parser.add_option('', 'with_fathers', 'boolean', 'fathers', - _("build all necessary products to the given product (KERNEL is build before" - " building GUI)."), False) + _("Optional: build all necessary products to the given product (KERNEL is " + "build before building GUI)."), False) parser.add_option('', 'with_children', 'boolean', 'children', - _("build all products using the given product (all SMESH plugins are build " - "after SMESH)."), False) + _("Optional: build all products using the given product (all SMESH plugins" + " are build after SMESH)."), False) parser.add_option('', 'clean_all', 'boolean', 'clean_all', - _("clean BUILD dir and INSTALL dir before building product."), False) + _("Optional: clean BUILD dir and INSTALL dir before building product."), + False) parser.add_option('', 'clean_install', 'boolean', 'clean_install', - _("clean INSTALL dir before building product."), False) + _("Optional: clean INSTALL dir before building product."), False) parser.add_option('', 'make_flags', 'string', 'makeflags', - _("add extra options to the 'make' command.")) + _("Optional: add extra options to the 'make' command.")) parser.add_option('', 'show', 'boolean', 'no_compile', - _("DO NOT COMPILE just show if products are installed or not."), False) -parser.add_option('', 'stop_first_fail', 'boolean', 'stop_first_fail', _("Stop" - "s the command at first product compilation fail."), False) + _("Optional: DO NOT COMPILE just show if products are installed or not."), + False) +parser.add_option('', 'stop_first_fail', 'boolean', 'stop_first_fail', _( + "Optional: Stops the command at first product compilation" + " fail."), False) +parser.add_option('', 'check', 'boolean', 'check', _( + "Optional: execute the unit tests after compilation"), False) + +parser.add_option('', 'clean_build_after', 'boolean', 'clean_build_after', + _('Optional: remove the build directory after successful compilation'), False) def get_products_list(options, cfg, logger): '''method that gives the product list with their informations from @@ -80,7 +89,6 @@ def get_products_list(options, cfg, logger): products_infos = src.product.get_products_infos(products, cfg) products_infos = [pi for pi in products_infos if not( - src.product.product_is_native(pi[1]) or src.product.product_is_fixed(pi[1]))] return products_infos @@ -290,28 +298,77 @@ def compile_all_products(sat, config, options, products_infos, logger): logger.write("\n", 4, False) logger.flush() - # Do nothing if he product is not compilable - if ("properties" in p_info and "compilation" in p_info.properties and - p_info.properties.compilation == "no"): + # Do nothing if the product is not compilable + if ("properties" in p_info and + "compilation" in p_info.properties and + p_info.properties.compilation == "no"): + log_step(logger, header, "ignored") logger.write("\n", 3, False) continue + # Do nothing if the product is native + if src.product.product_is_native(p_info): + log_step(logger, header, "native") + logger.write("\n", 3, False) + continue + # Clean the build and the install directories # if the corresponding options was called if options.clean_all: - log_step(logger, header, "CLEAN BUILD AND INSTALL") + log_step(logger, header, "CLEAN BUILD AND INSTALL ") sat.clean(config.VARS.application + " --products " + p_name + - " --build --install", batch=True, verbose=0) + " --build --install", + batch=True, + verbose=0, + logger_add_link = logger) # Clean the the install directory # if the corresponding option was called if options.clean_install and not options.clean_all: - log_step(logger, header, "CLEAN INSTALL") + log_step(logger, header, "CLEAN INSTALL ") sat.clean(config.VARS.application + " --products " + p_name + - " --install", batch=True, verbose=0) + " --install", + batch=True, + verbose=0, + logger_add_link = logger) + + # Recompute the product information to get the right install_dir + # (it could change if there is a clean of the install directory) + p_info = src.product.get_product_config(config, p_name) + + # Check if sources was already successfully installed + check_source = src.product.check_source(p_info) + if not check_source: + logger.write(_("Sources of product not found (try 'sat -h prepare') \n")) + res += 1 #BUG + continue + + if src.product.product_is_salome(p_info): + # For salome modules, we check if the sources of configuration modules are present + # configuration modules have the property "configure_dependency" + + # get the list of all modules in application + all_products_infos = src.product.get_products_infos(config.APPLICATION.products, + config) + check_source = True + # for configuration modules, check if sources are present + for product_name, product_info in all_products_infos: + if ("properties" in product_info and + "configure_dependency" in product_info.properties and + product_info.properties.configure_dependency == "yes"): + check_source = check_source and src.product.check_source(product_info) + if not check_source: + logger.write(_("\nERROR : SOURCES of %s not found! It is required for" + " the configuration\n" % product_name)) + logger.write(_(" Get it with the command : sat prepare %s -p %s \n" % + (config.APPLICATION.name, product_name))) + if not check_source: + # if at least one configuration module is not present, we stop compilation + res += 1 + continue # Check if it was already successfully installed if src.product.check_installation(p_info): @@ -335,29 +392,43 @@ def compile_all_products(sat, config, options, products_infos, logger): continue # Call the function to compile the product - res_prod, len_end_line, error_step = compile_product(sat, - p_name_info, - config, - options, - logger, - header, - len_end_line) + res_prod, len_end_line, error_step = compile_product( + sat, p_name_info, config, options, logger, header, len_end_line) if res_prod != 0: - # Clean the install directory if there is any - logger.write(_("Cleaning the install directory if there is any\n"), - 5) - sat.clean(config.VARS.application + - " --products " + p_name + - " --install", batch=True, verbose=0) res += 1 + if error_step != "CHECK": + # Clean the install directory if there is any + logger.write(_( + "Cleaning the install directory if there is any\n"), + 5) + sat.clean(config.VARS.application + + " --products " + p_name + + " --install", + batch=True, + verbose=0, + logger_add_link = logger) + else: + # Clean the build directory if the compilation and tests succeed + if options.clean_build_after: + log_step(logger, header, "CLEAN BUILD") + sat.clean(config.VARS.application + + " --products " + p_name + + " --build", + batch=True, + verbose=0, + logger_add_link = logger) + # Log the result if res_prod > 0: logger.write("\r%s%s" % (header, " " * len_end_line), 3) logger.write("\r" + header + src.printcolors.printcError("KO ") + error_step) logger.write("\n==== %(KO)s in compile of %(name)s \n" % { "name" : p_name , "KO" : src.printcolors.printcInfo("ERROR")}, 4) + if error_step == "CHECK": + logger.write(_("\nINSTALL directory = %s" % + src.printcolors.printcInfo(p_info.install_dir)), 3) logger.flush() else: logger.write("\r%s%s" % (header, " " * len_end_line), 3) @@ -384,12 +455,89 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end): :param config Config: The global configuration :param logger Logger: The logger instance to use for the display and logging + :param header Str: the header to display when logging + :param len_end Int: the lenght of the the end of line (used in display) :return: 1 if it fails, else 0. :rtype: int ''' p_name, p_info = p_name_info - + + # Get the build procedure from the product configuration. + # It can be : + # build_sources : autotools -> build_configure, configure, make, make install + # build_sources : cmake -> cmake, make, make install + # build_sources : script -> script executions + res = 0 + if (src.product.product_is_autotools(p_info) or + src.product.product_is_cmake(p_info)): + res, len_end_line, error_step = compile_product_cmake_autotools(sat, + p_name_info, + config, + options, + logger, + header, + len_end) + if src.product.product_has_script(p_info): + res, len_end_line, error_step = compile_product_script(sat, + p_name_info, + config, + options, + logger, + header, + len_end) + + # Check that the install directory exists + if res==0 and not(os.path.exists(p_info.install_dir)): + res = 1 + error_step = "NO INSTALL DIR" + msg = _("Error: despite the fact that all the steps ended successfully," + " no install directory was found !") + logger.write(src.printcolors.printcError(msg), 4) + logger.write("\n", 4) + return res, len_end, error_step + + # Add the config file corresponding to the dependencies/versions of the + # product that have been successfully compiled + if res==0: + logger.write(_("Add the config file in installation directory\n"), 5) + add_compile_config_file(p_info, config) + + if options.check: + # Do the unit tests (call the check command) + log_step(logger, header, "CHECK") + res_check = sat.check( + config.VARS.application + " --products " + p_name, + verbose = 0, + logger_add_link = logger) + if res_check != 0: + error_step = "CHECK" + + res += res_check + + return res, len_end_line, error_step + +def compile_product_cmake_autotools(sat, + p_name_info, + config, + options, + logger, + header, + len_end): + '''Execute the proper build procedure for autotools or cmake + in the product build directory. + + :param p_name_info tuple: (str, Config) => (product_name, product_info) + :param config Config: The global configuration + :param logger Logger: The logger instance to use for the display + and logging + :param header Str: the header to display when logging + :param len_end Int: the lenght of the the end of line (used in display) + :return: 1 if it fails, else 0. + :rtype: int + ''' + p_name, p_info = p_name_info + # Execute "sat configure", "sat make" and "sat install" res = 0 error_step = "" @@ -405,7 +553,7 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end): if res_c > 0: error_step = "CONFIGURE" - else: + else: # Logging and sat command call for make step # Logging take account of the fact that the product has a compilation # script or not @@ -444,14 +592,42 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end): if res_mi > 0: error_step = "MAKE INSTALL" + + return res, len_end_line, error_step + +def compile_product_script(sat, + p_name_info, + config, + options, + logger, + header, + len_end): + '''Execute the script build procedure in the product build directory. - # Add the config file corresponding to the dependencies/versions of the - # product that have been successfully compiled - if res==0: - logger.write(_("Add the config file in installation directory\n"), 5) - add_compile_config_file(p_info, config) + :param p_name_info tuple: (str, Config) => (product_name, product_info) + :param config Config: The global configuration + :param logger Logger: The logger instance to use for the display + and logging + :param header Str: the header to display when logging + :param len_end Int: the lenght of the the end of line (used in display) + :return: 1 if it fails, else 0. + :rtype: int + ''' + p_name, p_info = p_name_info - return res, len_end_line, error_step + # Execute "sat configure", "sat make" and "sat install" + error_step = "" + + # Logging and sat command call for the script step + scrit_path_display = src.printcolors.printcLabel(p_info.compil_script) + log_step(logger, header, "SCRIPT " + scrit_path_display) + len_end_line = len_end + len(scrit_path_display) + res = sat.script(config.VARS.application + " --products " + p_name, + verbose = 0, + logger_add_link = logger) + log_res_step(logger, res) + + return res, len_end_line, error_step def add_compile_config_file(p_info, config): '''Execute the proper configuration command(s) @@ -481,12 +657,14 @@ def description(): :return: The text to display for the compile command description. :rtype: str ''' - return _("The compile command constructs the products of the application") + return _("The compile command constructs the products of the application" + "\n\nexample:\nsat compile SALOME-master --products KERNEL,GUI," + "MEDCOUPLING --clean_all") def run(args, runner, logger): '''method that is called when salomeTools is called with compile parameter. ''' - + # DBG.write("compile runner.cfg", runner.cfg, True) # Parse the options (options, args) = parser.parse_args(args) @@ -503,6 +681,20 @@ def run(args, runner, logger): # check that the command has been called with an application src.check_config_has_application( runner.cfg ) + # Print some informations + logger.write(_('Executing the compile commands in the build ' + 'directories of the products of ' + 'the application %s\n') % + src.printcolors.printcLabel(runner.cfg.VARS.application), 1) + + info = [ + (_("SOURCE directory"), + os.path.join(runner.cfg.APPLICATION.workdir, 'SOURCES')), + (_("BUILD directory"), + os.path.join(runner.cfg.APPLICATION.workdir, 'BUILD')) + ] + src.print_info(logger, info) + # Get the list of products to treat products_infos = get_products_list(options, runner.cfg, logger) @@ -517,19 +709,6 @@ def run(args, runner, logger): # Sort the list regarding the dependencies of the products products_infos = sort_products(runner.cfg, products_infos) - # Print some informations - logger.write(_('Executing the compile commands in the build ' - 'directories of the products of ' - 'the application %s\n') % - src.printcolors.printcLabel(runner.cfg.VARS.application), 1) - - info = [ - (_("SOURCE directory"), - os.path.join(runner.cfg.APPLICATION.workdir, 'SOURCES')), - (_("BUILD directory"), - os.path.join(runner.cfg.APPLICATION.workdir, 'BUILD')) - ] - src.print_info(logger, info) # Call the function that will loop over all the products and execute # the right command(s) @@ -550,4 +729,4 @@ def run(args, runner, logger): code = res if code != 0: code = 1 - return code \ No newline at end of file + return code