manylinux.py 3.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. script = (
  37. 'yum --disablerepo="*" --enablerepo=base install -q -y tk',
  38. python + ' -m python_appimage ' + argv + ' --contained',
  39. ''
  40. )
  41. docker_run(image, script)
  42. appimage_name = _get_appimage_name(abi, tag)
  43. if tag.startswith('1_') or tag.startswith('2010_'):
  44. # appimagetool does not run on manylinux1 (CentOS 5) or
  45. # manylinux2010 (CentOS 6). Below is a patch for these specific
  46. # cases.
  47. arch = tag.split('_', 1)[-1]
  48. if arch == platform.machine():
  49. # Pack the image directly from the host
  50. build_appimage(destination=appimage_name)
  51. else:
  52. # Use a manylinux2014 Docker image (CentOS 7) in order to
  53. # pack the image.
  54. script = (
  55. 'python -m python_appimage ' + argv + ' --contained',
  56. ''
  57. )
  58. docker_run('quay.io/pypa/manylinux2014_' + arch, script)
  59. shutil.move(appimage_name, os.path.join(pwd, appimage_name))
  60. else:
  61. # We are running within a manylinux Docker image
  62. is_manylinux_old = tag.startswith('1_') or tag.startswith('2010_')
  63. if not os.path.exists('AppDir'):
  64. # Relocate the targeted manylinux Python installation
  65. relocate_python()
  66. else:
  67. # This is a second stage build. The Docker image has actually been
  68. # overriden (see above).
  69. is_manylinux_old = False
  70. if is_manylinux_old:
  71. # Build only the AppDir when running within a manylinux1 Docker
  72. # image because appimagetool does not support CentOS 5 or CentOS 6.
  73. pass
  74. else:
  75. build_appimage(destination=_get_appimage_name(abi, tag))