Add patch for installing script package.py

This commit is contained in:
Michal Cyprian 2015-08-18 11:53:05 +02:00
parent b1bc7860fe
commit 324b4feca2
2 changed files with 13 additions and 366 deletions

View File

@ -1,366 +0,0 @@
#!/usr/bin/env python
""" packages PyPy, provided that it's already built.
It uses 'pypy/goal/pypy-c' and parts of the rest of the working
copy. Usage:
package.py [--options] pypy-VER-PLATFORM
The output is found in the directory from --builddir,
by default /tmp/usession-YOURNAME/build/.
"""
import shutil
import sys
import os
#Add toplevel repository dir to sys.path
basedir = os.path.dirname(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
sys.path.insert(0,basedir)
import py
import fnmatch
import subprocess
import glob
if sys.version_info < (2,6): py.test.skip("requires 2.6 so far")
USE_ZIPFILE_MODULE = sys.platform == 'win32'
STDLIB_VER = "2.7"
def ignore_patterns(*patterns):
"""Function that can be used as copytree() ignore parameter.
Patterns is a sequence of glob-style patterns
that are used to exclude files"""
def _ignore_patterns(path, names):
ignored_names = []
for pattern in patterns:
ignored_names.extend(fnmatch.filter(names, pattern))
return set(ignored_names)
return _ignore_patterns
class PyPyCNotFound(Exception):
pass
class MissingDependenciesError(Exception):
pass
def fix_permissions(dirname):
if sys.platform != 'win32':
os.system("chmod -R a+rX %s" % dirname)
os.system("chmod -R g-w %s" % dirname)
cffi_build_scripts = {
"sqlite3": "_sqlite3_build.py",
"audioop": "_audioop_build.py",
"tk": "_tkinter/tklib_build.py",
"curses": "_curses_build.py" if sys.platform != "win32" else None,
"syslog": "_syslog_build.py" if sys.platform != "win32" else None,
"gdbm": "_gdbm_build.py" if sys.platform != "win32" else None,
"pwdgrp": "_pwdgrp_build.py" if sys.platform != "win32" else None,
"xx": None, # for testing: 'None' should be completely ignored
}
def create_cffi_import_libraries(pypy_c, options, basedir):
shutil.rmtree(str(basedir.join('lib_pypy', '__pycache__')),
ignore_errors=True)
for key, module in sorted(cffi_build_scripts.items()):
if module is None or getattr(options, 'no_' + key):
continue
if module.endswith('.py'):
args = [str(pypy_c), module]
cwd = str(basedir.join('lib_pypy'))
else:
args = [str(pypy_c), '-c', 'import ' + module]
cwd = None
print >> sys.stderr, '*', ' '.join(args)
try:
subprocess.check_call(args, cwd=cwd)
except subprocess.CalledProcessError:
print >>sys.stderr, """!!!!!!!!!!\nBuilding {0} bindings failed.
You can either install development headers package,
add the --without-{0} option to skip packaging this
binary CFFI extension, or say --without-cffi.""".format(key)
raise MissingDependenciesError(module)
def pypy_runs(pypy_c, quiet=False):
kwds = {}
if quiet:
kwds['stderr'] = subprocess.PIPE
return subprocess.call([str(pypy_c), '-c', 'pass'], **kwds) == 0
def create_package(basedir, options, _fake=False):
retval = 0
name = options.name
if not name:
name = 'pypy-nightly'
rename_pypy_c = options.pypy_c
override_pypy_c = options.override_pypy_c
basedir = py.path.local(basedir)
if not override_pypy_c:
basename = 'pypy-c'
if sys.platform == 'win32':
basename += '.exe'
pypy_c = basedir.join('pypy', 'goal', basename)
else:
pypy_c = py.path.local(override_pypy_c)
if not _fake and not pypy_c.check():
raise PyPyCNotFound(
'Expected but did not find %s.'
' Please compile pypy first, using translate.py,'
' or check that you gave the correct path'
' with --override_pypy_c' % pypy_c)
if not _fake and not pypy_runs(pypy_c):
raise OSError("Running %r failed!" % (str(pypy_c),))
if not options.no_cffi:
try:
create_cffi_import_libraries(pypy_c, options, basedir)
except MissingDependenciesError:
return 1, None
if sys.platform == 'win32' and not rename_pypy_c.lower().endswith('.exe'):
rename_pypy_c += '.exe'
binaries = [(pypy_c, rename_pypy_c)]
if (sys.platform != 'win32' and # handled below
not _fake and os.path.getsize(str(pypy_c)) < 500000):
# This pypy-c is very small, so it means it relies on libpypy_c.so.
# If it would be bigger, it wouldn't. That's a hack.
libpypy_name = ('libpypy-c.so' if not sys.platform.startswith('darwin')
else 'libpypy-c.dylib')
libpypy_c = pypy_c.new(basename=libpypy_name)
if not libpypy_c.check():
raise PyPyCNotFound('Expected pypy to be mostly in %r, but did '
'not find it' % (str(libpypy_c),))
binaries.append((libpypy_c, libpypy_name))
#
builddir = py.path.local(options.builddir)
pypydir = builddir.ensure(name, dir=True)
includedir = basedir.join('include')
# Recursively copy all headers, shutil has only ignore
# so we do a double-negative to include what we want
def copyonly(dirpath, contents):
return set(contents) - set( # XXX function not used?
shutil.ignore_patterns('*.h', '*.incl')(dirpath, contents),
)
shutil.copytree(str(includedir), str(pypydir.join('include')))
pypydir.ensure('include', dir=True)
if sys.platform == 'win32':
src,tgt = binaries[0]
pypyw = src.new(purebasename=src.purebasename + 'w')
if pypyw.exists():
tgt = py.path.local(tgt)
binaries.append((pypyw, tgt.new(purebasename=tgt.purebasename + 'w').basename))
print "Picking %s" % str(pypyw)
# Can't rename a DLL: it is always called 'libpypy-c.dll'
win_extras = ['libpypy-c.dll', 'sqlite3.dll']
if not options.no_tk:
win_extras += ['tcl85.dll', 'tk85.dll']
for extra in win_extras:
p = pypy_c.dirpath().join(extra)
if not p.check():
p = py.path.local.sysfind(extra)
if not p:
print "%s not found, expect trouble if this is a shared build" % (extra,)
continue
print "Picking %s" % p
binaries.append((p, p.basename))
importlib_name = 'python27.lib'
if pypy_c.dirpath().join(importlib_name).check():
shutil.copyfile(str(pypy_c.dirpath().join(importlib_name)),
str(pypydir.join('include/python27.lib')))
print "Picking %s as %s" % (pypy_c.dirpath().join(importlib_name),
pypydir.join('include/python27.lib'))
else:
pass
# XXX users will complain that they cannot compile cpyext
# modules for windows, has the lib moved or are there no
# exported functions in the dll so no import library is created?
if not options.no_tk:
try:
p = pypy_c.dirpath().join('tcl85.dll')
if not p.check():
p = py.path.local.sysfind('tcl85.dll')
tktcldir = p.dirpath().join('..').join('lib')
shutil.copytree(str(tktcldir), str(pypydir.join('tcl')))
except WindowsError:
print >>sys.stderr, """Packaging Tk runtime failed.
tk85.dll and tcl85.dll found, expecting to find runtime in ..\\lib
directory next to the dlls, as per build instructions."""
import traceback;traceback.print_exc()
raise MissingDependenciesError('Tk runtime')
print '* Binaries:', [source.relto(str(basedir))
for source, target in binaries]
# Careful: to copy lib_pypy, copying just the hg-tracked files
# would not be enough: there are also ctypes_config_cache/_*_cache.py.
shutil.copytree(str(basedir.join('lib-python').join(STDLIB_VER)),
str(pypydir.join('lib-python').join(STDLIB_VER)),
ignore=ignore_patterns('.svn', 'py', '*.pyc', '*~'))
shutil.copytree(str(basedir.join('lib_pypy')),
str(pypydir.join('lib_pypy')),
ignore=ignore_patterns('.svn', 'py', '*.pyc', '*~',
'*.c', '*.o'))
for file in ['README.rst',]:
shutil.copy(str(basedir.join(file)), str(pypydir))
for file in ['_testcapimodule.c', '_ctypes_test.c']:
shutil.copyfile(str(basedir.join('lib_pypy', file)),
str(pypydir.join('lib_pypy', file)))
# Use original LICENCE file
base_file = str(basedir.join('LICENSE'))
with open(base_file) as fid:
license = fid.read()
with open(str(pypydir.join('LICENSE')), 'w') as LICENSE:
LICENSE.write(license)
#
spdir = pypydir.ensure('site-packages', dir=True)
shutil.copy(str(basedir.join('site-packages', 'README')), str(spdir))
#
if sys.platform == 'win32':
bindir = pypydir
else:
bindir = pypydir.join('bin')
bindir.ensure(dir=True)
for source, target in binaries:
archive = bindir.join(target)
if not _fake:
shutil.copy(str(source), str(archive))
else:
open(str(archive), 'wb').close()
os.chmod(str(archive), 0755)
fix_permissions(pypydir)
old_dir = os.getcwd()
try:
os.chdir(str(builddir))
if not options.nostrip:
for source, target in binaries:
if sys.platform == 'win32':
pass
elif sys.platform == 'darwin':
# 'strip' fun: see issue #587 for why -x
os.system("strip -x " + str(bindir.join(target))) # ignore errors
else:
os.system("strip " + str(bindir.join(target))) # ignore errors
#
if USE_ZIPFILE_MODULE:
import zipfile
archive = str(builddir.join(name + '.zip'))
zf = zipfile.ZipFile(archive, 'w',
compression=zipfile.ZIP_DEFLATED)
for (dirpath, dirnames, filenames) in os.walk(name):
for fnname in filenames:
filename = os.path.join(dirpath, fnname)
zf.write(filename)
zf.close()
else:
archive = str(builddir.join(name + '.tar.bz2'))
if sys.platform == 'darwin' or sys.platform.startswith('freebsd'):
print >>sys.stderr, """Warning: tar on current platform does not suport overriding the uid and gid
for its contents. The tarball will contain your uid and gid. If you are
building the actual release for the PyPy website, you may want to be
using another platform..."""
e = os.system('tar --numeric-owner -cvjf ' + archive + " " + name)
elif sys.platform == 'cygwin':
e = os.system('tar --owner=Administrator --group=Administrators --numeric-owner -cvjf ' + archive + " " + name)
else:
e = os.system('tar --owner=root --group=root --numeric-owner -cvjf ' + archive + " " + name)
if e:
raise OSError('"tar" returned exit status %r' % e)
finally:
os.chdir(old_dir)
if options.targetdir:
print "Copying %s to %s" % (archive, options.targetdir)
shutil.copy(archive, options.targetdir)
else:
print "Ready in %s" % (builddir,)
return retval, builddir # for tests
def package(*args, **kwds):
try:
import argparse
except ImportError:
import imp
argparse = imp.load_source('argparse', 'lib-python/2.7/argparse.py')
if sys.platform == 'win32':
pypy_exe = 'pypy.exe'
else:
pypy_exe = 'pypy'
parser = argparse.ArgumentParser()
args = list(args)
if args:
args[0] = str(args[0])
else:
args.append('--help')
for key, module in sorted(cffi_build_scripts.items()):
if module is not None:
parser.add_argument('--without-' + key,
dest='no_' + key,
action='store_true',
help='do not build and package the %r cffi module' % (key,))
parser.add_argument('--without-cffi', dest='no_cffi', action='store_true',
help='skip building *all* the cffi modules listed above')
parser.add_argument('--nostrip', dest='nostrip', action='store_true',
help='do not strip the exe, making it ~10MB larger')
parser.add_argument('--rename_pypy_c', dest='pypy_c', type=str, default=pypy_exe,
help='target executable name, defaults to "pypy"')
parser.add_argument('--archive-name', dest='name', type=str, default='',
help='pypy-VER-PLATFORM')
parser.add_argument('--builddir', type=str, default='',
help='tmp dir for packaging')
parser.add_argument('--targetdir', type=str, default='',
help='destination dir for archive')
parser.add_argument('--override_pypy_c', type=str, default='',
help='use as pypy exe instead of pypy/goal/pypy-c')
# Positional arguments, for backward compatability with buldbots
parser.add_argument('extra_args', help='optional interface to positional arguments', nargs=argparse.REMAINDER,
metavar='[archive-name] [rename_pypy_c] [targetdir] [override_pypy_c]',
)
options = parser.parse_args(args)
# Handle positional arguments, choke if both methods are used
for i,target, default in ([1, 'name', ''], [2, 'pypy_c', pypy_exe],
[3, 'targetdir', ''], [4,'override_pypy_c', '']):
if len(options.extra_args)>i:
if getattr(options, target) != default:
print 'positional argument',i,target,'already has value',getattr(options, target)
parser.print_help()
return
setattr(options, target, options.extra_args[i])
if os.environ.has_key("PYPY_PACKAGE_NOSTRIP"):
options.nostrip = True
if os.environ.has_key("PYPY_PACKAGE_WITHOUTTK"):
options.tk = True
if not options.builddir:
# The import actually creates the udir directory
from rpython.tool.udir import udir
options.builddir = udir.ensure("build", dir=True)
assert '/' not in options.pypy_c
return create_package(basedir, options, **kwds)
if __name__ == '__main__':
import sys
if sys.platform == 'win32':
# Try to avoid opeing a dialog box if one of the
# subprocesses causes a system error
import ctypes
winapi = ctypes.windll.kernel32
SetErrorMode = winapi.SetErrorMode
SetErrorMode.argtypes=[ctypes.c_int]
SEM_FAILCRITICALERRORS = 1
SEM_NOGPFAULTERRORBOX = 2
SEM_NOOPENFILEERRORBOX = 0x8000
flags = SEM_FAILCRITICALERRORS | SEM_NOGPFAULTERRORBOX | SEM_NOOPENFILEERRORBOX
#Since there is no GetErrorMode, do a double Set
old_mode = SetErrorMode(flags)
SetErrorMode(old_mode | flags)
retval, _ = package(*sys.argv[1:])
sys.exit(retval)

View File

@ -0,0 +1,13 @@
diff --git a/pypy/tool/release/package.py b/pypy/tool/release/package.py
index de6fdbd..4c0b6a2 100755
--- a/pypy/tool/release/package.py
+++ b/pypy/tool/release/package.py
@@ -135,7 +135,7 @@ def create_package(basedir, options, _fake=False):
'not find it' % (str(libpypy_c),))
binaries.append((libpypy_c, libpypy_name))
#
- builddir = options.builddir
+ builddir = py.path.local(options.builddir)
pypydir = builddir.ensure(name, dir=True)
includedir = basedir.join('include')
# Recursively copy all headers, shutil has only ignore