diff --git a/bin/update_constraints b/bin/update_constraints index 773a1d83..0e6ca9e4 100755 --- a/bin/update_constraints +++ b/bin/update_constraints @@ -20,7 +20,7 @@ subprocess.check_call([ '--generate-hashes', '--upgrade', 'cibuildwheel/resources/constraints.in', - '--output-file', 'cibuildwheel/resources/constraints-python2.txt' + '--output-file', 'cibuildwheel/resources/constraints-python27.txt' ]) Image = namedtuple('Image', ['manylinux_version', 'arch']) diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index 890bd4c7..38ecd711 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -4,7 +4,7 @@ import argparse, os, subprocess, sys, textwrap import cibuildwheel import cibuildwheel.linux, cibuildwheel.windows, cibuildwheel.macos from cibuildwheel.environment import parse_environment, EnvironmentParseError -from cibuildwheel.util import BuildSelector, Unbuffered +from cibuildwheel.util import BuildSelector, DependencyConstraints, Unbuffered def get_option_from_environment(option_name, platform=None, default=None): ''' @@ -102,15 +102,14 @@ def main(): repair_command_default = '' repair_command = get_option_from_environment('CIBW_REPAIR_WHEEL_COMMAND', platform=platform, default=repair_command_default) environment_config = get_option_from_environment('CIBW_ENVIRONMENT', platform=platform, default='') + dependency_versions = get_option_from_environment('CIBW_DEPENDENCY_VERSIONS', platform=platform, default='pinned') if dependency_versions == 'pinned': - dependency_constraints = os.path.join( - os.path.dirname(__file__), 'resources', 'constraints.txt' - ) + dependency_constraints = DependencyConstraints.with_defaults() elif dependency_versions == 'latest': - dependency_constraints = '' + dependency_constraints = None else: - dependency_constraints = dependency_versions + dependency_constraints = DependencyConstraints(dependency_versions) if test_extras: test_extras = '[{0}]'.format(test_extras) diff --git a/cibuildwheel/linux.py b/cibuildwheel/linux.py index ebbd9dc4..db066394 100644 --- a/cibuildwheel/linux.py +++ b/cibuildwheel/linux.py @@ -10,20 +10,20 @@ except ImportError: def get_python_configurations(build_selector): - PythonConfiguration = namedtuple('PythonConfiguration', ['identifier', 'path']) + PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'path']) python_configurations = [ - PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'), - PythonConfiguration(identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'), - PythonConfiguration(identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'), - PythonConfiguration(identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'), - PythonConfiguration(identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'), - PythonConfiguration(identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'), - PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'), - PythonConfiguration(identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'), - PythonConfiguration(identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'), - PythonConfiguration(identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'), - PythonConfiguration(identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'), - PythonConfiguration(identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'), + PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27m'), + PythonConfiguration(version='2.7', identifier='cp27-manylinux_x86_64', path='/opt/python/cp27-cp27mu'), + PythonConfiguration(version='3.5', identifier='cp35-manylinux_x86_64', path='/opt/python/cp35-cp35m'), + PythonConfiguration(version='3.6', identifier='cp36-manylinux_x86_64', path='/opt/python/cp36-cp36m'), + PythonConfiguration(version='3.7', identifier='cp37-manylinux_x86_64', path='/opt/python/cp37-cp37m'), + PythonConfiguration(version='3.8', identifier='cp38-manylinux_x86_64', path='/opt/python/cp38-cp38'), + PythonConfiguration(version='2.7', identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27m'), + PythonConfiguration(version='2.7', identifier='cp27-manylinux_i686', path='/opt/python/cp27-cp27mu'), + PythonConfiguration(version='3.5', identifier='cp35-manylinux_i686', path='/opt/python/cp35-cp35m'), + PythonConfiguration(version='3.6', identifier='cp36-manylinux_i686', path='/opt/python/cp36-cp36m'), + PythonConfiguration(version='3.7', identifier='cp37-manylinux_i686', path='/opt/python/cp37-cp37m'), + PythonConfiguration(version='3.8', identifier='cp38-manylinux_i686', path='/opt/python/cp38-cp38'), ] # skip builds as required @@ -79,7 +79,9 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef for config in platform_configs: if dependency_constraints: - run_docker(['cp', os.path.abspath(dependency_constraints), container_name + ':/constraints.txt']) + constraints_file = dependency_constraints.get_for_python_version(config.version) + run_docker(['cp', os.path.abspath(constraints_file), container_name + ':/constraints.txt']) + run_docker(['start', '-i', '-a', container_name], stdin_str=''' set -o errexit set -o xtrace diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index 0a221b29..72b45426 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -87,7 +87,11 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef call(['which', 'python'], env=env) call(['python', '--version'], env=env) - dependency_constraint_flags = ['-c', dependency_constraints] if dependency_constraints else [] + dependency_constraint_flags = [] + if dependency_constraints: + dependency_constraint_flags = [ + '-c', dependency_constraints.get_for_python_version(config.version) + ] # install pip & wheel call(['python', get_pip_script, '--no-setuptools', '--no-wheel'] + dependency_constraint_flags, env=env, cwd="/tmp") diff --git a/cibuildwheel/resources/constraints-python27.txt b/cibuildwheel/resources/constraints-python27.txt new file mode 100644 index 00000000..19b904ee --- /dev/null +++ b/cibuildwheel/resources/constraints-python27.txt @@ -0,0 +1,29 @@ +# +# This file is autogenerated by pip-compile +# To update, run: +# +# bin/update_constraints +# +auditwheel==2.1.1 \ + --hash=sha256:d9f0f47c0ecdf4f72316eabfb19223b81aec95f0deba97729e9c09ea4f2c166e \ + --hash=sha256:f60e265dc168ae7c9d65a814410881c5ca170d88644c178f8e3aa20eecd0fae1 +delocate==0.8.0 \ + --hash=sha256:ac9f4d8d28b2582d94f764db0d72a1fe3c42ab8212e9b780168455de385d5b95 +pyelftools==0.26 \ + --hash=sha256:86ac6cee19f6c945e8dedf78c6ee74f1112bd14da5a658d8c9d4103aed5756a2 \ + --hash=sha256:cc0ea0de82b240a73ef4056fce44acbb4727dca7d66759371aff2bad457ed711 \ + # via auditwheel +virtualenv==16.7.9 \ + --hash=sha256:0d62c70883c0342d59c11d0ddac0d954d0431321a41ab20851facf2b222598f3 \ + --hash=sha256:55059a7a676e4e19498f1aad09b8313a38fcc0cdbe4fdddc0e9b06946d21b4bb +wheel==0.31.1 \ + --hash=sha256:0a2e54558a0628f2145d2fc822137e322412115173e8a2ddbe1c9024338ae83c \ + --hash=sha256:80044e51ec5bbf6c894ba0bc48d26a8c20a9ba629f4ca19ea26ecfcf87685f5f + +# The following packages are considered to be unsafe in a requirements file: +pip==20.0.2 \ + --hash=sha256:4ae14a42d8adba3205ebeb38aa68cfc0b6c346e1ae2e699a0b3bad4da19cef5c \ + --hash=sha256:7db0c8ea4c7ea51c8049640e8e6e7fde949de672bfa4949920675563a5a6967f +setuptools==44.0.0 \ + --hash=sha256:180081a244d0888b0065e18206950d603f6550721bd6f8c0a10221ed467dd78e \ + --hash=sha256:e5baf7723e5bb8382fc146e33032b241efc63314211a3a120aaa55d62d2bb008 diff --git a/cibuildwheel/util.py b/cibuildwheel/util.py index 7d67d436..28648a18 100644 --- a/cibuildwheel/util.py +++ b/cibuildwheel/util.py @@ -83,4 +83,29 @@ def download(url, dest): response.close() +class DependencyConstraints(object): + def __init__(self, base_file_path): + assert os.path.exists(base_file_path) + self.base_file_path = base_file_path + + @classmethod + def with_defaults(cls): + return cls( + base_file_path=os.path.join(os.path.dirname(__file__), 'resources', 'constraints.txt') + ) + + def get_for_python_version(self, version): + version_parts = version.split('.') + + # try to find a version-specific dependency file e.g. if + # ./constraints.txt is the base, look for ./constraints-python27.txt + base, ext = os.path.splitext(self.base_file_path) + specific = base + '-{}{}'.format(version_parts[0], version_parts[1]) + specific_file_path = specific + ext + if os.path.exists(specific_file_path): + return specific_file_path + else: + return self.base_file_path + + get_pip_script = os.path.abspath(os.path.join(os.path.dirname(__file__), 'resources', 'get-pip.py')) diff --git a/cibuildwheel/windows.py b/cibuildwheel/windows.py index b4e612d0..141b5049 100644 --- a/cibuildwheel/windows.py +++ b/cibuildwheel/windows.py @@ -104,8 +104,12 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef simple_shell(['python', '--version'], env=env) simple_shell(['python', '-c', '"import struct; print(struct.calcsize(\'P\') * 8)\"'], env=env) - dependency_constraint_flags = ['-c', dependency_constraints] if dependency_constraints else [] - + dependency_constraint_flags = [] + if dependency_constraints: + dependency_constraint_flags = [ + '-c', dependency_constraints.get_for_python_version(config.version) + ] + # make sure pip is installed if not os.path.exists(os.path.join(config_python_path, 'Scripts', 'pip.exe')): simple_shell(['python', get_pip_script] + dependency_constraint_flags, env=env, cwd="C:\\cibw") diff --git a/docs/options.md b/docs/options.md index f32305ed..919837d4 100644 --- a/docs/options.md +++ b/docs/options.md @@ -285,6 +285,13 @@ To control the versions of dependencies yourself, you can supply a [pip constraints](https://pip.pypa.io/en/stable/user_guide/#constraints-files) file here and it will be used instead. +!!! note + If you need different dependencies for each python version, provide them + in the same folder with a `-pythonXY` suffix. e.g. if your + `CIBW_DEPENDENCY_VERSIONS=./constraints.txt`, cibuildwheel will use + `./constraints-python27.txt` on Python 2.7, or fallback to + `./constraints.txt` if that's not found. + Platform-specific variants also available:
`CIBW_DEPENDENCY_VERSIONS_MACOS` | `CIBW_DEPENDENCY_VERSIONS_WINDOWS` | `CIBW_DEPENDENCY_VERSIONS_LINUX`