Salome HOME
Add make command first version
authorSerge Rehbinder <serge.rehbinder@cea.fr>
Wed, 18 May 2016 12:31:52 +0000 (14:31 +0200)
committerSerge Rehbinder <serge.rehbinder@cea.fr>
Wed, 18 May 2016 12:31:52 +0000 (14:31 +0200)
commands/configure.py
commands/make.py [new file with mode: 0644]
complete_sat.sh
src/compilation.py
src/product.py

index 17341d8bbb06eeea0aa100b753f643f213e08325..9349fed1101357a2cdd9ba3f0ea912195a239153 100644 (file)
@@ -177,7 +177,7 @@ def description():
              "cmake: cmake\nscript: N\A")
   
 def run(args, runner, logger):
-    '''method that is called when salomeTools is called with prepare parameter.
+    '''method that is called when salomeTools is called with make parameter.
     '''
     
     # Parse the options
diff --git a/commands/make.py b/commands/make.py
new file mode 100644 (file)
index 0000000..a64ec11
--- /dev/null
@@ -0,0 +1,232 @@
+#!/usr/bin/env python
+#-*- coding:utf-8 -*-
+#  Copyright (C) 2010-2012  CEA/DEN
+#
+#  This library is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU Lesser General Public
+#  License as published by the Free Software Foundation; either
+#  version 2.1 of the License.
+#
+#  This library is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  Lesser General Public License for more details.
+#
+#  You should have received a copy of the GNU Lesser General Public
+#  License along with this library; if not, write to the Free Software
+#  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+
+import os
+import re
+
+import src
+
+# Define all possible option for the make command :  sat make <options>
+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.'))
+parser.add_option('o', 'option', 'string', 'option',
+    _('Option to add to the make command.'), "")
+
+def get_products_list(options, cfg, logger):
+    '''method that gives the product list with their informations from 
+       configuration regarding the passed options.
+    
+    :param options Options: The Options instance that stores the commands 
+                            arguments
+    :param cfg Config: The global configuration
+    :param logger Logger: The logger instance to use for the display and logging
+    :return: The list of (product name, product_informations).
+    :rtype: List
+    '''
+    # Get the products to be prepared, regarding the options
+    if options.products is None:
+        # No options, get all products sources
+        products = cfg.APPLICATION.products
+    else:
+        # if option --products, check that all products of the command line
+        # are present in the application.
+        products = options.products
+        for p in products:
+            if p not in cfg.APPLICATION.products:
+                raise src.SatException(_("Product %(product)s "
+                            "not defined in application %(application)s") %
+                        { 'product': p, 'application': cfg.VARS.application} )
+    
+    # Construct the list of tuple containing 
+    # the products name and their definition
+    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
+
+def log_step(logger, header, step):
+    logger.write("\r%s%s" % (header, " " * 20), 3)
+    logger.write("\r%s%s" % (header, step), 3)
+    logger.write("\n==== %s \n" % src.printcolors.printcInfo(step), 4)
+    logger.flush()
+
+def log_res_step(logger, res):
+    if res == 0:
+        logger.write("%s \n" % src.printcolors.printcSuccess("OK"), 4)
+        logger.flush()
+    else:
+        logger.write("%s \n" % src.printcolors.printcError("KO"), 4)
+        logger.flush()
+
+def make_all_products(config, products_infos, make_option, logger):
+    '''Execute the proper configuration commands 
+       in each product build directory.
+
+    :param config Config: The global configuration
+    :param products_info list: List of 
+                                 (str, Config) => (product_name, product_info)
+    :param make_option str: The options to add to the command
+    :param logger Logger: The logger instance to use for the display and logging
+    :return: the number of failing commands.
+    :rtype: int
+    '''
+    res = 0
+    for p_name_info in products_infos:
+        res_prod = make_product(p_name_info, make_option, config, logger)
+        if res_prod != 0:
+            res += 1 
+    return res
+
+def make_product(p_name_info, make_option, config, logger):
+    '''Execute the proper configuration command(s) 
+       in the product build directory.
+    
+    :param p_name_info tuple: (str, Config) => (product_name, product_info)
+    :param make_option str: The options to add to the command
+    :param config Config: The global configuration
+    :param logger Logger: The logger instance to use for the display 
+                          and logging
+    :return: 1 if it fails, else 0.
+    :rtype: int
+    '''
+    
+    p_name, p_info = p_name_info
+    
+    # Logging
+    logger.write("\n", 4, False)
+    logger.write("################ ", 4)
+    header = _("Make of %s") % src.printcolors.printcLabel(p_name)
+    header += " %s " % ("." * (20 - len(p_name)))
+    logger.write(header, 3)
+    logger.write("\n", 4, False)
+    logger.flush()
+    
+    # Instantiate the class that manages all the construction commands
+    # like cmake, make, make install, make test, environment management, etc...
+    builder = src.compilation.Builder(config, logger, p_info)
+    
+    # Prepare the environment
+    log_step(logger, header, "PREPARE ENV")
+    res_prepare = builder.prepare()
+    log_res_step(logger, res_prepare)
+    
+    # Execute buildconfigure, configure if the product is autotools
+    # Execute cmake if the product is cmake
+    res = 0
+    if not src.product.product_has_script(p_info):
+        nb_proc, make_opt_without_j = get_nb_proc(p_info, config, make_option)
+        log_step(logger, header, "MAKE -j" + str(nb_proc))
+        res_m = builder.make(nb_proc, make_opt_without_j)
+        log_res_step(logger, res_m)
+        res += res_m
+    
+    # Log the result
+    if res > 0:
+        logger.write("\r%s%s" % (header, " " * 20), 3)
+        logger.write("\r" + header + src.printcolors.printcError("KO"))
+        logger.write("==== %(KO)s in make of %(name)s \n" %
+            { "name" : p_name , "KO" : src.printcolors.printcInfo("ERROR")}, 4)
+        logger.flush()
+    else:
+        logger.write("\r%s%s" % (header, " " * 20), 3)
+        logger.write("\r" + header + src.printcolors.printcSuccess("OK"))
+        logger.write("==== %s \n" % src.printcolors.printcInfo("OK"), 4)
+        logger.write("==== Make of %(name)s %(OK)s \n" %
+            { "name" : p_name , "OK" : src.printcolors.printcInfo("OK")}, 4)
+        logger.flush()
+    logger.write("\n", 3, False)
+
+    return res
+
+def get_nb_proc(product_info, config, make_option):
+    
+    opt_nb_proc = None
+    new_make_option = make_option
+    if "-j" in make_option:
+        oExpr = re.compile("-j[0-9]+")
+        found = oExpr.search(make_option)
+        opt_nb_proc = int(re.findall('\d+', found.group())[0])
+        new_make_option = make_option.replace(found.group(), "")
+    
+    nbproc = -1
+    if "nb_proc" in product_info:
+        # nb proc is specified in module definition
+        nbproc = product_info.nb_proc
+        if opt_nb_proc and opt_nb_proc < product_info.nb_proc:
+            # use command line value only if it is lower than module definition
+            nbproc = opt_nb_proc
+    else:
+        # nb proc is not specified in module definition
+        if opt_nb_proc:
+            nbproc = opt_nb_proc
+        else:
+            nbproc = config.VARS.nb_proc
+    
+    assert nbproc > 0
+    return nbproc, new_make_option
+
+def description():
+    '''method that is called when salomeTools is called with --help option.
+    
+    :return: The text to display for the make command description.
+    :rtype: str
+    '''
+    return _("The make command executes the \"make\" command in"
+             " the build directory")
+  
+def run(args, runner, logger):
+    '''method that is called when salomeTools is called with make parameter.
+    '''
+    
+    # Parse the options
+    (options, args) = parser.parse_args(args)
+
+    # check that the command has been called with an application
+    src.check_config_has_application( runner.cfg )
+
+    # Get the list of products to threat
+    products_infos = get_products_list(options, runner.cfg, logger)
+    
+    # Print some informations
+    logger.write(_('Executing the make command in the build directories of the application %s\n') % 
+                src.printcolors.printcLabel(runner.cfg.VARS.application), 1)
+    
+    info = [(_("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)
+    res = make_all_products(runner.cfg, products_infos, options.option, logger)
+    
+    # Print the final state
+    nb_products = len(products_infos)
+    if res == 0:
+        final_status = "OK"
+    else:
+        final_status = "KO"
+   
+    logger.write(_("\nMake: %(status)s (%(valid_result)d/%(nb_products)d)\n") % \
+        { 'status': src.printcolors.printc(final_status), 
+          'valid_result': nb_products - res,
+          'nb_products': nb_products }, 1)    
+    
+    return res 
\ No newline at end of file
index 8c5e650d3b70c5a72f2f26069b152a95d02b61ba..585e73454ef5c34724c1008ad1bac55435d4bd25 100755 (executable)
@@ -80,7 +80,7 @@ _salomeTools_complete()
     # first argument => show available commands
     if [[ ${argc} == 1 ]]
     then
-        opts="config log testcommand source patch prepare environ clean configure --help"
+        opts="config log testcommand source patch prepare environ clean configure make --help"
         COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
         return 0
     fi
@@ -169,6 +169,11 @@ _salomeTools_complete()
             COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
             return 0
             ;;
+        make)
+            opts="--products --option"
+            COMPREPLY=( $(compgen -W "${opts}" -- ${cur}) )
+            return 0
+            ;;
         *) return 0 ;;
     esac
     
index 12ee8e94e5d7f206fe9136758926e1496f9373bd..f08d171e98ee4badefa6c950343021515ccc8205 100644 (file)
@@ -229,20 +229,12 @@ CC=\\"hack_libtool\\"%g" libtool'''
 
     ##
     # Runs make to build the module.
