We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
remove .so files when copying source into the container
Trying to build wheels on travis and I'm getting the following error:

```
auditwheel: error: cannot repair "/tmp/built_wheel/pydantic-0.27a1-cp37-cp37m-linux_x86_64.whl" to "manylinux1_x86_64" ABI because of the presence of too-recent versioned symbols. You'll need to compile the wheel on an older toolchain.
```

See [this build](https://travis-ci.org/samuelcolvin/pydantic/jobs/537258176) for details.

I don't get this error when building locally with `cibuildwheel --platform linux --output-dir dist`.

Any idea what I'm doing wrong?

--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `cibuildwheel/linux.py`
Content:
```
1 from __future__ import print_function
2 import os, subprocess, sys, uuid
3 from collections import namedtuple
4 from .util import prepare_command, get_build_verbosity_extra_flags
5 
6 try:
7     from shlex import quote as shlex_quote
8 except ImportError:
9     from pipes import quote as shlex_quote
10 
11 
12 def get_python_configurations(build_selector):
13     PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path'])
14     python_configurations = [
15         PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'),
16         PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'),
17         PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'),
18         PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'),
19         PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'),
20         PythonConfiguration(identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'),
21         PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'),
22         PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'),
23         PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'),
24         PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'),
25         PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'),
26         PythonConfiguration(identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'),
27     ]
28 
29     # skip builds as required
30     return [c for c in python_configurations if build_selector(c.identifier)]
31 
32 
33 def build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images):
34     try:
35         subprocess.check_call(['docker', '--version'])
36     except:
37         print('cibuildwheel: Docker not found. Docker is required to run Linux builds. '
38               'If you\'re building on Travis CI, add `services: [docker]` to your .travis.yml.'
39               'If you\'re building on Circle CI in Linux, add a `setup_remote_docker` step to your .circleci/config.yml',
40               file=sys.stderr)
41         exit(2)
42 
43     python_configurations = get_python_configurations(build_selector)
44     platforms = [
45         ('manylinux_x86_64', manylinux_images['x86_64']),
46         ('manylinux_i686', manylinux_images['i686']),
47     ]
48 
49     for platform_tag, docker_image in platforms:
50         platform_configs = [c for c in python_configurations if c.identifier.endswith(platform_tag)]
51         if not platform_configs:
52             continue
53 
54         bash_script = '''
55             set -o errexit
56             set -o xtrace
57             mkdir /output
58             cd /project
59 
60             {environment_exports}
61 
62             for PYBIN in {pybin_paths}; do
63                 if [ ! -z {before_build} ]; then
64                     PATH="$PYBIN:$PATH" sh -c {before_build}
65                 fi
66 
67                 # Build the wheel
68                 rm -rf /tmp/built_wheel
69                 mkdir /tmp/built_wheel
70                 PATH="$PYBIN:$PATH" "$PYBIN/pip" wheel . -w /tmp/built_wheel --no-deps {build_verbosity_flag}
71                 built_wheel=(/tmp/built_wheel/*.whl)
72 
73                 # repair the wheel
74                 rm -rf /tmp/repaired_wheels
75                 mkdir /tmp/repaired_wheels
76                 # NOTE: 'built_wheel' here is a bash array of glob matches; "$built_wheel" returns
77                 # the first element
78                 if [[ "$built_wheel" == *none-any.whl ]] || [ -z {repair_command} ]; then
79                     # pure Python wheel or empty repair command
80                     mv "$built_wheel" /tmp/repaired_wheels
81                 else
82                     sh -c {repair_command} repair_command "$built_wheel"
83                 fi
84                 repaired_wheels=(/tmp/repaired_wheels/*.whl)
85 
86                 if [ ! -z {test_command} ]; then
87                     # Set up a virtual environment to install and test from, to make sure
88                     # there are no dependencies that were pulled in at build time.
89                     "$PYBIN/pip" install virtualenv
90                     venv_dir=`mktemp -d`/venv
91                     "$PYBIN/python" -m virtualenv "$venv_dir"
92 
93                     # run the tests in a subshell to keep that `activate`
94                     # script from polluting the env
95                     (
96                         source "$venv_dir/bin/activate"
97 
98                         echo "Running tests using `which python`"
99 
100                         # Install the wheel we just built
101                         # Note: If auditwheel produced two wheels, it's because the earlier produced wheel
102                         # conforms to multiple manylinux standards. These multiple versions of the wheel are
103                         # functionally the same, differing only in name, wheel metadata, and possibly include
104                         # different external shared libraries. so it doesn't matter which one we run the tests on.
105                         # Let's just pick the first one.
106                         pip install "${{repaired_wheels[0]}}"{test_extras}
107 
108                         # Install any requirements to run the tests
109                         if [ ! -z "{test_requires}" ]; then
110                             pip install {test_requires}
111                         fi
112 
113                         # Run the tests from a different directory
114                         pushd $HOME
115                         sh -c {test_command}
116                         popd
117                     )
118                     # exit if tests failed (needed for older bash versions)
119                     if [ $? -ne 0 ]; then
120                       exit 1;
121                     fi
122 
123                     # clean up
124                     rm -rf "$venv_dir"
125                 fi
126 
127                 # we're all done here; move it to output
128                 mv "${{repaired_wheels[@]}}" /output
129                 for repaired_wheel in "${{repaired_wheels[@]}}"; do chown {uid}:{gid} "/output/$(basename "$repaired_wheel")"; done
130             done
131         '''.format(
132             pybin_paths=' '.join(c.path+'/bin' for c in platform_configs),
133             test_requires=' '.join(test_requires),
134             test_extras=test_extras,
135             test_command=shlex_quote(
136                 prepare_command(test_command, project='/project') if test_command else ''
137             ),
138             before_build=shlex_quote(
139                 prepare_command(before_build, project='/project') if before_build else ''
140             ),
141             build_verbosity_flag=' '.join(get_build_verbosity_extra_flags(build_verbosity)),
142             repair_command=shlex_quote(
143                 prepare_command(repair_command, wheel='"$1"', dest_dir='/tmp/repaired_wheels') if repair_command else ''
144             ),
145             environment_exports='\n'.join(environment.as_shell_commands()),
146             uid=os.getuid(),
147             gid=os.getgid(),
148         )
149 
150         def run_docker(command, stdin_str=None):
151             print('docker command: docker {}'.format(' '.join(map(shlex_quote, command))))
152             if stdin_str is None:
153                 subprocess.check_call(['docker'] + command)
154             else:
155                 args = ['docker'] + command
156                 process = subprocess.Popen(args, stdin=subprocess.PIPE, universal_newlines=True)
157                 try:
158                     process.communicate(stdin_str)
159                 except KeyboardInterrupt:
160                     process.kill()
161                     process.wait()
162                 if process.returncode != 0:
163                     raise subprocess.CalledProcessError(process.returncode, args)
164 
165         container_name = 'cibuildwheel-{}'.format(uuid.uuid4())
166         try:
167             run_docker(['create',
168                         '--env', 'CIBUILDWHEEL',
169                         '--name', container_name,
170                         '-i',
171                         '-v', '/:/host', # ignored on Circle
172                         docker_image, '/bin/bash'])
173             run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project'])
174             run_docker(['start', '-i', '-a', container_name], stdin_str=bash_script)
175             run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)])
176         except subprocess.CalledProcessError:
177             exit(1)
178         finally:
179             # Still gets executed, even when 'exit(1)' gets called
180             run_docker(['rm', '--force', '-v', container_name])
181
```
--- 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/cibuildwheel/linux.py b/cibuildwheel/linux.py
--- a/cibuildwheel/linux.py
+++ b/cibuildwheel/linux.py
@@ -1,5 +1,5 @@
 from __future__ import print_function
-import os, subprocess, sys, uuid
+import os, subprocess, sys, uuid, textwrap
 from collections import namedtuple
 from .util import prepare_command, get_build_verbosity_extra_flags
 
@@ -173,8 +173,36 @@
             run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project'])
             run_docker(['start', '-i', '-a', container_name], stdin_str=bash_script)
             run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)])
