manylinux.py 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. import glob
  2. import os
  3. import platform
  4. import shutil
  5. import sys
  6. from ...appimage import build_appimage, relocate_python
  7. from ...utils.docker import docker_run
  8. from ...utils.fs import copy_tree
  9. from ...utils.tmp import TemporaryDirectory
  10. __all__ = ['execute']
  11. def _unpack_args(args):
  12. '''Unpack command line arguments
  13. '''
  14. return args.tag, args.abi, args.contained
  15. def _get_appimage_name(abi, tag):
  16. '''Format the Python AppImage name using the ABI and OS tags
  17. '''
  18. # Read the Python version from the desktop file
  19. desktop = glob.glob('AppDir/python*.desktop')[0]
  20. fullversion = desktop[13:-8]
  21. # Finish building the AppImage on the host. See below.
  22. return 'python{:}-{:}-manylinux{:}.AppImage'.format(
  23. fullversion, abi, tag)
  24. def execute(tag, abi, contained=False):
  25. '''Build a Python AppImage using a manylinux docker image
  26. '''
  27. if not contained:
  28. # Forward the build to a Docker image
  29. image = 'quay.io/pypa/manylinux' + tag
  30. python = '/opt/python/' + abi + '/bin/python'
  31. pwd = os.getcwd()
  32. dirname = os.path.abspath(os.path.dirname(__file__) + '/../..')
  33. with TemporaryDirectory() as tmpdir:
  34. copy_tree(dirname, 'python_appimage')
  35. argv = ' '.join(sys.argv[1:])
  36. if tag.startswith("1_"):
  37. # On manylinux1 tk is not installed
  38. script = [
  39. 'yum --disablerepo="*" --enablerepo=base install -q -y tk']
  40. else:
  41. # tk is already installed on other platforms
  42. script = []
  43. script += [
  44. python + ' -m python_appimage ' + argv + ' --contained',
  45. ''
  46. ]
  47. docker_run(image, script)
  48. appimage_name = _get_appimage_name(abi, tag)
  49. if tag.startswith('1_') or tag.startswith('2010_'):
  50. # appimagetool does not run on manylinux1 (CentOS 5) or
  51. # manylinux2010 (CentOS 6). Below is a patch for these specific
  52. # cases.
  53. arch = tag.split('_', 1)[-1]
  54. if arch == platform.machine():
  55. # Pack the image directly from the host
  56. build_appimage(destination=appimage_name)
  57. else:
  58. # Use a manylinux2014 Docker image (CentOS 7) in order to
  59. # pack the image.
  60. script = (
  61. 'python -m python_appimage ' + argv + ' --contained',
  62. ''
  63. )
  64. docker_run('quay.io/pypa/manylinux2014_' + arch, script)
  65. shutil.move(appimage_name, os.path.join(pwd, appimage_name))
  66. else:
  67. # We are running within a manylinux Docker image
  68. is_manylinux_old = tag.startswith('1_') or tag.startswith('2010_')
  69. if not os.path.exists('AppDir'):
  70. # Relocate the targeted manylinux Python installation
  71. relocate_python()
  72. else:
  73. # This is a second stage build. The Docker image has actually been
  74. # overriden (see above).
  75. is_manylinux_old = False
  76. if is_manylinux_old:
  77. # Build only the AppDir when running within a manylinux1 Docker
  78. # image because appimagetool does not support CentOS 5 or CentOS 6.
  79. pass
  80. else:
  81. build_appimage(destination=_get_appimage_name(abi, tag))