-    def make(self, opt_nb_proc = None):
-        nbproc = self.get_nb_proc(opt_nb_proc)
-
-        hh = 'MAKE -j%s' % str(nbproc)
-        if self.debug_mode:
-            hh += " " + src.printcolors.printcWarning("DEBUG")
-        self.log_step(hh)
+    def make(self, nb_proc, make_opt):
 
         # make
         command = 'make'
-        if self.options.makeflags:
-            command = command + " " + self.options.makeflags
-        command = command + " -j" + str(nbproc)
-
+        command = command + " -j" + str(nb_proc)
+        command = command + " " + make_opt
         self.log_command(command)
         res = subprocess.call(command,
                               shell=True,
index b607b659ede08309998db33b7386989a904fef94..a165d739c2d08af1889e838492a933ae701b0a2b 100644 (file)
@@ -274,4 +274,15 @@ def product_is_cmake(product_info):
     :rtype: boolean
     '''
     build_src = product_info.build_source
-    return build_src.lower() == 'cmake'
\ No newline at end of file
+    return build_src.lower() == 'cmake'
+
+def product_has_script(product_info):
+    '''Know if a product has a compilation script
+    
+    :param product_info Config: The configuration specific to 
+                               the product
+    :return: True if the product it has a compilation script, else False
+    :rtype: boolean
+    '''
+    build_src = product_info.build_source
+    return build_src.lower() == 'script'
\ No newline at end of file