-        except subprocess.CalledProcessError:
+        except subprocess.CalledProcessError as error:
+            troubleshoot(project_dir, error)
             exit(1)
         finally:
             # Still gets executed, even when 'exit(1)' gets called
             run_docker(['rm', '--force', '-v', container_name])
+
+
+def troubleshoot(project_dir, error):
+    if (isinstance(error, subprocess.CalledProcessError) and 'start' in error.cmd):
+        # the bash script failed
+        print('Checking for common errors...')
+        so_files = []
+        for root, dirs, files in os.walk(project_dir):
+            for name in files:
+                _, ext = os.path.splitext(name)
+                if ext == '.so':
+                    so_files.append(os.path.join(root, name))
+
+        if so_files:
+            print(textwrap.dedent('''
+                NOTE: Shared object (.so) files found in this project.
+
+                  These files might be built against the wrong OS, causing problems with
+                  auditwheel.
+
+                  If you're using Cython and have previously done an in-place build,
+                  remove those build files (*.so and *.c) before starting cibuildwheel.
+            '''))
+
+            print('  Files detected:')
+            print('\n'.join(['    '+f for f in so_files]))
+            print('')

{"golden_diff": "diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py\n--- a/cibuildwheel/linux.py\n+++ b/cibuildwheel/linux.py\n@@ -1,5 +1,5 @@\n from __future__ import print_function\n-import os, subprocess, sys, uuid\n+import os, subprocess, sys, uuid, textwrap\n from collections import namedtuple\n from .util import prepare_command, get_build_verbosity_extra_flags\n \n@@ -173,8 +173,36 @@\n             run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project'])\n             run_docker(['start', '-i', '-a', container_name], stdin_str=bash_script)\n             run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)])\n-        except subprocess.CalledProcessError:\n+        except subprocess.CalledProcessError as error:\n+            troubleshoot(project_dir, error)\n             exit(1)\n         finally:\n             # Still gets executed, even when 'exit(1)' gets called\n             run_docker(['rm', '--force', '-v', container_name])\n+\n+\n+def troubleshoot(project_dir, error):\n+    if (isinstance(error, subprocess.CalledProcessError) and 'start' in error.cmd):\n+        # the bash script failed\n+        print('Checking for common errors...')\n+        so_files = []\n+        for root, dirs, files in os.walk(project_dir):\n+            for name in files:\n+                _, ext = os.path.splitext(name)\n+                if ext == '.so':\n+                    so_files.append(os.path.join(root, name))\n+\n+        if so_files:\n+            print(textwrap.dedent('''\n+                NOTE: Shared object (.so) files found in this project.\n+\n+                  These files might be built against the wrong OS, causing problems with\n+                  auditwheel.\n+\n+                  If you're using Cython and have previously done an in-place build,\n+                  remove those build files (*.so and *.c) before starting cibuildwheel.\n+            '''))\n+\n+            print('  Files detected:')\n+            print('\\n'.join(['    '+f for f in so_files]))\n+            print('')\n", "issue": "remove .so files when copying source into the container\nTrying to build wheels on travis and I'm getting the following error:\r\n\r\n```\r\nauditwheel: error: cannot repair \"/tmp/built_wheel/pydantic-0.27a1-cp37-cp37m-linux_x86_64.whl\" to \"manylinux1_x86_64\" ABI because of the presence of too-recent versioned symbols. You'll need to compile the wheel on an older toolchain.\r\n```\r\n\r\nSee [this build](https://travis-ci.org/samuelcolvin/pydantic/jobs/537258176) for details.\r\n\r\nI don't get this error when building locally with `cibuildwheel --platform linux --output-dir dist`.\r\n\r\nAny idea what I'm doing wrong?\n", "before_files": [{"content": "from __future__ import print_function\nimport os, subprocess, sys, uuid\nfrom collections import namedtuple\nfrom .util import prepare_command, get_build_verbosity_extra_flags\n\ntry:\n    from shlex import quote as shlex_quote\nexcept ImportError:\n    from pipes import quote as shlex_quote\n\n\ndef get_python_configurations(build_selector):\n    PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path'])\n    python_configurations = [\n        PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'),\n        PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'),\n        PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'),\n        PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'),\n        PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'),\n        PythonConfiguration(identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'),\n        PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'),\n        PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'),\n        PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'),\n        PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'),\n        PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'),\n        PythonConfiguration(identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'),\n    ]\n\n    # skip builds as required\n    return [c for c in python_configurations if build_selector(c.identifier)]\n\n\ndef build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images):\n    try:\n        subprocess.check_call(['docker', '--version'])\n    except:\n        print('cibuildwheel: Docker not found. Docker is required to run Linux builds. '\n              'If you\\'re building on Travis CI, add `services: [docker]` to your .travis.yml.'\n              'If you\\'re building on Circle CI in Linux, add a `setup_remote_docker` step to your .circleci/config.yml',\n              file=sys.stderr)\n        exit(2)\n\n    python_configurations = get_python_configurations(build_selector)\n    platforms = [\n        ('manylinux_x86_64', manylinux_images['x86_64']),\n        ('manylinux_i686', manylinux_images['i686']),\n    ]\n\n    for platform_tag, docker_image in platforms:\n        platform_configs = [c for c in python_configurations if c.identifier.endswith(platform_tag)]\n        if not platform_configs:\n            continue\n\n        bash_script = '''\n            set -o errexit\n            set -o xtrace\n            mkdir /output\n            cd /project\n\n            {environment_exports}\n\n            for PYBIN in {pybin_paths}; do\n                if [ ! -z {before_build} ]; then\n                    PATH=\"$PYBIN:$PATH\" sh -c {before_build}\n                fi\n\n                # Build the wheel\n                rm -rf /tmp/built_wheel\n                mkdir /tmp/built_wheel\n                PATH=\"$PYBIN:$PATH\" \"$PYBIN/pip\" wheel . -w /tmp/built_wheel --no-deps {build_verbosity_flag}\n                built_wheel=(/tmp/built_wheel/*.whl)\n\n                # repair the wheel\n                rm -rf /tmp/repaired_wheels\n                mkdir /tmp/repaired_wheels\n                # NOTE: 'built_wheel' here is a bash array of glob matches; \"$built_wheel\" returns\n                # the first element\n                if [[ \"$built_wheel\" == *none-any.whl ]] || [ -z {repair_command} ]; then\n                    # pure Python wheel or empty repair command\n                    mv \"$built_wheel\" /tmp/repaired_wheels\n                else\n                    sh -c {repair_command} repair_command \"$built_wheel\"\n                fi\n                repaired_wheels=(/tmp/repaired_wheels/*.whl)\n\n                if [ ! -z {test_command} ]; then\n                    # Set up a virtual environment to install and test from, to make sure\n                    # there are no dependencies that were pulled in at build time.\n                    \"$PYBIN/pip\" install virtualenv\n                    venv_dir=`mktemp -d`/venv\n                    \"$PYBIN/python\" -m virtualenv \"$venv_dir\"\n\n                    # run the tests in a subshell to keep that `activate`\n                    # script from polluting the env\n                    (\n                        source \"$venv_dir/bin/activate\"\n\n                        echo \"Running tests using `which python`\"\n\n                        # Install the wheel we just built\n                        # Note: If auditwheel produced two wheels, it's because the earlier produced wheel\n                        # conforms to multiple manylinux standards. These multiple versions of the wheel are\n                        # functionally the same, differing only in name, wheel metadata, and possibly include\n                        # different external shared libraries. so it doesn't matter which one we run the tests on.\n                        # Let's just pick the first one.\n                        pip install \"${{repaired_wheels[0]}}\"{test_extras}\n\n                        # Install any requirements to run the tests\n                        if [ ! -z \"{test_requires}\" ]; then\n                            pip install {test_requires}\n                        fi\n\n                        # Run the tests from a different directory\n                        pushd $HOME\n                        sh -c {test_command}\n                        popd\n                    )\n                    # exit if tests failed (needed for older bash versions)\n                    if [ $? -ne 0 ]; then\n                      exit 1;\n                    fi\n\n                    # clean up\n                    rm -rf \"$venv_dir\"\n                fi\n\n                # we're all done here; move it to output\n                mv \"${{repaired_wheels[@]}}\" /output\n                for repaired_wheel in \"${{repaired_wheels[@]}}\"; do chown {uid}:{gid} \"/output/$(basename \"$repaired_wheel\")\"; done\n            done\n        '''.format(\n            pybin_paths=' '.join(c.path+'/bin' for c in platform_configs),\n            test_requires=' '.join(test_requires),\n            test_extras=test_extras,\n            test_command=shlex_quote(\n                prepare_command(test_command, project='/project') if test_command else ''\n            ),\n            before_build=shlex_quote(\n                prepare_command(before_build, project='/project') if before_build else ''\n            ),\n            build_verbosity_flag=' '.join(get_build_verbosity_extra_flags(build_verbosity)),\n            repair_command=shlex_quote(\n                prepare_command(repair_command, wheel='\"$1\"', dest_dir='/tmp/repaired_wheels') if repair_command else ''\n            ),\n            environment_exports='\\n'.join(environment.as_shell_commands()),\n            uid=os.getuid(),\n            gid=os.getgid(),\n        )\n\n        def run_docker(command, stdin_str=None):\n            print('docker command: docker {}'.format(' '.join(map(shlex_quote, command))))\n            if stdin_str is None:\n                subprocess.check_call(['docker'] + command)\n            else:\n                args = ['docker'] + command\n                process = subprocess.Popen(args, stdin=subprocess.PIPE, universal_newlines=True)\n                try:\n                    process.communicate(stdin_str)\n                except KeyboardInterrupt:\n                    process.kill()\n                    process.wait()\n                if process.returncode != 0:\n                    raise subprocess.CalledProcessError(process.returncode, args)\n\n        container_name = 'cibuildwheel-{}'.format(uuid.uuid4())\n        try:\n            run_docker(['create',\n                        '--env', 'CIBUILDWHEEL',\n                        '--name', container_name,\n                        '-i',\n                        '-v', '/:/host', # ignored on Circle\n                        docker_image, '/bin/bash'])\n            run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project'])\n            run_docker(['start', '-i', '-a', container_name], stdin_str=bash_script)\n            run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)])\n        except subprocess.CalledProcessError:\n            exit(1)\n        finally:\n            # Still gets executed, even when 'exit(1)' gets called\n            run_docker(['rm', '--force', '-v', container_name])\n", "path": "cibuildwheel/linux.py"}], "after_files": [{"content": "from __future__ import print_function\nimport os, subprocess, sys, uuid, textwrap\nfrom collections import namedtuple\nfrom .util import prepare_command, get_build_verbosity_extra_flags\n\ntry:\n    from shlex import quote as shlex_quote\nexcept ImportError:\n    from pipes import quote as shlex_quote\n\n\ndef get_python_configurations(build_selector):\n    PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path'])\n    python_configurations = [\n        PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'),\n        PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'),\n        PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'),\n        PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'),\n        PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'),\n        PythonConfiguration(identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'),\n        PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'),\n        PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'),\n        PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'),\n        PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'),\n        PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'),\n        PythonConfiguration(identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'),\n    ]\n\n    # skip builds as required\n    return [c for c in python_configurations if build_selector(c.identifier)]\n\n\ndef build(project_dir, output_dir, test_command, test_requires, test_extras, before_build, build_verbosity, build_selector, repair_command, environment, manylinux_images):\n    try:\n        subprocess.check_call(['docker', '--version'])\n    except:\n        print('cibuildwheel: Docker not found. Docker is required to run Linux builds. '\n              'If you\\'re building on Travis CI, add `services: [docker]` to your .travis.yml.'\n              'If you\\'re building on Circle CI in Linux, add a `setup_remote_docker` step to your .circleci/config.yml',\n              file=sys.stderr)\n        exit(2)\n\n    python_configurations = get_python_configurations(build_selector)\n    platforms = [\n        ('manylinux_x86_64', manylinux_images['x86_64']),\n        ('manylinux_i686', manylinux_images['i686']),\n    ]\n\n    for platform_tag, docker_image in platforms:\n        platform_configs = [c for c in python_configurations if c.identifier.endswith(platform_tag)]\n        if not platform_configs:\n            continue\n\n        bash_script = '''\n            set -o errexit\n            set -o xtrace\n            mkdir /output\n            cd /project\n\n            {environment_exports}\n\n            for PYBIN in {pybin_paths}; do\n                if [ ! -z {before_build} ]; then\n                    PATH=\"$PYBIN:$PATH\" sh -c {before_build}\n                fi\n\n                # Build the wheel\n                rm -rf /tmp/built_wheel\n                mkdir /tmp/built_wheel\n                PATH=\"$PYBIN:$PATH\" \"$PYBIN/pip\" wheel . -w /tmp/built_wheel --no-deps {build_verbosity_flag}\n                built_wheel=(/tmp/built_wheel/*.whl)\n\n                # repair the wheel\n                rm -rf /tmp/repaired_wheels\n                mkdir /tmp/repaired_wheels\n                # NOTE: 'built_wheel' here is a bash array of glob matches; \"$built_wheel\" returns\n                # the first element\n                if [[ \"$built_wheel\" == *none-any.whl ]] || [ -z {repair_command} ]; then\n                    # pure Python wheel or empty repair command\n                    mv \"$built_wheel\" /tmp/repaired_wheels\n                else\n                    sh -c {repair_command} repair_command \"$built_wheel\"\n                fi\n                repaired_wheels=(/tmp/repaired_wheels/*.whl)\n\n                if [ ! -z {test_command} ]; then\n                    # Set up a virtual environment to install and test from, to make sure\n                    # there are no dependencies that were pulled in at build time.\n                    \"$PYBIN/pip\" install virtualenv\n                    venv_dir=`mktemp -d`/venv\n                    \"$PYBIN/python\" -m virtualenv \"$venv_dir\"\n\n                    # run the tests in a subshell to keep that `activate`\n                    # script from polluting the env\n                    (\n                        source \"$venv_dir/bin/activate\"\n\n                        echo \"Running tests using `which python`\"\n\n                        # Install the wheel we just built\n                        # Note: If auditwheel produced two wheels, it's because the earlier produced wheel\n                        # conforms to multiple manylinux standards. These multiple versions of the wheel are\n                        # functionally the same, differing only in name, wheel metadata, and possibly include\n                        # different external shared libraries. so it doesn't matter which one we run the tests on.\n                        # Let's just pick the first one.\n                        pip install \"${{repaired_wheels[0]}}\"{test_extras}\n\n                        # Install any requirements to run the tests\n                        if [ ! -z \"{test_requires}\" ]; then\n                            pip install {test_requires}\n                        fi\n\n                        # Run the tests from a different directory\n                        pushd $HOME\n                        sh -c {test_command}\n                        popd\n                    )\n                    # exit if tests failed (needed for older bash versions)\n                    if [ $? -ne 0 ]; then\n                      exit 1;\n                    fi\n\n                    # clean up\n                    rm -rf \"$venv_dir\"\n                fi\n\n                # we're all done here; move it to output\n                mv \"${{repaired_wheels[@]}}\" /output\n                for repaired_wheel in \"${{repaired_wheels[@]}}\"; do chown {uid}:{gid} \"/output/$(basename \"$repaired_wheel\")\"; done\n            done\n        '''.format(\n            pybin_paths=' '.join(c.path+'/bin' for c in platform_configs),\n            test_requires=' '.join(test_requires),\n            test_extras=test_extras,\n            test_command=shlex_quote(\n                prepare_command(test_command, project='/project') if test_command else ''\n            ),\n            before_build=shlex_quote(\n                prepare_command(before_build, project='/project') if before_build else ''\n            ),\n            build_verbosity_flag=' '.join(get_build_verbosity_extra_flags(build_verbosity)),\n            repair_command=shlex_quote(\n                prepare_command(repair_command, wheel='\"$1\"', dest_dir='/tmp/repaired_wheels') if repair_command else ''\n            ),\n            environment_exports='\\n'.join(environment.as_shell_commands()),\n            uid=os.getuid(),\n            gid=os.getgid(),\n        )\n\n        def run_docker(command, stdin_str=None):\n            print('docker command: docker {}'.format(' '.join(map(shlex_quote, command))))\n            if stdin_str is None:\n                subprocess.check_call(['docker'] + command)\n            else:\n                args = ['docker'] + command\n                process = subprocess.Popen(args, stdin=subprocess.PIPE, universal_newlines=True)\n                try:\n                    process.communicate(stdin_str)\n                except KeyboardInterrupt:\n                    process.kill()\n                    process.wait()\n                if process.returncode != 0:\n                    raise subprocess.CalledProcessError(process.returncode, args)\n\n        container_name = 'cibuildwheel-{}'.format(uuid.uuid4())\n        try:\n            run_docker(['create',\n                        '--env', 'CIBUILDWHEEL',\n                        '--name', container_name,\n                        '-i',\n                        '-v', '/:/host', # ignored on Circle\n                        docker_image, '/bin/bash'])\n            run_docker(['cp', os.path.abspath(project_dir) + '/.', container_name + ':/project'])\n            run_docker(['start', '-i', '-a', container_name], stdin_str=bash_script)\n            run_docker(['cp', container_name + ':/output/.', os.path.abspath(output_dir)])\n        except subprocess.CalledProcessError as error:\n            troubleshoot(project_dir, error)\n            exit(1)\n        finally:\n            # Still gets executed, even when 'exit(1)' gets called\n            run_docker(['rm', '--force', '-v', container_name])\n\n\ndef troubleshoot(project_dir, error):\n    if (isinstance(error, subprocess.CalledProcessError) and 'start' in error.cmd):\n        # the bash script failed\n        print('Checking for common errors...')\n        so_files = []\n        for root, dirs, files in os.walk(project_dir):\n            for name in files:\n                _, ext = os.path.splitext(name)\n                if ext == '.so':\n                    so_files.append(os.path.join(root, name))\n\n        if so_files:\n            print(textwrap.dedent('''\n                NOTE: Shared object (.so) files found in this project.\n\n                  These files might be built against the wrong OS, causing problems with\n                  auditwheel.\n\n                  If you're using Cython and have previously done an in-place build,\n                  remove those build files (*.so and *.c) before starting cibuildwheel.\n            '''))\n\n            print('  Files detected:')\n            print('\\n'.join(['    '+f for f in so_files]))\n            print('')\n", "path": "cibuildwheel/linux.py"}]}