Ver código fonte

Add aarch64 to the update

Valentin Niess 7 meses atrás
pai
commit
f9b46b5e7f

+ 2 - 2
python_appimage/commands/build/manylinux.py

@@ -18,7 +18,7 @@ def _unpack_args(args):
     return args.tag, args.abi, args.bare, args.clean, args.no_packaging
 
 
-def execute(tag, abi, bare, clean, no_packaging):
+def execute(tag, abi, bare=False, clean=False, no_packaging=False):
     '''Build a Python AppImage using a Manylinux image
     '''
 
@@ -48,7 +48,7 @@ def execute(tag, abi, bare, clean, no_packaging):
             )
         elif bare:
             log('COMPRESS', fullname)
-            destination = f'{fullname}.tgz'
+            destination = f'{fullname}.tar.gz'
             tar_path = Path(tmpdir) / destination
             with tarfile.open(tar_path, "w:gz") as tar:
                 tar.add(appdir, arcname=fullname)

+ 5 - 1
python_appimage/manylinux/__init__.py

@@ -18,7 +18,11 @@ def ensure_image(tag, *, clean=False, extract=True):
     except ValueError:
         image_tag = 'latest'
 
-    tag, arch = tag.split('_', 1)
+    if tag.startswith('2_'):
+        tag, arch = tag[2:].split('_', 1)
+        tag = f'2_{tag}'
+    else:
+        tag, arch = tag.split('_', 1)
     tag = LinuxTag.from_brief(tag)
     arch = Arch.from_str(arch)
 

+ 36 - 20
python_appimage/manylinux/extract.py

@@ -77,9 +77,17 @@ class PythonExtractor:
         if self.arch in (Arch.AARCH64, Arch.X86_64):
             paths.append(self.prefix / 'lib64')
             paths.append(self.prefix / 'usr/lib64')
+            if self.arch == Arch.X86_64:
+                paths.append(self.prefix / 'lib/x86_64-linux-gnu')
+                paths.append(self.prefix / 'usr/lib/x86_64-linux-gnu')
+            else:
+                paths.append(self.prefix / 'lib/aarch64-linux-gnu')
+                paths.append(self.prefix / 'usr/lib/aarch64-linux-gnu')
         elif self.arch == Arch.I686:
             paths.append(self.prefix / 'lib')
             paths.append(self.prefix / 'usr/lib')
+            paths.append(self.prefix / 'lib/i386-linux-gnu')
+            paths.append(self.prefix / 'usr/lib/i386-linux-gnu')
         else:
             raise NotImplementedError()
         paths.append(self.prefix / 'usr/local/lib')
@@ -100,12 +108,13 @@ class PythonExtractor:
         else:
             ensure_excludelist()
             excludelist = Path(EXCLUDELIST)
-        excluded = []
+        excluded = set()
         with excludelist.open() as f:
             for line in f:
                 line = line.strip()
                 if line and not line.startswith('#'):
-                    excluded.append(line)
+                    excluded.add(line)
+        excluded.add('ld-linux-aarch64.so.1')  # patch for aarch64.
         object.__setattr__(self, 'excluded', excluded)
 
         # Set patchelf, if not provided.
@@ -248,24 +257,31 @@ class PythonExtractor:
 
         # Copy Tcl & Tk data.
         tx_version = []
