From cc852f1cc15d449623af395c456301a142f411e4 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Sun, 3 Sep 2017 10:00:18 +0100 Subject: [PATCH 1/6] Ignore vscode project settings --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index 62c1e736..5721e556 100644 --- a/.gitignore +++ b/.gitignore @@ -92,3 +92,6 @@ ENV/ # Rope project settings .ropeproject + +# VSCode project settings +/.vscode From bade2da061815771e44a01bb2242a08841469bba Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Wed, 6 Sep 2017 22:02:10 +0100 Subject: [PATCH 2/6] Add test for before_build executing in a shell --- test/03_before_build/environment.json | 4 ++-- test/03_before_build/setup.py | 18 ++++++++++++++++-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/test/03_before_build/environment.json b/test/03_before_build/environment.json index 04db7726..75074513 100644 --- a/test/03_before_build/environment.json +++ b/test/03_before_build/environment.json @@ -1,4 +1,4 @@ { - "CIBW_BEFORE_BUILD": "{python} -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\"", - "CIBW_BEFORE_BUILD_WINDOWS": "{python} -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\"" + "CIBW_BEFORE_BUILD": "{python} -c \"import sys; open('/tmp/pythonversion.txt', 'w').write(sys.version)\" && {python} -c \"import sys; open('/tmp/pythonexecutable.txt', 'w').write(sys.executable)\"", + "CIBW_BEFORE_BUILD_WINDOWS": "{python} -c \"import sys; open('c:\\pythonversion.txt', 'w').write(sys.version)\" && {python} -c \"import sys; open('c:\\pythonexecutable.txt', 'w').write(sys.executable)\"" } diff --git a/test/03_before_build/setup.py b/test/03_before_build/setup.py index 0d4d138a..8f6fbcf4 100644 --- a/test/03_before_build/setup.py +++ b/test/03_before_build/setup.py @@ -1,8 +1,8 @@ from setuptools import setup, Extension -import sys +import sys, os if sys.argv[-1] != '--name': - # assert that the Python version as written to version.txt in the CIBW_BEFORE_BUILD step + # assert that the Python version as written to pythonversion.txt in the CIBW_BEFORE_BUILD step # is the same one as is currently running. version_file = 'c:\\pythonversion.txt' if sys.platform == 'win32' else '/tmp/pythonversion.txt' with open(version_file) as f: @@ -11,6 +11,20 @@ if sys.argv[-1] != '--name': print('sys.version', sys.version) assert stored_version == sys.version + # check that the executable also was written + executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' + with open(executable_file) as f: + stored_executable = f.read() + + stored_executable_real = os.path.realpath(stored_executable) + sys_executable_real = os.path.realpath(sys.executable) + + print('stored_executable_real', stored_executable_real) + print('sys_executable_real', sys_executable_real) + assert stored_executable_real == sys_executable_real + + print('PATH', os.environ['PATH']) + setup( name="spam", ext_modules=[Extension('spam', sources=['spam.c'])], From ddb9c077a5bd2cecc1bec64128192ef043a56c53 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Wed, 6 Sep 2017 22:07:24 +0100 Subject: [PATCH 3/6] Use os.path.samefile to get around filename case insensitivity --- test/03_before_build/setup.py | 12 +++--------- 1 file changed, 3 insertions(+), 9 deletions(-) diff --git a/test/03_before_build/setup.py b/test/03_before_build/setup.py index 8f6fbcf4..4baa5634 100644 --- a/test/03_before_build/setup.py +++ b/test/03_before_build/setup.py @@ -15,15 +15,9 @@ if sys.argv[-1] != '--name': executable_file = 'c:\\pythonexecutable.txt' if sys.platform == 'win32' else '/tmp/pythonexecutable.txt' with open(executable_file) as f: stored_executable = f.read() - - stored_executable_real = os.path.realpath(stored_executable) - sys_executable_real = os.path.realpath(sys.executable) - - print('stored_executable_real', stored_executable_real) - print('sys_executable_real', sys_executable_real) - assert stored_executable_real == sys_executable_real - - print('PATH', os.environ['PATH']) + print('stored_executable', stored_executable) + print('sys.executable', sys.executable) + assert os.path.samefile(stored_executable, sys.executable) setup( name="spam", From b64a1c14659f94cd7d2ff5dc6a548a790eca14db Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Wed, 6 Sep 2017 22:11:05 +0100 Subject: [PATCH 4/6] Add shell-style execution on the Mac --- cibuildwheel/macos.py | 40 ++++++++++++++++++++++------------------ 1 file changed, 22 insertions(+), 18 deletions(-) diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index d98b9731..20cad75b 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -19,10 +19,14 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be PythonConfiguration(version='3.6', identifier='cp36-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.6.0/python-3.6.0-macosx10.6.pkg'), ] - def shell(args, env=None, cwd=None): + def call(args, env=None, cwd=None, shell=False): # print the command executing for the logs - print('+ ' + ' '.join(shlex_quote(a) for a in args)) - return subprocess.check_call(args, env=env, cwd=cwd) + if shell: + print('+ %s' % args) + else: + print('+ ' + ' '.join(shlex_quote(a) for a in args)) + + return subprocess.check_call(args, env=env, cwd=cwd, shell=shell) for config in python_configurations: if skip(config.identifier): @@ -30,9 +34,9 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be continue # download the pkg - shell(['curl', '-L', '-o', '/tmp/Python.pkg', config.url]) + call(['curl', '-L', '-o', '/tmp/Python.pkg', config.url]) # install - shell(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/']) + call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/']) env = os.environ.copy() env['PATH'] = os.pathsep.join([ @@ -44,14 +48,14 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be pip = 'pip3' if config.version[0] == '3' else 'pip2' # check what version we're on - shell(['which', python], env=env) - shell([python, '--version'], env=env) + call(['which', python], env=env) + call([python, '--version'], env=env) # install pip & wheel - shell([python, '-m', 'ensurepip', '--upgrade'], env=env) - shell([pip, '--version'], env=env) - shell([pip, 'install', 'wheel'], env=env) - shell([pip, 'install', 'delocate'], env=env) + call([python, '-m', 'ensurepip', '--upgrade'], env=env) + call([pip, '--version'], env=env) + call([pip, 'install', 'wheel'], env=env) + call([pip, 'install', 'delocate'], env=env) # setup dirs if os.path.exists('/tmp/built_wheel'): @@ -64,10 +68,10 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be # run the before_build command if before_build: before_build_prepared = prepare_command(before_build, python=python, pip=pip) - shell(shlex.split(before_build_prepared), env=env) + call(before_build_prepared, env=env, shell=True) # build the wheel - shell([pip, 'wheel', project_dir, '-w', '/tmp/built_wheel', '--no-deps'], env=env) + call([pip, 'wheel', project_dir, '-w', '/tmp/built_wheel', '--no-deps'], env=env) built_wheel = glob('/tmp/built_wheel/*.whl')[0] if built_wheel.endswith('none-any.whl'): @@ -75,24 +79,24 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be shutil.move(built_wheel, '/tmp/delocated_wheel') else: # list the dependencies - shell(['delocate-listdeps', built_wheel], env=env) + call(['delocate-listdeps', built_wheel], env=env) # rebuild the wheel with shared libraries included and place in output dir - shell(['delocate-wheel', '-w', '/tmp/delocated_wheel', built_wheel], env=env) + call(['delocate-wheel', '-w', '/tmp/delocated_wheel', built_wheel], env=env) delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0] # install the wheel - shell([pip, 'install', delocated_wheel], env=env) + call([pip, 'install', delocated_wheel], env=env) # test the wheel if test_requires: - shell([pip, 'install'] + test_requires, env=env) + call([pip, 'install'] + test_requires, env=env) if test_command: # run the tests from $HOME, with an absolute path in the command # (this ensures that Python runs the tests against the installed wheel # and not the repo code) abs_project_dir = os.path.abspath(project_dir) test_command_absolute = test_command.format(project=abs_project_dir) - shell(shlex.split(test_command_absolute), cwd=os.environ['HOME'], env=env) + call(shlex.split(test_command_absolute), cwd=os.environ['HOME'], env=env) # we're all done here; move it to output shutil.move(delocated_wheel, output_dir) From aca294f5bb8c28ce96f30440d29575be8cb1cd37 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Wed, 6 Sep 2017 22:33:01 +0100 Subject: [PATCH 5/6] os.path.samefile is not available on windows. --- test/03_before_build/setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/03_before_build/setup.py b/test/03_before_build/setup.py index 4baa5634..333de6e8 100644 --- a/test/03_before_build/setup.py +++ b/test/03_before_build/setup.py @@ -17,7 +17,8 @@ if sys.argv[-1] != '--name': stored_executable = f.read() print('stored_executable', stored_executable) print('sys.executable', sys.executable) - assert os.path.samefile(stored_executable, sys.executable) + # windows/mac are case insensitive + assert os.path.realpath(stored_executable).lower() == os.path.realpath(sys.executable).lower() setup( name="spam", From d381b63b0010f1f7b89e7603f4b9b3becde8edb0 Mon Sep 17 00:00:00 2001 From: Joe Rickerby Date: Thu, 7 Sep 2017 18:21:01 +0100 Subject: [PATCH 6/6] Update README --- README.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 160bc244..d2295f4c 100644 --- a/README.md +++ b/README.md @@ -137,14 +137,15 @@ Example: `nose==1.3.7 moto==0.4.31` Optional. -Shell command to run before building the wheel. This option allows you to run a command in **each** Python environment before the `pip wheel` command. This is useful if you need to set up some dependency so it's available during the build. +A shell command to run before building the wheel. This option allows you to run a command in **each** Python environment before the `pip wheel` command. This is useful if you need to set up some dependency so it's available during the build. If dependencies are required to build your wheel (for example if you include a header from a Python module), set this to `{pip} install .`, and the dependencies will be installed automatically by pip. However, this means your package will be built twice - if your package takes a long time to build, you might wish to manually list the dependencies here instead. The active Python binary can be accessed using `{python}`, and pip with `{pip}`. These are useful when you need to write `python3` or `pip3` on a Python 3.x build. Example: `{pip} install .` -Example: `{pip} install pybind11` +Example: `{pip} install pybind11` +Example: `yum install -y libffi-dev && {pip} install .` Platform-specific variants also available: `CIBW_BEFORE_BUILD_MACOS` | `CIBW_BEFORE_BUILD_WINDOWS` | `CIBW_BEFORE_BUILD_LINUX`