Merge tag 'u-boot-at91-fixes-2022.04-a' of https://source.denx.de/u-boot/custodians...
[platform/kernel/u-boot.git] / tools / buildman / toolchain.py
index 4f39bfd..46a4e5e 100644 (file)
@@ -10,10 +10,10 @@ import sys
 import tempfile
 import urllib.request, urllib.error, urllib.parse
 
-import bsettings
-import command
-import terminal
-import tools
+from buildman import bsettings
+from patman import command
+from patman import terminal
+from patman import tools
 
 (PRIORITY_FULL_PREFIX, PRIORITY_PREFIX_GCC, PRIORITY_PREFIX_GCC_PATH,
     PRIORITY_CALC) = list(range(4))
@@ -99,7 +99,7 @@ class Toolchain:
         else:
             self.priority = priority
         if test:
-            result = command.RunPipe([cmd], capture=True, env=env,
+            result = command.run_pipe([cmd], capture=True, env=env,
                                      raise_on_error=False)
             self.ok = result.return_code == 0
             if verbose:
@@ -179,27 +179,35 @@ class Toolchain:
         output and possibly unicode encoded output of all build tools by
         adding LC_ALL=C.
 
+        Note that os.environb is used to obtain the environment, since in some
+        cases the environment many contain non-ASCII characters and we see
+        errors like:
+
+          UnicodeEncodeError: 'utf-8' codec can't encode characters in position
+             569-570: surrogates not allowed
+
         Args:
             full_path: Return the full path in CROSS_COMPILE and don't set
                 PATH
         Returns:
-            Dict containing the environemnt to use. This is based on the current
-            environment, with changes as needed to CROSS_COMPILE, PATH and
-            LC_ALL.
+            Dict containing the (bytes) environment to use. This is based on the
+            current environment, with changes as needed to CROSS_COMPILE, PATH
+            and LC_ALL.
         """
-        env = dict(os.environ)
+        env = dict(os.environb)
         wrapper = self.GetWrapper()
 
         if self.override_toolchain:
             # We'll use MakeArgs() to provide this
             pass
         elif full_path:
-            env['CROSS_COMPILE'] = wrapper + os.path.join(self.path, self.cross)
+            env[b'CROSS_COMPILE'] = tools.to_bytes(
+                wrapper + os.path.join(self.path, self.cross))
         else:
-            env['CROSS_COMPILE'] = wrapper + self.cross
-            env['PATH'] = self.path + ':' + env['PATH']
+            env[b'CROSS_COMPILE'] = tools.to_bytes(wrapper + self.cross)
+            env[b'PATH'] = tools.to_bytes(self.path) + b':' + env[b'PATH']
 
-        env['LC_ALL'] = 'C'
+        env[b'LC_ALL'] = b'C'
 
         return env
 
@@ -373,7 +381,7 @@ class Toolchains:
     def List(self):
         """List out the selected toolchains for each architecture"""
         col = terminal.Color()
-        print(col.Color(col.BLUE, 'List of available toolchains (%d):' %
+        print(col.build(col.BLUE, 'List of available toolchains (%d):' %
                         len(self.toolchains)))
         if len(self.toolchains):
             for key, value in sorted(self.toolchains.items()):
@@ -486,15 +494,17 @@ class Toolchains:
             else
                 URL containing this toolchain, if avaialble, else None
         """
-        arch = command.OutputOneLine('uname', '-m')
+        arch = command.output_one_line('uname', '-m')
+        if arch == 'aarch64':
+            arch = 'arm64'
         base = 'https://www.kernel.org/pub/tools/crosstool/files/bin'
-        versions = ['7.3.0', '6.4.0', '4.9.4']
+        versions = ['11.1.0', '9.2.0', '7.3.0', '6.4.0', '4.9.4']
         links = []
         for version in versions:
             url = '%s/%s/%s/' % (base, arch, version)
             print('Checking: %s' % url)
             response = urllib.request.urlopen(url)
-            html = tools.ToString(response.read())
+            html = tools.to_string(response.read())
             parser = MyHTMLParser(fetch_arch)
             parser.feed(html)
             if fetch_arch == 'list':
@@ -505,50 +515,6 @@ class Toolchains:
             return arch, links
         return None
 
-    def Download(self, url):
-        """Download a file to a temporary directory
-
-        Args:
-            url: URL to download
-        Returns:
-            Tuple:
-                Temporary directory name
-                Full path to the downloaded archive file in that directory,
-                    or None if there was an error while downloading
-        """
-        print('Downloading: %s' % url)
-        leaf = url.split('/')[-1]
-        tmpdir = tempfile.mkdtemp('.buildman')
-        response = urllib.request.urlopen(url)
-        fname = os.path.join(tmpdir, leaf)
-        fd = open(fname, 'wb')
-        meta = response.info()
-        size = int(meta.get('Content-Length'))
-        done = 0
-        block_size = 1 << 16
-        status = ''
-
-        # Read the file in chunks and show progress as we go
-        while True:
-            buffer = response.read(block_size)
-            if not buffer:
-                print(chr(8) * (len(status) + 1), '\r', end=' ')
-                break
-
-            done += len(buffer)
-            fd.write(buffer)
-            status = r'%10d MiB  [%3d%%]' % (done // 1024 // 1024,
-                                             done * 100 // size)
-            status = status + chr(8) * (len(status) + 1)
-            print(status, end=' ')
-            sys.stdout.flush()
-        fd.close()
-        if done != size:
-            print('Error, failed to download')
-            os.remove(fname)
-            fname = None
-        return tmpdir, fname
-
     def Unpack(self, fname, dest):
         """Unpack a tar file
 
@@ -559,7 +525,7 @@ class Toolchains:
             Directory name of the first entry in the archive, without the
             trailing /
         """
-        stdout = command.Output('tar', 'xvfJ', fname, '-C', dest)
+        stdout = command.output('tar', 'xvfJ', fname, '-C', dest)
         dirs = stdout.splitlines()[1].split('/')[:2]
         return '/'.join(dirs)
 
@@ -593,7 +559,7 @@ class Toolchains:
         """
         # Fist get the URL for this architecture
         col = terminal.Color()
-        print(col.Color(col.BLUE, "Downloading toolchain for arch '%s'" % arch))
+        print(col.build(col.BLUE, "Downloading toolchain for arch '%s'" % arch))
         url = self.LocateArchUrl(arch)
         if not url:
             print(("Cannot find toolchain for arch '%s' - use 'list' to list" %
@@ -605,10 +571,10 @@ class Toolchains:
             os.mkdir(dest)
 
         # Download the tar file for this toolchain and unpack it
-        tmpdir, tarfile = self.Download(url)
+        tarfile, tmpdir = tools.download(url, '.buildman')
         if not tarfile:
             return 1
-        print(col.Color(col.GREEN, 'Unpacking to: %s' % dest), end=' ')
+        print(col.build(col.GREEN, 'Unpacking to: %s' % dest), end=' ')
         sys.stdout.flush()
         path = self.Unpack(tarfile, dest)
         os.remove(tarfile)
@@ -616,14 +582,14 @@ class Toolchains:
         print()
 
         # Check that the toolchain works
-        print(col.Color(col.GREEN, 'Testing'))
+        print(col.build(col.GREEN, 'Testing'))
         dirpath = os.path.join(dest, path)
         compiler_fname_list = self.ScanPath(dirpath, True)
         if not compiler_fname_list:
             print('Could not locate C compiler - fetch failed.')
             return 1
         if len(compiler_fname_list) != 1:
-            print(col.Color(col.RED, 'Warning, ambiguous toolchains: %s' %
+            print(col.build(col.RED, 'Warning, ambiguous toolchains: %s' %
                             ', '.join(compiler_fname_list)))
         toolchain = Toolchain(compiler_fname_list[0], True, True)