manylinux.py 3.5 KB

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