]> SALOME platform Git repositories - tools/sat.git/blob - commands/make.py
Salome HOME
#8577 extension du domaine des properties
[tools/sat.git] / commands / make.py
1 #!/usr/bin/env python
2 #-*- coding:utf-8 -*-
3 #  Copyright (C) 2010-2012  CEA/DEN
4 #
5 #  This library is free software; you can redistribute it and/or
6 #  modify it under the terms of the GNU Lesser General Public
7 #  License as published by the Free Software Foundation; either
8 #  version 2.1 of the License.
9 #
10 #  This library is distributed in the hope that it will be useful,
11 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
12 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13 #  Lesser General Public License for more details.
14 #
15 #  You should have received a copy of the GNU Lesser General Public
16 #  License along with this library; if not, write to the Free Software
17 #  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
18
19 import os
20 import re
21
22 import src
23
24 # Define all possible option for the make command :  sat make <options>
25 parser = src.options.Options()
26 parser.add_option('p', 'products', 'list2', 'products',
27     _('Optional: products to configure. This option can be'
28     ' passed several time to configure several products.'))
29 parser.add_option('o', 'option', 'string', 'option',
30     _('Optional: Option to add to the make command.'), "")
31
32
33 def log_step(logger, header, step):
34     logger.write("\r%s%s" % (header, " " * 20), 3)
35     logger.write("\r%s%s" % (header, step), 3)
36     logger.write("\n==== %s \n" % src.printcolors.printcInfo(step), 4)
37     logger.flush()
38
39 def log_res_step(logger, res):
40     if res == 0:
41         logger.write("%s \n" % src.printcolors.printcSuccess("OK"), 4)
42         logger.flush()
43     else:
44         logger.write("%s \n" % src.printcolors.printcError("KO"), 4)
45         logger.flush()
46
47 def make_all_products(config, products_infos, make_option, logger):
48     '''Execute the proper configuration commands 
49        in each product build directory.
50
51     :param config Config: The global configuration
52     :param products_info list: List of 
53                                  (str, Config) => (product_name, product_info)
54     :param make_option str: The options to add to the command
55     :param logger Logger: The logger instance to use for the display and logging
56     :return: the number of failing commands.
57     :rtype: int
58     '''
59     res = 0
60     for p_name_info in products_infos:
61         res_prod = make_product(p_name_info, make_option, config, logger)
62         if res_prod != 0:
63             res += 1 
64     return res
65
66 def make_product(p_name_info, make_option, config, logger):
67     '''Execute the proper configuration command(s) 
68        in the product build directory.
69     
70     :param p_name_info tuple: (str, Config) => (product_name, product_info)
71     :param make_option str: The options to add to the command
72     :param config Config: The global configuration
73     :param logger Logger: The logger instance to use for the display 
74                           and logging
75     :return: 1 if it fails, else 0.
76     :rtype: int
77     '''
78     
79     p_name, p_info = p_name_info
80     
81     # Logging
82     logger.write("\n", 4, False)
83     logger.write("################ ", 4)
84     header = _("Make of %s") % src.printcolors.printcLabel(p_name)
85     header += " %s " % ("." * (20 - len(p_name)))
86     logger.write(header, 3)
87     logger.write("\n", 4, False)
88     logger.flush()
89
90     # Do nothing if he product is not compilable
91     if ("properties" in p_info and "compilation" in p_info.properties and 
92                                         p_info.properties.compilation == "no"):
93         log_step(logger, header, "ignored")
94         logger.write("\n", 3, False)
95         return 0
96
97     # Instantiate the class that manages all the construction commands
98     # like cmake, make, make install, make test, environment management, etc...
99     builder = src.compilation.Builder(config, logger, p_info)
100     
101     # Prepare the environment
102     log_step(logger, header, "PREPARE ENV")
103     res_prepare = builder.prepare()
104     log_res_step(logger, res_prepare)
105     
106     # Execute buildconfigure, configure if the product is autotools
107     # Execute cmake if the product is cmake
108     len_end_line = 20
109
110     nb_proc, make_opt_without_j = get_nb_proc(p_info, config, make_option)
111     log_step(logger, header, "MAKE -j" + str(nb_proc))
112     if src.architecture.is_windows():
113         res = builder.wmake(nb_proc, make_opt_without_j)
114     else:
115         res = builder.make(nb_proc, make_opt_without_j)
116     log_res_step(logger, res)
117     
118     # Log the result
119     if res > 0:
120         logger.write("\r%s%s" % (header, " " * len_end_line), 3)
121         logger.write("\r" + header + src.printcolors.printcError("KO"))
122         logger.write("==== %(KO)s in make of %(name)s \n" %
123             { "name" : p_name , "KO" : src.printcolors.printcInfo("ERROR")}, 4)
124         logger.flush()
125     else:
126         logger.write("\r%s%s" % (header, " " * len_end_line), 3)
127         logger.write("\r" + header + src.printcolors.printcSuccess("OK"))
128         logger.write("==== %s \n" % src.printcolors.printcInfo("OK"), 4)
129         logger.write("==== Make of %(name)s %(OK)s \n" %
130             { "name" : p_name , "OK" : src.printcolors.printcInfo("OK")}, 4)
131         logger.flush()
132     logger.write("\n", 3, False)
133
134     return res
135
136 def get_nb_proc(product_info, config, make_option):
137     
138     opt_nb_proc = None
139     new_make_option = make_option
140     if "-j" in make_option:
141         oExpr = re.compile("-j[0-9]+")
142         found = oExpr.search(make_option)
143         opt_nb_proc = int(re.findall('\d+', found.group())[0])
144         new_make_option = make_option.replace(found.group(), "")
145     
146     nbproc = -1
147     if "nb_proc" in product_info:
148         # nb proc is specified in module definition
149         nbproc = product_info.nb_proc
150         if opt_nb_proc and opt_nb_proc < product_info.nb_proc:
151             # use command line value only if it is lower than module definition
152             nbproc = opt_nb_proc
153     else:
154         # nb proc is not specified in module definition
155         if opt_nb_proc:
156             nbproc = opt_nb_proc
157         else:
158             nbproc = config.VARS.nb_proc
159     
160     assert nbproc > 0
161     return nbproc, new_make_option
162
163 def description():
164     '''method that is called when salomeTools is called with --help option.
165     
166     :return: The text to display for the make command description.
167     :rtype: str
168     '''
169     return _("The make command executes the \"make\" command in"
170              " the build directory.\nexample:\nsat make SALOME-master "
171              "--products Python,KERNEL,GUI")
172   
173 def run(args, runner, logger):
174     '''method that is called when salomeTools is called with make parameter.
175     '''
176     
177     # Parse the options
178     (options, args) = parser.parse_args(args)
179
180     # check that the command has been called with an application
181     src.check_config_has_application( runner.cfg )
182
183     # Get the list of products to treat
184     products_infos = src.product.get_products_list(options, runner.cfg, logger)
185     
186     # Print some informations
187     logger.write(_('Executing the make command in the build '
188                                 'directories of the application %s\n') % 
189                 src.printcolors.printcLabel(runner.cfg.VARS.application), 1)
190     
191     info = [(_("BUILD directory"),
192              os.path.join(runner.cfg.APPLICATION.workdir, 'BUILD'))]
193     src.print_info(logger, info)
194     
195     # Call the function that will loop over all the products and execute
196     # the right command(s)
197     if options.option is None:
198         options.option = ""
199     res = make_all_products(runner.cfg, products_infos, options.option, logger)
200     
201     # Print the final state
202     nb_products = len(products_infos)
203     if res == 0:
204         final_status = "OK"
205     else:
206         final_status = "KO"
207    
208     logger.write(_("\nMake: %(status)s (%(valid_result)d/%(nb_products)d)\n") % \
209         { 'status': src.printcolors.printc(final_status), 
210           'valid_result': nb_products - res,
211           'nb_products': nb_products }, 1)    
212     
213     return res