Salome HOME
do not create install dir for pip products installed in python, adapt archives to...
[tools/sat.git] / commands / compile.py
index 4c469bcf5b3aee24b909da3a304bd9c00f640e60..47a3d4b8a53159c6dd7b7f1197c31efe0069eb75 100644 (file)
@@ -18,6 +18,7 @@
 
 import os
 import re
+import subprocess
 import src
 import src.debug as DBG
 
@@ -108,7 +109,7 @@ def check_dependencies(config, p_name_p_info, all_products_dict):
     for prod in p_name_p_info[1]["depend_all"]:
         # for each dependency, check the install
         prod_name, prod_info=all_products_dict[prod]
-        if not(src.product.check_installation(prod_info)):
+        if not(src.product.check_installation(config, prod_info)):
             l_depends_not_installed.append(prod_name)
     return l_depends_not_installed   # non installed deps
 
@@ -196,7 +197,10 @@ def compile_all_products(sat, config, options, products_infos, all_products_dict
         
         # Check if sources was already successfully installed
         check_source = src.product.check_source(p_info)
-        if not options.no_compile: # don't check sources with option --show!
+        is_pip= (src.appli_test_property(config,"pip", "yes") and src.product.product_test_property(p_info,"pip", "yes"))
+        # don't check sources with option --show 
+        # or for products managed by pip (there sources are in wheels stored in LOCAL.ARCHIVE
+        if not (options.no_compile or is_pip): 
             if not check_source:
                 logger.write(_("Sources of product not found (try 'sat -h prepare') \n"))
                 res += 1 # one more error
@@ -228,7 +232,7 @@ def compile_all_products(sat, config, options, products_infos, all_products_dict
                 continue
         
         # Check if it was already successfully installed
-        if src.product.check_installation(p_info):
+        if src.product.check_installation(config, p_info):
             logger.write(_("Already installed"))
             logger.write(_(" in %s" % p_info.install_dir), 4)
             logger.write(_("\n"))
@@ -328,23 +332,36 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end):
     # 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 if pip should be used : the application and product have pip property
+    if (src.appli_test_property(config,"pip", "yes") and 
+       src.product.product_test_property(p_info,"pip", "yes")):
+            res, len_end_line, error_step = compile_product_pip(sat,
+                                                                p_name_info,
+                                                                config,
+                                                                options,
+                                                                logger,
+                                                                header,
+                                                                len_end)
+    else:
+        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)):
@@ -376,6 +393,92 @@ def compile_product(sat, p_name_info, config, options, logger, header, len_end):
     
     return res, len_end_line, error_step
 
+
+def compile_product_pip(sat,
+                        p_name_info,
+                        config,
+                        options,
+                        logger,
+                        header,
+                        len_end):
+    '''Execute the proper build procedure for pip products
+    :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
+    '''
+    # a) initialisation
+    p_name, p_info = p_name_info
+    res = 0
+    error_step = ""
+    pip_install_in_python=False
+    pip_wheels_dir=os.path.join(config.LOCAL.archive_dir,"wheels")
+    pip_install_cmd=config.INTERNAL.command.pip_install # parametrized in src/internal
+
+    # b) get the build environment (useful to get the installed python & pip3)
+    build_environ = src.environment.SalomeEnviron(config,
+                             src.environment.Environ(dict(os.environ)),
+                             True)
+    environ_info = src.product.get_product_dependencies(config,
+                                                        p_info)
+    build_environ.silent = (config.USER.output_verbose_level < 5)
+    build_environ.set_full_environ(logger, environ_info)
+
+    # c- download : check/get pip wheel in pip_wheels_dir
+    pip_download_cmd=config.INTERNAL.command.pip_download +\
+                     " --destination-directory %s --no-deps %s==%s " %\
+                     (pip_wheels_dir, p_info.name, p_info.version)
+    logger.write("\n"+pip_download_cmd+"\n", 4, False) 
+    res_pip_dwl = (subprocess.call(pip_download_cmd, 
+                                   shell=True, 
+                                   cwd=config.LOCAL.workdir,
+                                   env=build_environ.environ.environ,
+                                   stdout=logger.logTxtFile, 
+                                   stderr=subprocess.STDOUT) == 0)
+    # error is not managed at the stage. error will be handled by pip install
+    # here we just print a message
+    if not res_pip_dwl:
+        logger.write("Error in pip download\n", 4, False)
+
+
+    # d- install (in python or in separate product directory)
+    if src.appli_test_property(config,"pip_install_dir", "python"):
+        # pip will install product in python directory"
+        pip_install_cmd+=" --find-links=%s --build %s %s==%s" %\
+        (pip_wheels_dir, p_info.build_dir, p_info.name, p_info.version)
+        pip_install_in_python=True
+        
+    else: 
+        # pip will install product in product install_dir
+        pip_install_dir=os.path.join(p_info.install_dir, "lib", "python${PYTHON_VERSION:0:3}", "site-packages")
+        pip_install_cmd+=" --find-links=%s --build %s --target %s %s==%s" %\
+        (pip_wheels_dir, p_info.build_dir, pip_install_dir, p_info.name, p_info.version)
+    log_step(logger, header, "PIP")
+    logger.write("\n"+pip_install_cmd+"\n", 4)
+    len_end_line = len_end + 3
+    error_step = ""
+
+    res_pip = (subprocess.call(pip_install_cmd, 
+                               shell=True, 
+                               cwd=config.LOCAL.workdir,
+                               env=build_environ.environ.environ,
+                               stdout=logger.logTxtFile, 
+                               stderr=subprocess.STDOUT) == 0)        
+    if res_pip:
+        res=0
+    else:
+        #log_res_step(logger, res)
+        res=1
+        error_step = "PIP"
+
+    return res, len_end_line, error_step 
+
+
+
 def compile_product_cmake_autotools(sat,
                                     p_name_info,
                                     config,