diff --git a/cibuildwheel/__main__.py b/cibuildwheel/__main__.py index ce9a72fc..9083707f 100644 --- a/cibuildwheel/__main__.py +++ b/cibuildwheel/__main__.py @@ -203,6 +203,9 @@ def detect_obsolete_options(): if deprecated in os.environ and 'manylinux1' in os.environ[deprecated]: print("Build identifiers with 'manylinux1' been deprecated. Replacing all occurences of 'manylinux1' by 'manylinux' in the option '{}'".format(deprecated)) os.environ[deprecated] = os.environ[deprecated].replace('manylinux1', 'manylinux') + if deprecated in os.environ and ("macosx_10_6" in os.environ[deprecated] or "macosx_10_9" in os.environ[deprecated]): + print("Build identifiers with 'macosx_10_6' or 'macosx_10_9' been deprecated. Replacing with 'macosx' in the option '{}'".format(deprecated)) + os.environ[deprecated] = os.environ[deprecated].replace('macosx_10_6', 'macosx').replace('macosx_10_9', 'macosx') def print_preamble(platform, build_options): diff --git a/cibuildwheel/macos.py b/cibuildwheel/macos.py index e8dfb775..d7cde8bf 100644 --- a/cibuildwheel/macos.py +++ b/cibuildwheel/macos.py @@ -14,11 +14,11 @@ from .util import prepare_command, get_build_verbosity_extra_flags def get_python_configurations(build_selector): PythonConfiguration = namedtuple('PythonConfiguration', ['version', 'identifier', 'url']) python_configurations = [ - PythonConfiguration(version='2.7', identifier='cp27-macosx_10_6_intel', url='https://www.python.org/ftp/python/2.7.17/python-2.7.17-macosx10.6.pkg'), - PythonConfiguration(version='3.5', identifier='cp35-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg'), - PythonConfiguration(version='3.6', identifier='cp36-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.6.pkg'), - PythonConfiguration(version='3.7', identifier='cp37-macosx_10_6_intel', url='https://www.python.org/ftp/python/3.7.6/python-3.7.6-macosx10.6.pkg'), - PythonConfiguration(version='3.8', identifier='cp38-macosx_10_9_x86_64', url='https://www.python.org/ftp/python/3.8.1/python-3.8.1-macosx10.9.pkg'), + PythonConfiguration(version='2.7', identifier='cp27-macosx_intel', url='https://www.python.org/ftp/python/2.7.17/python-2.7.17-macosx10.6.pkg'), + PythonConfiguration(version='3.5', identifier='cp35-macosx_intel', url='https://www.python.org/ftp/python/3.5.4/python-3.5.4-macosx10.6.pkg'), + PythonConfiguration(version='3.6', identifier='cp36-macosx_intel', url='https://www.python.org/ftp/python/3.6.8/python-3.6.8-macosx10.6.pkg'), + PythonConfiguration(version='3.7', identifier='cp37-macosx_intel', url='https://www.python.org/ftp/python/3.7.5/python-3.7.5-macosx10.6.pkg'), + PythonConfiguration(version='3.8', identifier='cp38-macosx_x86_64', url='https://www.python.org/ftp/python/3.8.0/python-3.8.0-macosx10.9.pkg') ] # skip builds as required @@ -96,7 +96,9 @@ def build(project_dir, output_dir, test_command, test_requires, test_extras, bef call(['python', get_pip_script, '--no-setuptools', '--no-wheel'], env=env, cwd="/tmp") assert os.path.exists(os.path.join(installation_bin_path, 'pip')) call(['pip', '--version'], env=env) - call(['pip', 'install', '--upgrade', 'setuptools', 'wheel', 'delocate'], env=env) + call(['pip', 'install', '--upgrade', 'setuptools'], env=env) + call(['pip', 'install', 'git+https://github.com/Czaki/wheel.git@1a907d36eb4921efa0c9e7dce6b570aa5f84d7f5'], env=env) + call(['pip', 'install', 'delocate'], env=env) # run the before_build command if before_build: diff --git a/test/10_cpp_standards/cibuildwheel_test.py b/test/10_cpp_standards/cibuildwheel_test.py new file mode 100644 index 00000000..04734c8b --- /dev/null +++ b/test/10_cpp_standards/cibuildwheel_test.py @@ -0,0 +1,55 @@ +import os +import sys + +import pytest + +import utils + + +def test_cpp11(tmp_path): + add_env = {"CIBW_SKIP": "cp27-win*", "CIBW_ENVIRONMENT": "STANDARD=11"} + # VC for python 2.7 do not support modern standards + if utils.platform == "macos": + add_env["MACOSX_DEPLOYMENT_TARGET"] = "10.9" + project_dir = os.path.dirname(__file__) + # this test checks if c++11 standard is supported. + + actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env) + expected_wheels = [x for x in utils.expected_wheels('spam', '0.1.0', "10.9") if "cp27-cp27m-win" not in x] + assert set(actual_wheels) == set(expected_wheels) + + +def test_cpp14(): + add_env = {"CIBW_SKIP": "cp27-win* cp35-win*", "CIBW_ENVIRONMENT": "STANDARD=14"} + # VC for python 2.7 do not support modern standards + # manylinux1 docker image do not support compilers with standards newer than c++11 + # python 3.4 and 3.5 are compiled with MSVC 10. which not support c++14 + if utils.platform == "macos": + add_env["MACOSX_DEPLOYMENT_TARGET"] = "10.9" + project_dir = os.path.dirname(__file__) + # this test checks if c++14 standard is supported. + + actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env) + expected_wheels = [x for x in utils.expected_wheels('spam', '0.1.0', "10.9") + if "cp27-cp27m-win" not in x and "cp35-cp35m-win" not in x] + assert set(actual_wheels) == set(expected_wheels) + +def test_cpp17(): + # python 2.7 use `register` keyword which is forbidden in c++17 standard + # manylinux1 docker image do not support compilers with standards newer than c++11 + # python 3.4 and 3.5 are compiled with MSVC 10. which not support c++17 + if os.environ.get("APPVEYOR_BUILD_WORKER_IMAGE", "") == "Visual Studio 2015": + pytest.skip("Visual Studio 2015 does not support c++17") + + add_env = {"CIBW_SKIP": "cp27-win* cp35-win*", "CIBW_ENVIRONMENT": "STANDARD=17"} + if utils.platform == "macos": + add_env["MACOSX_DEPLOYMENT_TARGET"] = "10.13" + + project_dir = os.path.dirname(__file__) + # this test checks if c++17 standard is supported. + + actual_wheels = utils.cibuildwheel_run(project_dir, add_env=add_env) + expected_wheels = [x for x in utils.expected_wheels('spam', '0.1.0', "10.13") + if "cp27-cp27m-win" not in x and "cp35-cp35m-win" not in x] + assert set(actual_wheels) == set(expected_wheels) + diff --git a/test/10_cpp_standards/setup.py b/test/10_cpp_standards/setup.py new file mode 100644 index 00000000..85e9492c --- /dev/null +++ b/test/10_cpp_standards/setup.py @@ -0,0 +1,21 @@ +import os, sys +from setuptools import setup, Extension +import platform + +standard = os.environ["STANDARD"] + +language_standard = "/std:c++" + standard if platform.system() == "Windows" else "-std=c++" + standard + +extra_compile_args=[language_standard, "-DSTANDARD=" + standard] + +if standard == "17": + if platform.system() == "Windows": + extra_compile_args.append("/wd5033") + else: + extra_compile_args.append("-Wno-register") + +setup( + name="spam", + ext_modules=[Extension('spam', sources=['spam.cpp'], language="c++", extra_compile_args=extra_compile_args)], + version="0.1.0", +) diff --git a/test/10_cpp_standards/spam.cpp b/test/10_cpp_standards/spam.cpp new file mode 100644 index 00000000..d619c54b --- /dev/null +++ b/test/10_cpp_standards/spam.cpp @@ -0,0 +1,62 @@ +#include +#include +#if STANDARD == 11 +#include +#elif STANDARD == 14 +int a = 100'000; +#elif STANDARD == 17 +#include +auto a = std::pair(5.0, false); +#else +#error Standard needed +#endif + +#define STR_HELPER(x) #x +#define STR(x) STR_HELPER(x) + +static PyObject * +spam_system(PyObject *self, PyObject *args) +{ + const char *command; + int sts; + + if (!PyArg_ParseTuple(args, "s", &command)) + return NULL; + sts = system(command); + return PyLong_FromLong(sts); +} + +/* Module initialization */ + +#if PY_MAJOR_VERSION >= 3 + #define MOD_INIT(name) PyMODINIT_FUNC PyInit_##name(void) + #define MOD_DEF(m, name, doc, methods, module_state_size) \ + static struct PyModuleDef moduledef = { \ + PyModuleDef_HEAD_INIT, name, doc, module_state_size, methods, }; \ + m = PyModule_Create(&moduledef); + #define MOD_RETURN(m) return m; +#else + #define MOD_INIT(name) PyMODINIT_FUNC init##name(void) + #define MOD_DEF(m, name, doc, methods, module_state_size) \ + m = Py_InitModule3(name, methods, doc); + #define MOD_RETURN(m) return; +#endif + +static PyMethodDef module_methods[] = { + {"system", (PyCFunction)spam_system, METH_VARARGS, + "Execute a shell command."}, + {NULL} /* Sentinel */ +}; + +MOD_INIT(spam) +{ + PyObject* m; + + MOD_DEF(m, + "spam", + "Example module", + module_methods, + -1) + + MOD_RETURN(m) +}