-        for location in ('usr/local/lib', 'usr/share'):
-            tcltk_src = self.prefix / location
-            for match in glob.glob(str(tcltk_src / 'tk*')):
-                path = Path(match)
-                if path.is_dir():
-                    tx_version.append(LooseVersion(path.name[2:]))
-        tx_version.sort()
-        tx_version = tx_version[-1]
-
-        log('INSTALL', f'Tcl/Tk{tx_version}')
-        tcltk_dir = Path(system_dest / 'share/tcltk')
-        tcltk_dir.mkdir(exist_ok=True, parents=True)
-
-        for tx in ('tcl', 'tk'):
-            name = f'{tx}{tx_version}'
-            src = tcltk_src / name
-            dst = tcltk_dir / name
-            shutil.copytree(src, dst, symlinks=True, dirs_exist_ok=True)
+        for match in glob.glob(str(system_dest / 'lib/libtk*')):
+            path = system_dest / f'lib/{match}'
+            tx_version.append(LooseVersion(path.name[5:8]))
+
+        if tx_version:
+            tx_version.sort()
+            tx_version = tx_version[-1]
+
+            for location in ('usr/local/lib', 'usr/share', 'usr/share/tcltk'):
+                tcltk_src = self.prefix / location
+                path = tcltk_src / f'tk{tx_version}'
+                if path.exists() and path.is_dir():
+                    break
+            else:
+                raise ValueError(f'could not locate Tcl/Tk{tx_version}')
+
+            log('INSTALL', f'Tcl/Tk{tx_version}')
+            tcltk_dir = Path(system_dest / 'share/tcltk')
+            tcltk_dir.mkdir(exist_ok=True, parents=True)
+
+            for tx in ('tcl', 'tk'):
+                name = f'{tx}{tx_version}'
+                src = tcltk_src / name
+                dst = tcltk_dir / name
+                shutil.copytree(src, dst, symlinks=True, dirs_exist_ok=True)
 
         if appify:
             appifier = Appifier(

+ 2 - 2
python_appimage/manylinux/patch.py

@@ -29,7 +29,7 @@ class Patcher:
             patch = f'tk-manylinux1_{self.arch}'
             log('PATCH', patch)
             tarfile = f'{patch}.tar.gz'
-            path = cache / patch
+            path = cache / tarfile
             if not path.exists():
                 url = f'https://github.com/niess/python-appimage/releases/download/manylinux1/{tarfile}'
                 urlretrieve(url, path)
@@ -40,7 +40,7 @@ class Patcher:
             cmd = ''.join((
                  f'trap \'chmod u+rw -R {destination}\' EXIT ; ',
                  f'mkdir -p {destination} && ',
-                 f'tar -xzf {tarfile} -C {destination}',
+                 f'tar -xzf {path} -C {destination}',
             ))
             r = subprocess.run(f'/bin/bash -c "{cmd}"', shell=True,
                                capture_output=True)

+ 14 - 0
python_appimage/utils/manylinux.py

@@ -0,0 +1,14 @@
+def format_appimage_name(abi, version, tag):
+    '''Format the Python AppImage name using the ABI, python version and OS tags
+    '''
+    return 'python{:}-{:}-{:}.AppImage'.format(
+        version, abi, format_tag(tag))
+
+
+def format_tag(tag):
+    '''Format Manylinux tag
+    '''
+    if tag.startswith('2_'):
+        return 'manylinux_' + tag
+    else:
+        return 'manylinux' + tag

+ 17 - 6
scripts/test-appimage.py

@@ -81,7 +81,10 @@ import os
 appdir = os.environ['APPDIR']
 env = {}
 for var in ('SSL_CERT_FILE', 'TCL_LIBRARY', 'TK_LIBRARY', 'TKPATH'):
-    env[var] = os.environ[var].replace(appdir, '$APPDIR')
+    try:
+        env[var] = os.environ[var].replace(appdir, '$APPDIR')
+    except KeyError:
+        pass
 print(env)
         ''').run(appimage))
 
@@ -149,7 +152,11 @@ print(env)
             content
         )
         content = self.list_content(f'{prefix}/include')
-        assert_eq([f'python{self.version.flavoured()}'], content)
+        if (self.version.major == 3) and (self.version.minor <= 7):
+            expected = [f'python{self.version.short()}m']
+        else:
+            expected = [f'python{self.version.flavoured()}']
+        assert_eq(expected, content)
         content = self.list_content(f'{prefix}/lib')
         assert_eq([f'python{self.version.flavoured()}'], content)
         return Status.SUCCESS
@@ -171,10 +178,13 @@ print(env)
     def test_tcltk_bundling(self):
         '''Check Tcl/Tk bundling'''
 
-        for var in ('TCL_LIBRARY', 'TK_LIBRARY', 'TKPATH'):
-            path = Path(self.env[var].replace('$APPDIR', str(self.appdir)))
-            assert path.exists()
-        return Status.SUCCESS
+        if 'TK_LIBRARY' not in self.env:
+            return Status.SKIPPED
+        else:
+            for var in ('TCL_LIBRARY', 'TK_LIBRARY', 'TKPATH'):
+                path = Path(self.env[var].replace('$APPDIR', str(self.appdir)))
+                assert path.exists()
+            return Status.SUCCESS
 
     def test_ssl_bundling(self):
         '''Check SSL certs bundling'''
@@ -262,6 +272,7 @@ with urllib.request.urlopen('https://wikipedia.org') as r:
 
         try:
             os.environ['DISPLAY']
+            self.env['TK_LIBRARY']
         except KeyError:
             return Status.SKIPPED
         else:

+ 12 - 3
scripts/update-appimages.py

@@ -16,9 +16,9 @@ from python_appimage.utils.manylinux import format_appimage_name, format_tag
 
 
 # Build matrix
-ARCHS = ('x86_64', 'i686')
+ARCHS = ('x86_64', 'i686', 'aarch64')
 MANYLINUSES = ('1', '2010', '2014', '2_24', '2_28')
-EXCLUDES = ('2_28_i686',)
+EXCLUDES = ('2_28_i686', '1_aarch64', '2010_aarch64')
 
 # Build directory for AppImages
 APPIMAGES_DIR = 'build-appimages'
@@ -202,7 +202,8 @@ def update(args):
         if new_assets:
             log('DRY', f'new update summary with {len(new_assets)} entries')
 
-        return
+        if not args.build:
+            return
 
     if new_assets:
         # Build new AppImage(s)
@@ -215,6 +216,9 @@ def update(args):
         finally:
             os.chdir(cwd)
 
+    if args.dry:
+        return
+
     # Create any new release(s).
     for tag in new_releases:
         meta = ReleaseMeta(tag)
@@ -305,6 +309,11 @@ if __name__ == '__main__':
         action = 'store_true',
         default = False
     )
+    parser.add_argument('-b', '--build',
+        help = 'build AppImages (in dry mode)',
+        action = 'store_true',
+        default = False
+    )
     parser.add_argument('-d', '--dry',
         help = 'dry run (only log changes)',
         action = 'store_true',