We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
Update to Python 3.7
Python 3.7 is out.

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `tools/common.py`
Content:
```
1 from pathlib import Path
2 
3 
4 ROOTDIR = Path(__file__).parent.resolve()
5 HOSTPYTHON = ROOTDIR / '..' / 'cpython' / 'build' / '3.6.4' / 'host'
6 TARGETPYTHON = ROOTDIR / '..' / 'cpython' / 'installs' / 'python-3.6.4'
7 DEFAULTCFLAGS = ''
8 DEFAULTLDFLAGS = ' '.join([
9     '-O3',
10     '-s', "BINARYEN_METHOD='native-wasm'",
11     '-Werror',
12     '-s', 'EMULATED_FUNCTION_POINTERS=1',
13     '-s', 'EMULATE_FUNCTION_POINTER_CASTS=1',
14     '-s', 'SIDE_MODULE=1',
15     '-s', 'WASM=1',
16     '--memory-init-file', '0'
17     ])
18 
19 
20 def parse_package(package):
21     # Import yaml here because pywasmcross needs to run in the built native
22     # Python, which won't have PyYAML
23     import yaml
24     # TODO: Validate against a schema
25     with open(package) as fd:
26         return yaml.load(fd)
27
```

Path: `tools/buildpkg.py`
Content:
```
1 #!/usr/bin/env python3
2 
3 """
4 Builds a Pyodide package.
5 """
6 
7 import argparse
8 import hashlib
9 import os
10 from pathlib import Path
11 import shutil
12 import subprocess
13 
14 
15 import common
16 
17 
18 ROOTDIR = Path(__file__).parent.resolve()
19 
20 
21 def check_checksum(path, pkg):
22     """
23     Checks that a tarball matches the checksum in the package metadata.
24     """
25     checksum_keys = {'md5', 'sha256'}.intersection(pkg['source'])
26     if not checksum_keys:
27         return
28     elif len(checksum_keys) != 1:
29         raise ValueError('Only one checksum should be included in a package '
30                          'setup; found {}.'.format(checksum_keys))
31     checksum_algorithm = checksum_keys.pop()
32     checksum = pkg['source'][checksum_algorithm]
33     CHUNK_SIZE = 1 << 16
34     h = getattr(hashlib, checksum_algorithm)()
35     with open(path, 'rb') as fd:
36         while True:
37             chunk = fd.read(CHUNK_SIZE)
38             h.update(chunk)
39             if len(chunk) < CHUNK_SIZE:
40                 break
41     if h.hexdigest() != checksum:
42         raise ValueError("Invalid {} checksum".format(checksum_algorithm))
43 
44 
45 def download_and_extract(buildpath, packagedir, pkg, args):
46     tarballpath = buildpath / Path(pkg['source']['url']).name
47     if not tarballpath.is_file():
48         subprocess.run([
49             'wget', '-q', '-O', str(tarballpath), pkg['source']['url']
50         ], check=True)
51         check_checksum(tarballpath, pkg)
52     srcpath = buildpath / packagedir
53     if not srcpath.is_dir():
54         shutil.unpack_archive(str(tarballpath), str(buildpath))
55     return srcpath
56 
57 
58 def patch(path, srcpath, pkg, args):
59     if (srcpath / '.patched').is_file():
60         return
61 
62     # Apply all of the patches
63     orig_dir = Path.cwd()
64     pkgdir = path.parent.resolve()
65     os.chdir(srcpath)
66     try:
67         for patch in pkg['source'].get('patches', []):
68             subprocess.run([
69                 'patch', '-p1', '--binary', '-i', pkgdir / patch
70             ], check=True)
71     finally:
72         os.chdir(orig_dir)
73 
74     # Add any extra files
75     for src, dst in pkg['source'].get('extras', []):
76         shutil.copyfile(pkgdir / src, srcpath / dst)
77 
78     with open(srcpath / '.patched', 'wb') as fd:
79         fd.write(b'\n')
80 
81 
82 def get_libdir(srcpath, args):
83     # Get the name of the build/lib.XXX directory that distutils wrote its
84     # output to
85     slug = subprocess.check_output([
86         str(Path(args.host) / 'bin' / 'python3'),
87         '-c',
88         'import sysconfig, sys; '
89         'print("{}-{}.{}".format('
90         'sysconfig.get_platform(), '
91         'sys.version_info[0], '
92         'sys.version_info[1]))']).decode('ascii').strip()
93     purelib = srcpath / 'build' / 'lib'
94     if purelib.is_dir():
95         libdir = purelib
96     else:
97         libdir = srcpath / 'build' / ('lib.' + slug)
98     return libdir
99 
100 
101 def compile(path, srcpath, pkg, args):
102     if (srcpath / '.built').is_file():
103         return
104 
105     orig_dir = Path.cwd()
106     os.chdir(srcpath)
107     try:
108         subprocess.run([
109             str(Path(args.host) / 'bin' / 'python3'),
110             str(ROOTDIR / 'pywasmcross'),
111             '--cflags',
112             args.cflags + ' ' +
113             pkg.get('build', {}).get('cflags', ''),
114             '--ldflags',
115             args.ldflags + ' ' +
116             pkg.get('build', {}).get('ldflags', ''),
117             '--host', args.host,
118             '--target', args.target], check=True)
119     finally:
120         os.chdir(orig_dir)
121 
122     post = pkg.get('build', {}).get('post')
123     if post is not None:
124         libdir = get_libdir(srcpath, args)
125         pkgdir = path.parent.resolve()
126         env = {
127             'BUILD': libdir,
128             'PKGDIR': pkgdir
129         }
130         subprocess.run([
131             'bash', '-c', post], env=env, check=True)
132 
133     with open(srcpath / '.built', 'wb') as fd:
134         fd.write(b'\n')
135 
136 
137 def package_files(buildpath, srcpath, pkg, args):
138     if (buildpath / '.packaged').is_file():
139         return
140 
141     name = pkg['package']['name']
142     install_prefix = (srcpath / 'install').resolve()
143     subprocess.run([
144         'python',
145         Path(os.environ['EMSCRIPTEN']) / 'tools' / 'file_packager.py',
146         name + '.data',
147         '--preload',
148         '{}@/'.format(install_prefix),
149         '--js-output={}'.format(name + '.js'),
150         '--export-name=pyodide',
151         '--exclude', '*.wasm.pre',
152         '--exclude', '__pycache__',
153         '--use-preload-plugins'],
154         cwd=buildpath, check=True)
155     subprocess.run([
156         'uglifyjs',
157         buildpath / (name + '.js'),
158         '-o',
159         buildpath / (name + '.js')], check=True)
160 
161     with open(buildpath / '.packaged', 'wb') as fd:
162         fd.write(b'\n')
163 
164 
165 def build_package(path, args):
166     pkg = common.parse_package(path)
167     packagedir = pkg['package']['name'] + '-' + pkg['package']['version']
168     dirpath = path.parent
169     orig_path = Path.cwd()
170     os.chdir(dirpath)
171     try:
172         buildpath = dirpath / 'build'
173         if not buildpath.is_dir():
174             os.makedirs(buildpath)
175         srcpath = download_and_extract(buildpath, packagedir, pkg, args)
176         patch(path, srcpath, pkg, args)
177         compile(path, srcpath, pkg, args)
178         package_files(buildpath, srcpath, pkg, args)
179     finally:
180         os.chdir(orig_path)
181 
182 
183 def parse_args():
184     parser = argparse.ArgumentParser('Build a pyodide package.')
185     parser.add_argument(
186         'package', type=str, nargs=1,
187         help="Path to meta.yaml package description")
188     parser.add_argument(
189         '--cflags', type=str, nargs='?', default=common.DEFAULTCFLAGS,
190         help='Extra compiling flags')
191     parser.add_argument(
192         '--ldflags', type=str, nargs='?', default=common.DEFAULTLDFLAGS,
193         help='Extra linking flags')
194     parser.add_argument(
195         '--host', type=str, nargs='?', default=common.HOSTPYTHON,
196         help='The path to the host Python installation')
197     parser.add_argument(
198         '--target', type=str, nargs='?', default=common.TARGETPYTHON,
199         help='The path to the target Python installation')
200     return parser.parse_args()
201 
202 
203 def main(args):
204     path = Path(args.package[0]).resolve()
205     build_package(path, args)
206 
207 
208 if __name__ == '__main__':
209     args = parse_args()
210     main(args)
211
```
--- END FILES ---

Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.

