diff --git a/README.md b/README.md index cdce45f3..89ba9240 100644 --- a/README.md +++ b/README.md @@ -206,13 +206,13 @@ Optional. 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. +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. `{project}` can be used as a placeholder for the absolute path to the project's root. +The active Python binary can be accessed using `python`, and pip with `pip`; `cibuildwheel` makes sure the right version of Python and pip will be executed. `{project}` can be used as a placeholder for the absolute path to the project's root. -Example: `{pip} install .` -Example: `{pip} install pybind11` -Example: `yum install -y libffi-dev && {pip} install .` +Example: `pip install .` +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` @@ -234,7 +234,7 @@ Example: `dockcross/manylinux-x86` Optional. -Shell command to run tests after the build. The wheel will be installed automatically and available for import from the tests. Just like in the `CIBW_BEFORE_BUILD` option, `{python}`, `{pip}`, and `{project}` will respectively be replaced by the Python executable, the pip executable, and the absolute project directory. +Shell command to run tests after the build. The wheel will be installed automatically and available for import from the tests. `{project}` can be used as a placeholder for the absolute path to the project's root and will be replaced by `cibuildwheel`. Example: `nosetests {project}/tests` diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index ca45fe31..775a20e2 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -171,7 +171,27 @@ def print_preamble(platform, build_options): for option, value in build_options.items(): print(' %s: %r' % (option, value)) + warnings = detect_warnings(platform, build_options) + if warnings: + print('\nWarnings:') + for warning in warnings: + print(' ' + warning) + print('\nHere we go!\n') +def detect_warnings(platform, build_options): + warnings = [] + + # warn about deprecated {python} and {pip} + for option_name in ['test_command', 'before_build']: + option_value = build_options.get(option_name) + + if option_value: + if '{python}' in option_value or '{pip}' in option_value: + warnings.append(option_name + ": '{python}' and '{pip}' are no longer needed, and will be removed in a future release. Simply use 'python' or 'pip' instead.") + + return warnings + + if __name__ == '__main__': main() diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index 114b63da..b2b0f44d 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -104,10 +104,10 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be pybin_paths=' '.join(c.path+'/bin' for c in platform_configs), test_requires=' '.join(test_requires), test_command=shlex_quote( - prepare_command(test_command, python='python', pip='pip', project='/project') if test_command else '' + prepare_command(test_command, project='/project') if test_command else '' ), before_build=shlex_quote( - prepare_command(before_build, python='python', pip='pip', project='/project') if before_build else '' + prepare_command(before_build, project='/project') if before_build else '' ), build_verbosity_flag=' '.join(get_build_verbosity_extra_flags(build_verbosity)), environment_exports='\n'.join(environment.as_shell_commands()), diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index b445d2ba..496c4d1c 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -54,26 +54,37 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be # install call(['sudo', 'installer', '-pkg', '/tmp/Python.pkg', '-target', '/']) + installation_bin_path = '/Library/Frameworks/Python.framework/Versions/{}/bin'.format(config.version) + + # Python bin folders on Mac don't symlink python3 to python, so we do that + # so `python` and `pip` always point to the active configuration. + if os.path.exists('/tmp/cibw_bin'): + shutil.rmtree('/tmp/cibw_bin') + os.makedirs('/tmp/cibw_bin') + + if config.version[0] == '3': + os.symlink(os.path.join(installation_bin_path, 'python3'), '/tmp/cibw_bin/python') + os.symlink(os.path.join(installation_bin_path, 'python3-config'), '/tmp/cibw_bin/python-config') + os.symlink(os.path.join(installation_bin_path, 'pip3'), '/tmp/cibw_bin/pip') + env = os.environ.copy() env['PATH'] = os.pathsep.join([ - '/Library/Frameworks/Python.framework/Versions/%s/bin' % config.version, + '/tmp/cibw_bin', + installation_bin_path, env['PATH'], ]) env = environment.as_dictionary(prev_environment=env) - python = 'python3' if config.version[0] == '3' else 'python2' - pip = 'pip3' if config.version[0] == '3' else 'pip2' - # check what version we're on - call(['which', python], env=env) - call([python, '--version'], env=env) + call(['which', 'python'], env=env) + call(['python', '--version'], env=env) # install pip & wheel - call([python, get_pip_script, '--no-setuptools', '--no-wheel'], env=env) - call([pip, '--version'], env=env) - call([pip, 'install', '--upgrade', 'setuptools'], env=env) - call([pip, 'install', 'wheel'], env=env) - call([pip, 'install', 'delocate'], env=env) + call(['python', get_pip_script, '--no-setuptools', '--no-wheel'], env=env) + call(['pip', '--version'], env=env) + call(['pip', 'install', '--upgrade', 'setuptools'], env=env) + call(['pip', 'install', 'wheel'], env=env) + call(['pip', 'install', 'delocate'], env=env) # setup dirs if os.path.exists('/tmp/built_wheel'): @@ -85,11 +96,11 @@ 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, project=abs_project_dir) + before_build_prepared = prepare_command(before_build, project=abs_project_dir) call(before_build_prepared, env=env, shell=True) # build the wheel - call([pip, 'wheel', abs_project_dir, '-w', '/tmp/built_wheel', '--no-deps'] + get_build_verbosity_extra_flags(build_verbosity), env=env) + call(['pip', 'wheel', abs_project_dir, '-w', '/tmp/built_wheel', '--no-deps'] + get_build_verbosity_extra_flags(build_verbosity), env=env) built_wheel = glob('/tmp/built_wheel/*.whl')[0] if built_wheel.endswith('none-any.whl'): @@ -103,16 +114,16 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be delocated_wheel = glob('/tmp/delocated_wheel/*.whl')[0] # install the wheel - call([pip, 'install', delocated_wheel], env=env) + call(['pip', 'install', delocated_wheel], env=env) # test the wheel if test_requires: - call([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) - test_command_prepared = prepare_command(test_command, python=python, pip=pip, project=abs_project_dir) + test_command_prepared = prepare_command(test_command, project=abs_project_dir) call(shlex.split(test_command_prepared), cwd=os.environ['HOME'], env=env) # we're all done here; move it to output diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index fe73a5c8..7db3edaa 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -1,16 +1,15 @@ from fnmatch import fnmatch +import warnings -def prepare_command(command, python, pip, project): +def prepare_command(command, project): ''' - Preprocesses a command by expanding variables like {python} or {pip}. + Preprocesses a command by expanding variables like {project}. - For example, used for the before_build option, where the user would - like to run a command like `python setup.py test`. If the command should run on - Python 3, the user could write `{python} setup.py test`. This command would expand - it out to python2 or python3 as appropriate. + For example, used in the test_command option, to specify the path to the + tests directory. ''' - return command.format(python=python, pip=pip, project=project) + return command.format(python='python', pip='pip', project=project) def get_build_verbosity_extra_flags(level): diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index 299e160d..77bba341 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -79,7 +79,7 @@ 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', project=abs_project_dir) + before_build_prepared = prepare_command(before_build, project=abs_project_dir) shell([before_build_prepared], env=env) # build the wheel @@ -96,7 +96,7 @@ def build(project_dir, package_name, output_dir, test_command, test_requires, be # run the tests from c:\, with an absolute path in the command # (this ensures that Python runs the tests against the installed wheel # and not the repo code) - test_command_prepared = prepare_command(test_command, python='python', pip='pip', project=abs_project_dir) + test_command_prepared = prepare_command(test_command, project=abs_project_dir) shell([test_command_prepared], cwd='c:\\', env=env) # we're all done here; move it to output diff --git a/test/03_before_build/environment.json b/test/03_before_build/environment.json index 75074513..3e9108ea 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)\" && {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)\"" + "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)\"" }