Here is an example:

```diff
diff --git a/examples/server_async.py b/examples/server_async.py
--- a/examples/server_async.py
+++ b/examples/server_async.py
@@ -313,4 +313,4 @@
 
 
 if __name__ == "__main__":
-    asyncio.run(run_async_server("."), debug=True)
+    asyncio.run(run_async_server(), debug=True)
diff --git a/examples/server_sync.py b/examples/server_sync.py
--- a/examples/server_sync.py
+++ b/examples/server_sync.py
@@ -313,5 +313,5 @@
 
 
 if __name__ == "__main__":
-    server = run_sync_server(".")
+    server = run_sync_server()
     server.shutdown()

```

diff --git a/tools/buildpkg.py b/tools/buildpkg.py
--- a/tools/buildpkg.py
+++ b/tools/buildpkg.py
@@ -79,25 +79,6 @@
         fd.write(b'\n')
 
 
-def get_libdir(srcpath, args):
-    # Get the name of the build/lib.XXX directory that distutils wrote its
-    # output to
-    slug = subprocess.check_output([
-        str(Path(args.host) / 'bin' / 'python3'),
-        '-c',
-        'import sysconfig, sys; '
-        'print("{}-{}.{}".format('
-        'sysconfig.get_platform(), '
-        'sys.version_info[0], '
-        'sys.version_info[1]))']).decode('ascii').strip()
-    purelib = srcpath / 'build' / 'lib'
-    if purelib.is_dir():
-        libdir = purelib
-    else:
-        libdir = srcpath / 'build' / ('lib.' + slug)
-    return libdir
-
-
 def compile(path, srcpath, pkg, args):
     if (srcpath / '.built').is_file():
         return
@@ -121,10 +102,11 @@
 
     post = pkg.get('build', {}).get('post')
     if post is not None:
-        libdir = get_libdir(srcpath, args)
+        site_packages_dir = (
+            srcpath / 'install' / 'lib' / 'python3.7' / 'site-packages')
         pkgdir = path.parent.resolve()
         env = {
-            'BUILD': libdir,
+            'SITEPACKAGES': site_packages_dir,
             'PKGDIR': pkgdir
         }
         subprocess.run([
diff --git a/tools/common.py b/tools/common.py
--- a/tools/common.py
+++ b/tools/common.py
@@ -2,8 +2,8 @@
 
 
 ROOTDIR = Path(__file__).parent.resolve()
-HOSTPYTHON = ROOTDIR / '..' / 'cpython' / 'build' / '3.6.4' / 'host'
-TARGETPYTHON = ROOTDIR / '..' / 'cpython' / 'installs' / 'python-3.6.4'
+HOSTPYTHON = ROOTDIR / '..' / 'cpython' / 'build' / '3.7.0' / 'host'
+TARGETPYTHON = ROOTDIR / '..' / 'cpython' / 'installs' / 'python-3.7.0'
 DEFAULTCFLAGS = ''
 DEFAULTLDFLAGS = ' '.join([
     '-O3',

{"golden_diff": "diff --git a/tools/buildpkg.py b/tools/buildpkg.py\n--- a/tools/buildpkg.py\n+++ b/tools/buildpkg.py\n@@ -79,25 +79,6 @@\n         fd.write(b'\\n')\n \n \n-def get_libdir(srcpath, args):\n-    # Get the name of the build/lib.XXX directory that distutils wrote its\n-    # output to\n-    slug = subprocess.check_output([\n-        str(Path(args.host) / 'bin' / 'python3'),\n-        '-c',\n-        'import sysconfig, sys; '\n-        'print(\"{}-{}.{}\".format('\n-        'sysconfig.get_platform(), '\n-        'sys.version_info[0], '\n-        'sys.version_info[1]))']).decode('ascii').strip()\n-    purelib = srcpath / 'build' / 'lib'\n-    if purelib.is_dir():\n-        libdir = purelib\n-    else:\n-        libdir = srcpath / 'build' / ('lib.' + slug)\n-    return libdir\n-\n-\n def compile(path, srcpath, pkg, args):\n     if (srcpath / '.built').is_file():\n         return\n@@ -121,10 +102,11 @@\n \n     post = pkg.get('build', {}).get('post')\n     if post is not None:\n-        libdir = get_libdir(srcpath, args)\n+        site_packages_dir = (\n+            srcpath / 'install' / 'lib' / 'python3.7' / 'site-packages')\n         pkgdir = path.parent.resolve()\n         env = {\n-            'BUILD': libdir,\n+            'SITEPACKAGES': site_packages_dir,\n             'PKGDIR': pkgdir\n         }\n         subprocess.run([\ndiff --git a/tools/common.py b/tools/common.py\n--- a/tools/common.py\n+++ b/tools/common.py\n@@ -2,8 +2,8 @@\n \n \n ROOTDIR = Path(__file__).parent.resolve()\n-HOSTPYTHON = ROOTDIR / '..' / 'cpython' / 'build' / '3.6.4' / 'host'\n-TARGETPYTHON = ROOTDIR / '..' / 'cpython' / 'installs' / 'python-3.6.4'\n+HOSTPYTHON = ROOTDIR / '..' / 'cpython' / 'build' / '3.7.0' / 'host'\n+TARGETPYTHON = ROOTDIR / '..' / 'cpython' / 'installs' / 'python-3.7.0'\n DEFAULTCFLAGS = ''\n DEFAULTLDFLAGS = ' '.join([\n     '-O3',\n", "issue": "Update to Python 3.7\nPython 3.7 is out.\n", "before_files": [{"content": "from pathlib import Path\n\n\nROOTDIR = Path(__file__).parent.resolve()\nHOSTPYTHON = ROOTDIR / '..' / 'cpython' / 'build' / '3.6.4' / 'host'\nTARGETPYTHON = ROOTDIR / '..' / 'cpython' / 'installs' / 'python-3.6.4'\nDEFAULTCFLAGS = ''\nDEFAULTLDFLAGS = ' '.join([\n    '-O3',\n    '-s', \"BINARYEN_METHOD='native-wasm'\",\n    '-Werror',\n    '-s', 'EMULATED_FUNCTION_POINTERS=1',\n    '-s', 'EMULATE_FUNCTION_POINTER_CASTS=1',\n    '-s', 'SIDE_MODULE=1',\n    '-s', 'WASM=1',\n    '--memory-init-file', '0'\n    ])\n\n\ndef parse_package(package):\n    # Import yaml here because pywasmcross needs to run in the built native\n    # Python, which won't have PyYAML\n    import yaml\n    # TODO: Validate against a schema\n    with open(package) as fd:\n        return yaml.load(fd)\n", "path": "tools/common.py"}, {"content": "#!/usr/bin/env python3\n\n\"\"\"\nBuilds a Pyodide package.\n\"\"\"\n\nimport argparse\nimport hashlib\nimport os\nfrom pathlib import Path\nimport shutil\nimport subprocess\n\n\nimport common\n\n\nROOTDIR = Path(__file__).parent.resolve()\n\n\ndef check_checksum(path, pkg):\n    \"\"\"\n    Checks that a tarball matches the checksum in the package metadata.\n    \"\"\"\n    checksum_keys = {'md5', 'sha256'}.intersection(pkg['source'])\n    if not checksum_keys:\n        return\n    elif len(checksum_keys) != 1:\n        raise ValueError('Only one checksum should be included in a package '\n                         'setup; found {}.'.format(checksum_keys))\n    checksum_algorithm = checksum_keys.pop()\n    checksum = pkg['source'][checksum_algorithm]\n    CHUNK_SIZE = 1 << 16\n    h = getattr(hashlib, checksum_algorithm)()\n    with open(path, 'rb') as fd:\n        while True:\n            chunk = fd.read(CHUNK_SIZE)\n            h.update(chunk)\n            if len(chunk) < CHUNK_SIZE:\n                break\n    if h.hexdigest() != checksum:\n        raise ValueError(\"Invalid {} checksum\".format(checksum_algorithm))\n\n\ndef download_and_extract(buildpath, packagedir, pkg, args):\n    tarballpath = buildpath / Path(pkg['source']['url']).name\n    if not tarballpath.is_file():\n        subprocess.run([\n            'wget', '-q', '-O', str(tarballpath), pkg['source']['url']\n        ], check=True)\n        check_checksum(tarballpath, pkg)\n    srcpath = buildpath / packagedir\n    if not srcpath.is_dir():\n        shutil.unpack_archive(str(tarballpath), str(buildpath))\n    return srcpath\n\n\ndef patch(path, srcpath, pkg, args):\n    if (srcpath / '.patched').is_file():\n        return\n\n    # Apply all of the patches\n    orig_dir = Path.cwd()\n    pkgdir = path.parent.resolve()\n    os.chdir(srcpath)\n    try:\n        for patch in pkg['source'].get('patches', []):\n            subprocess.run([\n                'patch', '-p1', '--binary', '-i', pkgdir / patch\n            ], check=True)\n    finally:\n        os.chdir(orig_dir)\n\n    # Add any extra files\n    for src, dst in pkg['source'].get('extras', []):\n        shutil.copyfile(pkgdir / src, srcpath / dst)\n\n    with open(srcpath / '.patched', 'wb') as fd:\n        fd.write(b'\\n')\n\n\ndef get_libdir(srcpath, args):\n    # Get the name of the build/lib.XXX directory that distutils wrote its\n    # output to\n    slug = subprocess.check_output([\n        str(Path(args.host) / 'bin' / 'python3'),\n        '-c',\n        'import sysconfig, sys; '\n        'print(\"{}-{}.{}\".format('\n        'sysconfig.get_platform(), '\n        'sys.version_info[0], '\n        'sys.version_info[1]))']).decode('ascii').strip()\n    purelib = srcpath / 'build' / 'lib'\n    if purelib.is_dir():\n        libdir = purelib\n    else:\n        libdir = srcpath / 'build' / ('lib.' + slug)\n    return libdir\n\n\ndef compile(path, srcpath, pkg, args):\n    if (srcpath / '.built').is_file():\n        return\n\n    orig_dir = Path.cwd()\n    os.chdir(srcpath)\n    try:\n        subprocess.run([\n            str(Path(args.host) / 'bin' / 'python3'),\n            str(ROOTDIR / 'pywasmcross'),\n            '--cflags',\n            args.cflags + ' ' +\n            pkg.get('build', {}).get('cflags', ''),\n            '--ldflags',\n            args.ldflags + ' ' +\n            pkg.get('build', {}).get('ldflags', ''),\n            '--host', args.host,\n            '--target', args.target], check=True)\n    finally:\n        os.chdir(orig_dir)\n\n    post = pkg.get('build', {}).get('post')\n    if post is not None:\n        libdir = get_libdir(srcpath, args)\n        pkgdir = path.parent.resolve()\n        env = {\n            'BUILD': libdir,\n            'PKGDIR': pkgdir\n        }\n        subprocess.run([\n            'bash', '-c', post], env=env, check=True)\n\n    with open(srcpath / '.built', 'wb') as fd:\n        fd.write(b'\\n')\n\n\ndef package_files(buildpath, srcpath, pkg, args):\n    if (buildpath / '.packaged').is_file():\n        return\n\n    name = pkg['package']['name']\n    install_prefix = (srcpath / 'install').resolve()\n    subprocess.run([\n        'python',\n        Path(os.environ['EMSCRIPTEN']) / 'tools' / 'file_packager.py',\n        name + '.data',\n        '--preload',\n        '{}@/'.format(install_prefix),\n        '--js-output={}'.format(name + '.js'),\n        '--export-name=pyodide',\n        '--exclude', '*.wasm.pre',\n        '--exclude', '__pycache__',\n        '--use-preload-plugins'],\n        cwd=buildpath, check=True)\n    subprocess.run([\n        'uglifyjs',\n        buildpath / (name + '.js'),\n        '-o',\n        buildpath / (name + '.js')], check=True)\n\n    with open(buildpath / '.packaged', 'wb') as fd:\n        fd.write(b'\\n')\n\n\ndef build_package(path, args):\n    pkg = common.parse_package(path)\n    packagedir = pkg['package']['name'] + '-' + pkg['package']['version']\n    dirpath = path.parent\n    orig_path = Path.cwd()\n    os.chdir(dirpath)\n    try:\n        buildpath = dirpath / 'build'\n        if not buildpath.is_dir():\n            os.makedirs(buildpath)\n        srcpath = download_and_extract(buildpath, packagedir, pkg, args)\n        patch(path, srcpath, pkg, args)\n        compile(path, srcpath, pkg, args)\n        package_files(buildpath, srcpath, pkg, args)\n    finally:\n        os.chdir(orig_path)\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser('Build a pyodide package.')\n    parser.add_argument(\n        'package', type=str, nargs=1,\n        help=\"Path to meta.yaml package description\")\n    parser.add_argument(\n        '--cflags', type=str, nargs='?', default=common.DEFAULTCFLAGS,\n        help='Extra compiling flags')\n    parser.add_argument(\n        '--ldflags', type=str, nargs='?', default=common.DEFAULTLDFLAGS,\n        help='Extra linking flags')\n    parser.add_argument(\n        '--host', type=str, nargs='?', default=common.HOSTPYTHON,\n        help='The path to the host Python installation')\n    parser.add_argument(\n        '--target', type=str, nargs='?', default=common.TARGETPYTHON,\n        help='The path to the target Python installation')\n    return parser.parse_args()\n\n\ndef main(args):\n    path = Path(args.package[0]).resolve()\n    build_package(path, args)\n\n\nif __name__ == '__main__':\n    args = parse_args()\n    main(args)\n", "path": "tools/buildpkg.py"}], "after_files": [{"content": "from pathlib import Path\n\n\nROOTDIR = Path(__file__).parent.resolve()\nHOSTPYTHON = ROOTDIR / '..' / 'cpython' / 'build' / '3.7.0' / 'host'\nTARGETPYTHON = ROOTDIR / '..' / 'cpython' / 'installs' / 'python-3.7.0'\nDEFAULTCFLAGS = ''\nDEFAULTLDFLAGS = ' '.join([\n    '-O3',\n    '-s', \"BINARYEN_METHOD='native-wasm'\",\n    '-Werror',\n    '-s', 'EMULATED_FUNCTION_POINTERS=1',\n    '-s', 'EMULATE_FUNCTION_POINTER_CASTS=1',\n    '-s', 'SIDE_MODULE=1',\n    '-s', 'WASM=1',\n    '--memory-init-file', '0'\n    ])\n\n\ndef parse_package(package):\n    # Import yaml here because pywasmcross needs to run in the built native\n    # Python, which won't have PyYAML\n    import yaml\n    # TODO: Validate against a schema\n    with open(package) as fd:\n        return yaml.load(fd)\n", "path": "tools/common.py"}, {"content": "#!/usr/bin/env python3\n\n\"\"\"\nBuilds a Pyodide package.\n\"\"\"\n\nimport argparse\nimport hashlib\nimport os\nfrom pathlib import Path\nimport shutil\nimport subprocess\n\n\nimport common\n\n\nROOTDIR = Path(__file__).parent.resolve()\n\n\ndef check_checksum(path, pkg):\n    \"\"\"\n    Checks that a tarball matches the checksum in the package metadata.\n    \"\"\"\n    checksum_keys = {'md5', 'sha256'}.intersection(pkg['source'])\n    if not checksum_keys:\n        return\n    elif len(checksum_keys) != 1:\n        raise ValueError('Only one checksum should be included in a package '\n                         'setup; found {}.'.format(checksum_keys))\n    checksum_algorithm = checksum_keys.pop()\n    checksum = pkg['source'][checksum_algorithm]\n    CHUNK_SIZE = 1 << 16\n    h = getattr(hashlib, checksum_algorithm)()\n    with open(path, 'rb') as fd:\n        while True:\n            chunk = fd.read(CHUNK_SIZE)\n            h.update(chunk)\n            if len(chunk) < CHUNK_SIZE:\n                break\n    if h.hexdigest() != checksum:\n        raise ValueError(\"Invalid {} checksum\".format(checksum_algorithm))\n\n\ndef download_and_extract(buildpath, packagedir, pkg, args):\n    tarballpath = buildpath / Path(pkg['source']['url']).name\n    if not tarballpath.is_file():\n        subprocess.run([\n            'wget', '-q', '-O', str(tarballpath), pkg['source']['url']\n        ], check=True)\n        check_checksum(tarballpath, pkg)\n    srcpath = buildpath / packagedir\n    if not srcpath.is_dir():\n        shutil.unpack_archive(str(tarballpath), str(buildpath))\n    return srcpath\n\n\ndef patch(path, srcpath, pkg, args):\n    if (srcpath / '.patched').is_file():\n        return\n\n    # Apply all of the patches\n    orig_dir = Path.cwd()\n    pkgdir = path.parent.resolve()\n    os.chdir(srcpath)\n    try:\n        for patch in pkg['source'].get('patches', []):\n            subprocess.run([\n                'patch', '-p1', '--binary', '-i', pkgdir / patch\n            ], check=True)\n    finally:\n        os.chdir(orig_dir)\n\n    # Add any extra files\n    for src, dst in pkg['source'].get('extras', []):\n        shutil.copyfile(pkgdir / src, srcpath / dst)\n\n    with open(srcpath / '.patched', 'wb') as fd:\n        fd.write(b'\\n')\n\n\ndef compile(path, srcpath, pkg, args):\n    if (srcpath / '.built').is_file():\n        return\n\n    orig_dir = Path.cwd()\n    os.chdir(srcpath)\n    try:\n        subprocess.run([\n            str(Path(args.host) / 'bin' / 'python3'),\n            str(ROOTDIR / 'pywasmcross'),\n            '--cflags',\n            args.cflags + ' ' +\n            pkg.get('build', {}).get('cflags', ''),\n            '--ldflags',\n            args.ldflags + ' ' +\n            pkg.get('build', {}).get('ldflags', ''),\n            '--host', args.host,\n            '--target', args.target], check=True)\n    finally:\n        os.chdir(orig_dir)\n\n    post = pkg.get('build', {}).get('post')\n    if post is not None:\n        site_packages_dir = (\n            srcpath / 'install' / 'lib' / 'python3.7' / 'site-packages')\n        pkgdir = path.parent.resolve()\n        env = {\n            'SITEPACKAGES': site_packages_dir,\n            'PKGDIR': pkgdir\n        }\n        subprocess.run([\n            'bash', '-c', post], env=env, check=True)\n\n    with open(srcpath / '.built', 'wb') as fd:\n        fd.write(b'\\n')\n\n\ndef package_files(buildpath, srcpath, pkg, args):\n    if (buildpath / '.packaged').is_file():\n        return\n\n    name = pkg['package']['name']\n    install_prefix = (srcpath / 'install').resolve()\n    subprocess.run([\n        'python',\n        Path(os.environ['EMSCRIPTEN']) / 'tools' / 'file_packager.py',\n        name + '.data',\n        '--preload',\n        '{}@/'.format(install_prefix),\n        '--js-output={}'.format(name + '.js'),\n        '--export-name=pyodide',\n        '--exclude', '*.wasm.pre',\n        '--exclude', '__pycache__',\n        '--use-preload-plugins'],\n        cwd=buildpath, check=True)\n    subprocess.run([\n        'uglifyjs',\n        buildpath / (name + '.js'),\n        '-o',\n        buildpath / (name + '.js')], check=True)\n\n    with open(buildpath / '.packaged', 'wb') as fd:\n        fd.write(b'\\n')\n\n\ndef build_package(path, args):\n    pkg = common.parse_package(path)\n    packagedir = pkg['package']['name'] + '-' + pkg['package']['version']\n    dirpath = path.parent\n    orig_path = Path.cwd()\n    os.chdir(dirpath)\n    try:\n        buildpath = dirpath / 'build'\n        if not buildpath.is_dir():\n            os.makedirs(buildpath)\n        srcpath = download_and_extract(buildpath, packagedir, pkg, args)\n        patch(path, srcpath, pkg, args)\n        compile(path, srcpath, pkg, args)\n        package_files(buildpath, srcpath, pkg, args)\n    finally:\n        os.chdir(orig_path)\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser('Build a pyodide package.')\n    parser.add_argument(\n        'package', type=str, nargs=1,\n        help=\"Path to meta.yaml package description\")\n    parser.add_argument(\n        '--cflags', type=str, nargs='?', default=common.DEFAULTCFLAGS,\n        help='Extra compiling flags')\n    parser.add_argument(\n        '--ldflags', type=str, nargs='?', default=common.DEFAULTLDFLAGS,\n        help='Extra linking flags')\n    parser.add_argument(\n        '--host', type=str, nargs='?', default=common.HOSTPYTHON,\n        help='The path to the host Python installation')\n    parser.add_argument(\n        '--target', type=str, nargs='?', default=common.TARGETPYTHON,\n        help='The path to the target Python installation')\n    return parser.parse_args()\n\n\ndef main(args):\n    path = Path(args.package[0]).resolve()\n    build_package(path, args)\n\n\nif __name__ == '__main__':\n    args = parse_args()\n    main(args)\n", "path": "tools/buildpkg.py"}]}