From 87c968bc7df97d5b7938d99073aac3744a80310e Mon Sep 17 00:00:00 2001 From: Christoph Gohlke Date: Tue, 10 Nov 2015 12:57:22 -0800 Subject: [PATCH 01/18] Do not run Windows' file system convert tool --- lib/matplotlib/animation.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index a44ed865cd43..c5dc3c94254a 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -262,6 +262,10 @@ def isAvailable(cls): Check to see if a MovieWriter subclass is actually available by running the commandline tool. ''' + if platform.system() == 'Windows' and cls.bin_path() == 'convert': + # On Windows, the full path to convert must be specified in + # matplotlibrc since convert is also the name of a system tool. + return False try: p = subprocess.Popen(cls.bin_path(), shell=False, From a30ec664e39c27feaef595d2d81046222ec9afee Mon Sep 17 00:00:00 2001 From: Christoph Gohlke Date: Wed, 25 Nov 2015 15:18:29 -0800 Subject: [PATCH 02/18] On Windows, initialize the animation.convert_path setting from the Registry --- lib/matplotlib/animation.py | 27 +++++++++++++++++++++++---- 1 file changed, 23 insertions(+), 4 deletions(-) diff --git a/lib/matplotlib/animation.py b/lib/matplotlib/animation.py index c5dc3c94254a..1667d79a3088 100644 --- a/lib/matplotlib/animation.py +++ b/lib/matplotlib/animation.py @@ -33,7 +33,7 @@ from matplotlib.cbook import iterable, is_string_like from matplotlib.compat import subprocess from matplotlib import verbose -from matplotlib import rcParams +from matplotlib import rcParams, rcParamsDefault # Process creation flag for subprocess to prevent it raising a terminal # window. See for example: @@ -262,9 +262,7 @@ def isAvailable(cls): Check to see if a MovieWriter subclass is actually available by running the commandline tool. ''' - if platform.system() == 'Windows' and cls.bin_path() == 'convert': - # On Windows, the full path to convert must be specified in - # matplotlibrc since convert is also the name of a system tool. + if not cls.bin_path(): return False try: p = subprocess.Popen(cls.bin_path(), @@ -549,6 +547,27 @@ def delay(self): def output_args(self): return [self.outfile] + @classmethod + def _init_from_registry(cls): + if sys.platform != 'win32' or rcParams[cls.exec_key] != 'convert': + return + from matplotlib.externals.six.moves import winreg + for flag in (0, winreg.KEY_WOW64_32KEY, winreg.KEY_WOW64_64KEY): + try: + hkey = winreg.OpenKeyEx(winreg.HKEY_LOCAL_MACHINE, + 'Software\\Imagemagick\\Current', + 0, winreg.KEY_QUERY_VALUE | flag) + binpath = winreg.QueryValueEx(hkey, 'BinPath')[0] + winreg.CloseKey(hkey) + binpath += '\\convert.exe' + break + except Exception: + binpath = '' + rcParams[cls.exec_key] = rcParamsDefault[cls.exec_key] = binpath + + +ImageMagickBase._init_from_registry() + @writers.register('imagemagick') class ImageMagickWriter(MovieWriter, ImageMagickBase): From 94d90750c65d525980713c0c1616542000e238b3 Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Tue, 1 Dec 2015 23:23:38 +0100 Subject: [PATCH 03/18] BLD: add conda patch to generate a version file --- .gitignore | 1 + ci/conda_recipe/condaversion.patch | 14 ++++++++++++++ 2 files changed, 15 insertions(+) create mode 100644 ci/conda_recipe/condaversion.patch diff --git a/.gitignore b/.gitignore index 2b7d5ec615c7..f107d8ec887f 100644 --- a/.gitignore +++ b/.gitignore @@ -80,3 +80,4 @@ setup.cfg .coverage .coverage.* cover/ +__conda_version__.txt diff --git a/ci/conda_recipe/condaversion.patch b/ci/conda_recipe/condaversion.patch new file mode 100644 index 000000000000..c0883d491bca --- /dev/null +++ b/ci/conda_recipe/condaversion.patch @@ -0,0 +1,14 @@ +diff --git setup.py setup.py +index 8af8b6d..4e4f9d2 100644 +--- setup.py ++++ setup.py +@@ -57,6 +57,9 @@ + import versioneer + __version__ = versioneer.get_version() + ++# For conda builds... ++with open("__conda_version__.txt", "w") as f: ++ f.write(__version__) + + # These are the packages in the order we want to display them. This + # list may contain strings to create section headers for the display. From 3aa9eed89c98484142d27d4ae8cc806ea8bdac69 Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Wed, 2 Dec 2015 23:19:38 +0100 Subject: [PATCH 04/18] BLD: Include conda dirs in basedir conda installs includes/libs in \Library, so adding this dir makes installing under conda much easier. --- setupext.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/setupext.py b/setupext.py index 01d482ce58fb..5037a26418bb 100755 --- a/setupext.py +++ b/setupext.py @@ -126,9 +126,15 @@ def get_base_dirs(): """ if options['basedirlist']: return options['basedirlist'] - + + win_bases = ['win32_static', ] + # on windows, we also add the \Library of the local interperter, as + # conda installs libs/includes there + if os.getenv('CONDA_DEFAULT_ENV'): + win_bases.append(os.path.join(os.getenv('CONDA_DEFAULT_ENV'), "Library")) + basedir_map = { - 'win32': ['win32_static', ], + 'win32': win_bases, 'darwin': ['/usr/local/', '/usr', '/usr/X11', '/opt/X11', '/opt/local'], 'sunos5': [os.getenv('MPLIB_BASE') or '/usr/local', ], From d53f9027c94ae8b8638a40f47242a8baa46df30b Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Wed, 2 Dec 2015 23:39:48 +0100 Subject: [PATCH 05/18] BLD: Add a way to influence basedirs with env vars --- setupext.py | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/setupext.py b/setupext.py index 5037a26418bb..7bc52ff9b61e 100755 --- a/setupext.py +++ b/setupext.py @@ -127,9 +127,12 @@ def get_base_dirs(): if options['basedirlist']: return options['basedirlist'] + if os.environ.get('MPLBASEDIRLIST'): + return os.environ.get('MPLBASEDIRLIST').split(os.pathsep) + win_bases = ['win32_static', ] - # on windows, we also add the \Library of the local interperter, as - # conda installs libs/includes there + # on conda windows, we also add the \Library of the local interperter, + # as conda installs libs/includes there if os.getenv('CONDA_DEFAULT_ENV'): win_bases.append(os.path.join(os.getenv('CONDA_DEFAULT_ENV'), "Library")) @@ -149,8 +152,11 @@ def get_include_dirs(): Returns a list of standard include directories on this platform. """ include_dirs = [os.path.join(d, 'include') for d in get_base_dirs()] - include_dirs.extend( - os.environ.get('CPLUS_INCLUDE_PATH', '').split(os.pathsep)) + if sys.platform != 'win32': + # gcc includes this dir automatically, so also look for headers in + # these dirs + include_dirs.extend( + os.environ.get('CPLUS_INCLUDE_PATH', '').split(os.pathsep)) return include_dirs From 659ce45ee37cdf5b8af8db9f74fbafbb689d14b1 Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 17:09:07 +0100 Subject: [PATCH 06/18] BLD: use patched bdist_wheel bdist_wheel currently has a bug when it works with namespaced packages (e.g. all python packages are in lib). The replacement bdist_wheel.run() method implments the patch from https://bitbucket.org/pypa/wheel/issues/91/cannot-create-a-file-when-that-file --- patched_bdist_wheel.py | 103 +++++++++++++++++++++++++++++++++++++++++ setup.py | 12 +++++ 2 files changed, 115 insertions(+) create mode 100644 patched_bdist_wheel.py diff --git a/patched_bdist_wheel.py b/patched_bdist_wheel.py new file mode 100644 index 000000000000..63fc3ec22d16 --- /dev/null +++ b/patched_bdist_wheel.py @@ -0,0 +1,103 @@ +""" +Workaround until https://bitbucket.org/pypa/wheel/issues/91/cannot-create-a-file-when-that-file +is fixed... + +Only one small patch in the os.name == nt case: +- basedir_observed = os.path.join(self.data_dir, '..') ++ basedir_observed = os.path.join(self.data_dir, '..', '.') +""" + +from wheel.bdist_wheel import bdist_wheel +from distutils.sysconfig import get_python_version +from distutils import log as logger +from wheel.archive import archive_wheelfile +import subprocess +import os +from shutil import rmtree + +class patched_bdist_wheel(bdist_wheel): + + def run(self): + build_scripts = self.reinitialize_command('build_scripts') + build_scripts.executable = 'python' + + if not self.skip_build: + self.run_command('build') + + install = self.reinitialize_command('install', + reinit_subcommands=True) + install.root = self.bdist_dir + install.compile = False + install.skip_build = self.skip_build + install.warn_dir = False + + # A wheel without setuptools scripts is more cross-platform. + # Use the (undocumented) `no_ep` option to setuptools' + # install_scripts command to avoid creating entry point scripts. + install_scripts = self.reinitialize_command('install_scripts') + install_scripts.no_ep = True + + # Use a custom scheme for the archive, because we have to decide + # at installation time which scheme to use. + for key in ('headers', 'scripts', 'data', 'purelib', 'platlib'): + setattr(install, + 'install_' + key, + os.path.join(self.data_dir, key)) + + basedir_observed = '' + + if os.name == 'nt': + # win32 barfs if any of these are ''; could be '.'? + # (distutils.command.install:change_roots bug) + # PATCHED... + basedir_observed = os.path.join(self.data_dir, '..', '.') + self.install_libbase = self.install_lib = basedir_observed + + setattr(install, + 'install_purelib' if self.root_is_pure else 'install_platlib', + basedir_observed) + + logger.info("installing to %s", self.bdist_dir) + + self.run_command('install') + + archive_basename = self.get_archive_basename() + + pseudoinstall_root = os.path.join(self.dist_dir, archive_basename) + if not self.relative: + archive_root = self.bdist_dir + else: + archive_root = os.path.join( + self.bdist_dir, + self._ensure_relative(install.install_base)) + + self.set_undefined_options( + 'install_egg_info', ('target', 'egginfo_dir')) + self.distinfo_dir = os.path.join(self.bdist_dir, + '%s.dist-info' % self.wheel_dist_name) + self.egg2dist(self.egginfo_dir, + self.distinfo_dir) + + self.write_wheelfile(self.distinfo_dir) + + self.write_record(self.bdist_dir, self.distinfo_dir) + + # Make the archive + if not os.path.exists(self.dist_dir): + os.makedirs(self.dist_dir) + wheel_name = archive_wheelfile(pseudoinstall_root, archive_root) + + # Sign the archive + if 'WHEEL_TOOL' in os.environ: + subprocess.call([os.environ['WHEEL_TOOL'], 'sign', wheel_name]) + + # Add to 'Distribution.dist_files' so that the "upload" command works + getattr(self.distribution, 'dist_files', []).append( + ('bdist_wheel', get_python_version(), wheel_name)) + + if not self.keep_temp: + if self.dry_run: + logger.info('removing %s', self.bdist_dir) + else: + rmtree(self.bdist_dir) + diff --git a/setup.py b/setup.py index 3e1393e8a6d3..e262db3fbb3a 100644 --- a/setup.py +++ b/setup.py @@ -253,6 +253,18 @@ def run(self): cmdclass['test'] = NoseTestCommand cmdclass['build_ext'] = BuildExtraLibraries +# patch bdist_wheel for a bug on windows +# https://bitbucket.org/pypa/wheel/issues/91/cannot-create-a-file-when-that-file +if os.name == 'nt': + try: + from wheel.bdist_wheel import bdist_wheel + except ImportError: + # No wheel installed, so we also can't run that command... + pass + else: + # patched_bdist_wheel has a run() method, which works on windows + from patched_bdist_wheel import patched_bdist_wheel + cmdclass['bdist_wheel'] = patched_bdist_wheel # One doesn't normally see `if __name__ == '__main__'` blocks in a setup.py, # however, this is needed on Windows to avoid creating infinite subprocesses From 5a7e3b47816ee1abccc3cca6bb9a25bce8448cd6 Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 17:12:00 +0100 Subject: [PATCH 07/18] CI: test in windows and build packages This builds windows conda packages and wheels for some python versions and runs the tests on these python versions on windows. It uses the AppVeyor CI servive and the packages are available as artefacts to download. Appveyor based on http://tjelvarolsson.com/blog/how-to-continuously-test-your-python-code-on-windows-using-appveyor/ https://packaging.python.org/en/latest/appveyor/ https://github.com/rmcgibbo/python-appveyor-conda-example Conda stuff based on https://github.com/conda/conda-recipes/tree/master/matplotlib ...and a lot of trial and error... --- appveyor.yml | 107 +++++++++++++++++++++++++++++ ci/appveyor/install.ps1 | 96 ++++++++++++++++++++++++++ ci/appveyor/run_with_env.cmd | 47 +++++++++++++ ci/conda_recipe/README.md | 3 + ci/conda_recipe/bld.bat | 29 ++++++++ ci/conda_recipe/build.sh | 23 +++++++ ci/conda_recipe/cfg.patch | 13 ++++ ci/conda_recipe/cfg_notests.patch | 13 ++++ ci/conda_recipe/cfg_qt4agg.patch | 11 +++ ci/conda_recipe/meta.yaml | 57 +++++++++++++++ ci/conda_recipe/osx-tk.patch | 60 ++++++++++++++++ ci/conda_recipe/rctmp_pyside.patch | 19 +++++ ci/conda_recipe/run_test.py | 28 ++++++++ ci/conda_recipe/setupext.patch | 30 ++++++++ 14 files changed, 536 insertions(+) create mode 100644 appveyor.yml create mode 100644 ci/appveyor/install.ps1 create mode 100644 ci/appveyor/run_with_env.cmd create mode 100644 ci/conda_recipe/README.md create mode 100644 ci/conda_recipe/bld.bat create mode 100644 ci/conda_recipe/build.sh create mode 100644 ci/conda_recipe/cfg.patch create mode 100644 ci/conda_recipe/cfg_notests.patch create mode 100644 ci/conda_recipe/cfg_qt4agg.patch create mode 100644 ci/conda_recipe/meta.yaml create mode 100644 ci/conda_recipe/osx-tk.patch create mode 100644 ci/conda_recipe/rctmp_pyside.patch create mode 100644 ci/conda_recipe/run_test.py create mode 100644 ci/conda_recipe/setupext.patch diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 000000000000..cd6f63a5e081 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,107 @@ +# With infos from +# http://tjelvarolsson.com/blog/how-to-continuously-test-your-python-code-on-windows-using-appveyor/ +# https://packaging.python.org/en/latest/appveyor/ +# https://github.com/rmcgibbo/python-appveyor-conda-example + +# Backslashes in quotes need to be escaped: \ -> "\\" + +environment: + + global: + # SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the + # /E:ON and /V:ON options are not enabled in the batch script intepreter + # See: http://stackoverflow.com/a/13751649/163740 + CMD_IN_ENV: "cmd /E:ON /V:ON /C .\\ci\\appveyor\\run_with_env.cmd" + + matrix: + - PYTHON: "C:\\Python34_64" + PYTHON_VERSION: "3.4" + PYTHON_ARCH: "64" + CONDA_PY: "34" + CONDA_NPY: "18" + + - PYTHON: "C:\\Python27_64" + PYTHON_VERSION: "2.7" + PYTHON_ARCH: "64" + CONDA_PY: "27" + CONDA_NPY: "18" + + - PYTHON: "C:\\Python27_32" + PYTHON_VERSION: "2.7" + PYTHON_ARCH: "32" + CONDA_PY: "27" + CONDA_NPY: "18" + +# We always use a 64-bit machine, but can build x86 distributions +# with the PYTHON_ARCH variable (which is used by CMD_IN_ENV). +platform: + - x64 + +# all our python builds have to happen in tests_script... +build: false + +init: + - "ECHO %PYTHON_VERSION% %PYTHON%" + +install: + - powershell .\ci\appveyor\install.ps1 + - SET PATH=%PYTHON%;%PYTHON%\Scripts;%PATH% + - cmd: conda config --set show_channel_urls yes + # for msinttypes + - cmd: conda config --add channels conda-forge + # this is now the downloaded conda... + - conda info -a + # same things as in tools/conda_recipe + - cmd: conda create -y -q -n test-environment python=%PYTHON_VERSION% pip setuptools numpy python-dateutil freetype=2.5 msinttypes pyparsing pytz tornado libpng zlib pyqt cycler nose mock + - activate test-environment + # This is needed for the installer to find the dlls... + - set LIBRARY_LIB=%CONDA_DEFAULT_ENV%\Library\lib + - dir %LIBRARY_LIB% + - cmd: 'mkdir lib || cmd /c "exit /b 0"' + - copy %LIBRARY_LIB%\zlibstatic.lib lib\z.lib + - copy %LIBRARY_LIB%\libpng_static.lib lib\png.lib + - set LIB=%LIBRARY_LIB%;.\lib + - set LIBPATH=%LIBRARY_LIB%;.\lib + - set LIB_INC=%CONDA_DEFAULT_ENV%\Library\include + - set INCLUDE=%LIB_INC%;%LIB_INC%\freetype2;WhateverInclude + - set CPLUS_INCLUDE_PATH=%LIB_INC%\freetype2;%LIB_INC%;WhateverCPLUS + - dir %LIB_INC% + - dir %LIB_INC%\freetype2 + # Show the installed packages + versions + - conda list + +test_script: + # Now build the thing.. + - '%CMD_IN_ENV% python setup.py develop' + # tests + # for now, just let them pass to get the after_test parts... + - python tests.py || cmd /c "exit /b 0" + +after_test: + # After the tests were a success, build packages (wheels and conda) + + # There is a bug in wheels which prevents building wheels when the package uses namespaces + - cmd: '%CMD_IN_ENV% python setup.py bdist_wheel' + # Note also that our setup.py script, which is called by conda-build, writes + # a __conda_version__.txt file, so the version number on the binary package + # is set dynamically. This unfortunately mean that conda build --output + # doesn't really work. + - cmd: '%CMD_IN_ENV% conda config --get channels' + # These vars get included in the conda env, so cleanup out current conda env + - set LIB= + - set LIBPATH= + - set INCLUDE= + - set LIB_INC= + - set + # we can't build conda packages on 27 due to missing functools32, which is a recent + # additional dependency for matplotlib + - cmd: if [%CONDA_PY%] NEQ [27] %CMD_IN_ENV% conda build .\ci\conda_recipe + # Move the conda package into the dist directory, to register it + # as an "artifact" for Appveyor. + - cmd: 'copy /Y %PYTHON%\conda-bld\win-32\*.bz2 dist || cmd /c "exit /b 0"' + - cmd: 'copy /Y %PYTHON%\conda-bld\win-64\*.bz2 dist || cmd /c "exit /b 0"' + - cmd: dir .\dist\ + +artifacts: + - path: dist\* + name: packages diff --git a/ci/appveyor/install.ps1 b/ci/appveyor/install.ps1 new file mode 100644 index 000000000000..c964973c6769 --- /dev/null +++ b/ci/appveyor/install.ps1 @@ -0,0 +1,96 @@ +# Sample script to install Miniconda under Windows +# Authors: Olivier Grisel, Jonathan Helmus and Kyle Kastner, Robert McGibbon +# License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ + +$MINICONDA_URL = "http://repo.continuum.io/miniconda/" + + +function DownloadMiniconda ($python_version, $platform_suffix) { + $webclient = New-Object System.Net.WebClient + if ($python_version -match "3.4") { + $filename = "Miniconda3-latest-Windows-" + $platform_suffix + ".exe" + } else { + $filename = "Miniconda-latest-Windows-" + $platform_suffix + ".exe" + } + $url = $MINICONDA_URL + $filename + + $basedir = $pwd.Path + "\" + $filepath = $basedir + $filename + if (Test-Path $filename) { + Write-Host "Reusing" $filepath + return $filepath + } + + # Download and retry up to 3 times in case of network transient errors. + Write-Host "Downloading" $filename "from" $url + $retry_attempts = 2 + for($i=0; $i -lt $retry_attempts; $i++){ + try { + $webclient.DownloadFile($url, $filepath) + break + } + Catch [Exception]{ + Start-Sleep 1 + } + } + if (Test-Path $filepath) { + Write-Host "File saved at" $filepath + } else { + # Retry once to get the error message if any at the last try + $webclient.DownloadFile($url, $filepath) + } + return $filepath +} + + +function InstallMiniconda ($python_version, $architecture, $python_home) { + Write-Host "Installing Python" $python_version "for" $architecture "bit architecture to" $python_home + if (Test-Path $python_home) { + Write-Host $python_home "already exists, skipping." + return $false + } + if ($architecture -match "32") { + $platform_suffix = "x86" + } else { + $platform_suffix = "x86_64" + } + + $filepath = DownloadMiniconda $python_version $platform_suffix + Write-Host "Installing" $filepath "to" $python_home + $install_log = $python_home + ".log" + $args = "/S /D=$python_home" + Write-Host $filepath $args + Start-Process -FilePath $filepath -ArgumentList $args -Wait -Passthru + if (Test-Path $python_home) { + Write-Host "Python $python_version ($architecture) installation complete" + } else { + Write-Host "Failed to install Python in $python_home" + Get-Content -Path $install_log + Exit 1 + } +} + + +function InstallCondaPackages ($python_home, $spec) { + $conda_path = $python_home + "\Scripts\conda.exe" + $args = "install --yes " + $spec + Write-Host ("conda " + $args) + Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru +} + +function UpdateConda ($python_home) { + $conda_path = $python_home + "\Scripts\conda.exe" + Write-Host "Updating conda..." + $args = "update --yes conda" + Write-Host $conda_path $args + Start-Process -FilePath "$conda_path" -ArgumentList $args -Wait -Passthru +} + + +function main () { + InstallMiniconda $env:PYTHON_VERSION $env:PYTHON_ARCH $env:PYTHON + UpdateConda $env:PYTHON + InstallCondaPackages $env:PYTHON "conda-build jinja2 anaconda-client" +} + +main diff --git a/ci/appveyor/run_with_env.cmd b/ci/appveyor/run_with_env.cmd new file mode 100644 index 000000000000..3a472bc836c3 --- /dev/null +++ b/ci/appveyor/run_with_env.cmd @@ -0,0 +1,47 @@ +:: To build extensions for 64 bit Python 3, we need to configure environment +:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) +:: +:: To build extensions for 64 bit Python 2, we need to configure environment +:: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: +:: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) +:: +:: 32 bit builds do not require specific environment configurations. +:: +:: Note: this script needs to be run with the /E:ON and /V:ON flags for the +:: cmd interpreter, at least for (SDK v7.0) +:: +:: More details at: +:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows +:: http://stackoverflow.com/a/13751649/163740 +:: +:: Author: Olivier Grisel +:: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ +@ECHO OFF + +SET COMMAND_TO_RUN=%* +SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows + +SET MAJOR_PYTHON_VERSION="%PYTHON_VERSION:~0,1%" +IF %MAJOR_PYTHON_VERSION% == "2" ( + SET WINDOWS_SDK_VERSION="v7.0" +) ELSE IF %MAJOR_PYTHON_VERSION% == "3" ( + SET WINDOWS_SDK_VERSION="v7.1" +) ELSE ( + ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" + EXIT 1 +) + +IF "%PYTHON_ARCH%"=="64" ( + ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture + SET DISTUTILS_USE_SDK=1 + SET MSSdk=1 + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 +) ELSE ( + ECHO Using default MSVC build environment for 32 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT 1 +) diff --git a/ci/conda_recipe/README.md b/ci/conda_recipe/README.md new file mode 100644 index 000000000000..7819c9f0c766 --- /dev/null +++ b/ci/conda_recipe/README.md @@ -0,0 +1,3 @@ +# conda package + +Up to now, this is mainly used to build a test conda package on windows on appveyor. \ No newline at end of file diff --git a/ci/conda_recipe/bld.bat b/ci/conda_recipe/bld.bat new file mode 100644 index 000000000000..472c4b97966d --- /dev/null +++ b/ci/conda_recipe/bld.bat @@ -0,0 +1,29 @@ +mkdir lib +copy %LIBRARY_LIB%\zlibstatic.lib lib\z.lib +if errorlevel 1 exit 1 +copy %LIBRARY_LIB%\libpng_static.lib lib\png.lib +if errorlevel 1 exit 1 + +set LIB=%LIB%;.\lib +set LIBPATH=%LIBPATH%;.\lib +set INCLUDE=%LIBRARY_INC%;%LIBRARY_INC%\freetype2;%INCLUDE% + +:: debug... +set + +copy setup.cfg.template setup.cfg +if errorlevel 1 exit 1 + +python setup.py install +if errorlevel 1 exit 1 + +rd /s /q %SP_DIR%\dateutil +rd /s /q %SP_DIR%\numpy + +if "%ARCH%"=="64" ( + set PLAT=win-amd64 +) else ( + set PLAT=win32 +) + +::copy C:\Tcl%ARCH%\bin\t*.dll %SP_DIR%\matplotlib-%PKG_VERSION%-py%PY_VER%-%PLAT%.egg\matplotlib\backends diff --git a/ci/conda_recipe/build.sh b/ci/conda_recipe/build.sh new file mode 100644 index 000000000000..c9ff280da808 --- /dev/null +++ b/ci/conda_recipe/build.sh @@ -0,0 +1,23 @@ +#!/bin/bash + +if [ `uname` == Linux ]; then + pushd $PREFIX/lib + ln -s libtcl8.5.so libtcl.so + ln -s libtk8.5.so libtk.so + popd +fi + +if [ `uname` == Darwin ]; then + sed s:'#ifdef WITH_NEXT_FRAMEWORK':'#if 1':g -i src/_macosx.m +fi + +cp setup.cfg.template setup.cfg || exit 1 + +sed s:/usr/local:$PREFIX:g -i setupext.py + +$PYTHON setup.py install + +rm -rf $SP_DIR/PySide +rm -rf $SP_DIR/__pycache__ +rm -rf $PREFIX/bin/nose* + diff --git a/ci/conda_recipe/cfg.patch b/ci/conda_recipe/cfg.patch new file mode 100644 index 000000000000..765e878812f5 --- /dev/null +++ b/ci/conda_recipe/cfg.patch @@ -0,0 +1,13 @@ +diff --git setup.cfg.template setup.cfg.template +index ba4cde3..8d8b7c5 100644 +--- setup.cfg.template ++++ setup.cfg.template +@@ -63,7 +63,7 @@ + #macosx = auto + #pyside = auto + #qt4agg = auto +-#tkagg = auto ++tkagg = True + #windowing = auto + #wxagg = auto + diff --git a/ci/conda_recipe/cfg_notests.patch b/ci/conda_recipe/cfg_notests.patch new file mode 100644 index 000000000000..e47f9d1619d3 --- /dev/null +++ b/ci/conda_recipe/cfg_notests.patch @@ -0,0 +1,13 @@ +diff --git setup.cfg.template setup.cfg.template +index 09fd92f..2085832 100644 +--- setup.cfg.template ++++ setup.cfg.template +@@ -18,7 +18,7 @@ + # optional. They are all installed by default, but they may be turned + # off here. + # +-#tests = True ++tests = False + #sample_data = True + #toolkits = True + # Tests for the toolkits are only automatically installed \ No newline at end of file diff --git a/ci/conda_recipe/cfg_qt4agg.patch b/ci/conda_recipe/cfg_qt4agg.patch new file mode 100644 index 000000000000..2403b9149fd5 --- /dev/null +++ b/ci/conda_recipe/cfg_qt4agg.patch @@ -0,0 +1,11 @@ +diff --git setup.cfg.template setup.cfg.template +index 8af8b6d..4e4f9d2 100644 +--- setup.cfg.template ++++ setup.cfg.template +@@ -78,5 +78,5 @@ + # if you have disabled the relevent extension modules. Agg will be used + # by default. + # +-#backend = Agg ++backend = Qt4Agg + # diff --git a/ci/conda_recipe/meta.yaml b/ci/conda_recipe/meta.yaml new file mode 100644 index 000000000000..262d2b9667de --- /dev/null +++ b/ci/conda_recipe/meta.yaml @@ -0,0 +1,57 @@ +# stolen from https://github.com/conda/conda-recipes/tree/master/matplotlib + +package: + name: matplotlib-test + version: 1.5.0.9 + +source: + path: ../../ + + patches: + # off for now until there is a way to get the dlls tkagg... + #- setupext.patch + # - cfg.patch + - cfg_notests.patch + - cfg_qt4agg.patch [not osx] + - rctmp_pyside.patch [not osx] + - osx-tk.patch [osx] + - condaversion.patch + +requirements: + build: + - python + - setuptools + - numpy + - python-dateutil + - freetype >=2.5,<2.6 + - pyparsing + - pytz + - py2cairo [linux and py2k] + - tornado + - libpng + - zlib [win] + - msinttypes # this package is from the conda-forge channel! + - pyqt [not osx] + - cycler + #- functools32 [py27] # this is actually not available + + run: + - python + - numpy + - python-dateutil + - freetype [unix] + - pytz + - pyparsing + - py2cairo [linux and py2k] + - libpng [unix] + - pyqt [not osx] + - cycler + +test: + requires: + - nose + - mock + +about: + home: http://matplotlib.sourceforge.net/ + license: PSF-based (http://matplotlib.sourceforge.net/users/license.html) diff --git a/ci/conda_recipe/osx-tk.patch b/ci/conda_recipe/osx-tk.patch new file mode 100644 index 000000000000..e950b3284829 --- /dev/null +++ b/ci/conda_recipe/osx-tk.patch @@ -0,0 +1,60 @@ +diff --git setupext.py setupext.py +index 9219c88..e3a9653 100644 +--- setupext.py ++++ setupext.py +@@ -1334,52 +1334,11 @@ class BackendTkAgg(OptionalBackendPackage): + ext.library_dirs.extend([os.path.join(sys.prefix, 'dlls')]) + + elif sys.platform == 'darwin': +- # this config section lifted directly from Imaging - thanks to +- # the effbot! +- +- # First test for a MacOSX/darwin framework install + from os.path import join, exists +- framework_dirs = [ +- join(os.getenv('HOME'), '/Library/Frameworks'), +- '/Library/Frameworks', +- '/System/Library/Frameworks/', +- ] +- +- # Find the directory that contains the Tcl.framework and +- # Tk.framework bundles. +- tk_framework_found = 0 +- for F in framework_dirs: +- # both Tcl.framework and Tk.framework should be present +- for fw in 'Tcl', 'Tk': +- if not exists(join(F, fw + '.framework')): +- break +- else: +- # ok, F is now directory with both frameworks. Continure +- # building +- tk_framework_found = 1 +- break +- if tk_framework_found: +- # For 8.4a2, we must add -I options that point inside +- # the Tcl and Tk frameworks. In later release we +- # should hopefully be able to pass the -F option to +- # gcc, which specifies a framework lookup path. +- +- tk_include_dirs = [ +- join(F, fw + '.framework', H) +- for fw in ('Tcl', 'Tk') +- for H in ('Headers', 'Versions/Current/PrivateHeaders') +- ] +- +- # For 8.4a2, the X11 headers are not included. Rather +- # than include a complicated search, this is a +- # hard-coded path. It could bail out if X11 libs are +- # not found... + +- # tk_include_dirs.append('/usr/X11R6/include') +- frameworks = ['-framework', 'Tcl', '-framework', 'Tk'] +- ext.include_dirs.extend(tk_include_dirs) +- ext.extra_link_args.extend(frameworks) +- ext.extra_compile_args.extend(frameworks) ++ ext.include_dirs.append(join(sys.prefix, 'include')) ++ ext.libraries.extend(['tk8.5', 'tcl8.5']) ++ ext.library_dirs.append(join(sys.prefix, 'lib')) + + # you're still here? ok we'll try it this way... + else: diff --git a/ci/conda_recipe/rctmp_pyside.patch b/ci/conda_recipe/rctmp_pyside.patch new file mode 100644 index 000000000000..15e97de64541 --- /dev/null +++ b/ci/conda_recipe/rctmp_pyside.patch @@ -0,0 +1,19 @@ +diff --git matplotlibrc.template matplotlibrc.template +index fdbbf26..6902fe9 100644 +--- matplotlibrc.template ++++ matplotlibrc.template +@@ -35,12 +35,12 @@ + # You can also deploy your own backend outside of matplotlib by + # referring to the module name (which must be in the PYTHONPATH) as + # 'module://my_backend'. +-backend : %(backend)s ++backend : Qt4Agg + + # If you are using the Qt4Agg backend, you can choose here + # to use the PyQt4 bindings or the newer PySide bindings to + # the underlying Qt4 toolkit. +-#backend.qt4 : PyQt4 # PyQt4 | PySide ++backend.qt4 : PyQt4 # PyQt4 | PySide + + # Note that this can be overridden by the environment variable + # QT_API used by Enthought Tool Suite (ETS); valid values are diff --git a/ci/conda_recipe/run_test.py b/ci/conda_recipe/run_test.py new file mode 100644 index 000000000000..aa921f2ec384 --- /dev/null +++ b/ci/conda_recipe/run_test.py @@ -0,0 +1,28 @@ +import os +import sys + +import matplotlib +import matplotlib.pyplot +import matplotlib._cntr +import matplotlib._delaunay +import matplotlib._image +import matplotlib._path +import matplotlib._png +import matplotlib._tri +import matplotlib.backends._backend_agg +import matplotlib.ft2font +import matplotlib.ttconv +# currently not working... +#import matplotlib.backends._tkagg + +import pylab +import mpl_toolkits + +if int(os.getenv('GUI_TEST', 0)): + assert matplotlib.rcParams['backend.qt4'] == 'PyQt4' + + import matplotlib.pyplot as plt + plt.ioff() + plt.title('If this window displays, success: CLOSE TO CONTINUE TESTS') + plt.plot([1,2,5,9]) + plt.show() diff --git a/ci/conda_recipe/setupext.patch b/ci/conda_recipe/setupext.patch new file mode 100644 index 000000000000..85268872db3a --- /dev/null +++ b/ci/conda_recipe/setupext.patch @@ -0,0 +1,30 @@ +diff --git setupext.py setupext.py +index 0ae553a..66c6e02 100755 +--- setupext.py ++++ setupext.py +@@ -1425,6 +1425,7 @@ class BackendTkAgg(OptionalBackendPackage): + tk.destroy() + + # Save directories and version string to cache ++# tcl_lib_dir = tk_lib_dir = r'C:\Tcl%d' % (8 * tuple.__itemsize__) + self.tcl_tk_cache = tcl_lib_dir, tk_lib_dir, str(Tkinter.TkVersion)[:3] + return self.tcl_tk_cache + +@@ -1531,13 +1532,10 @@ class BackendTkAgg(OptionalBackendPackage): + def add_flags(self, ext): + if sys.platform == 'win32': + major, minor1, minor2, s, tmp = sys.version_info +- if sys.version_info[0:2] < (3, 4): +- ext.include_dirs.extend(['win32_static/include/tcl85']) +- ext.libraries.extend(['tk85', 'tcl85']) +- else: +- ext.include_dirs.extend(['win32_static/include/tcl86']) +- ext.libraries.extend(['tk86t', 'tcl86t']) +- ext.library_dirs.extend([os.path.join(sys.prefix, 'dlls')]) ++ tcl_dir = r'C:\Tcl%d' % (8 * tuple.__itemsize__) ++ ext.include_dirs.append(os.path.join(tcl_dir, 'include')) ++ ext.library_dirs.append(os.path.join(tcl_dir, 'lib')) ++ ext.libraries.extend(['tk85', 'tcl85']) + + elif sys.platform == 'darwin': + # this config section lifted directly from Imaging - thanks to From aa4d19cc87fc7fb25b4f5427b87572f8ca8e5eb6 Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 13:48:59 +0100 Subject: [PATCH 08/18] BLD: Cleanup env vars after basedir change --- appveyor.yml | 17 ++--------------- ci/conda_recipe/bld.bat | 4 +--- 2 files changed, 3 insertions(+), 18 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index cd6f63a5e081..49ae80792367 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -56,18 +56,11 @@ install: - activate test-environment # This is needed for the installer to find the dlls... - set LIBRARY_LIB=%CONDA_DEFAULT_ENV%\Library\lib - - dir %LIBRARY_LIB% - cmd: 'mkdir lib || cmd /c "exit /b 0"' - copy %LIBRARY_LIB%\zlibstatic.lib lib\z.lib - copy %LIBRARY_LIB%\libpng_static.lib lib\png.lib - - set LIB=%LIBRARY_LIB%;.\lib - - set LIBPATH=%LIBRARY_LIB%;.\lib - - set LIB_INC=%CONDA_DEFAULT_ENV%\Library\include - - set INCLUDE=%LIB_INC%;%LIB_INC%\freetype2;WhateverInclude - - set CPLUS_INCLUDE_PATH=%LIB_INC%\freetype2;%LIB_INC%;WhateverCPLUS - - dir %LIB_INC% - - dir %LIB_INC%\freetype2 - # Show the installed packages + versions + - set MPLBASEDIRLIST=%CONDA_DEFAULT_ENV%\Library\;. + # Show the installed packages + versions - conda list test_script: @@ -87,12 +80,6 @@ after_test: # is set dynamically. This unfortunately mean that conda build --output # doesn't really work. - cmd: '%CMD_IN_ENV% conda config --get channels' - # These vars get included in the conda env, so cleanup out current conda env - - set LIB= - - set LIBPATH= - - set INCLUDE= - - set LIB_INC= - - set # we can't build conda packages on 27 due to missing functools32, which is a recent # additional dependency for matplotlib - cmd: if [%CONDA_PY%] NEQ [27] %CMD_IN_ENV% conda build .\ci\conda_recipe diff --git a/ci/conda_recipe/bld.bat b/ci/conda_recipe/bld.bat index 472c4b97966d..cd1ccc534666 100644 --- a/ci/conda_recipe/bld.bat +++ b/ci/conda_recipe/bld.bat @@ -4,9 +4,7 @@ if errorlevel 1 exit 1 copy %LIBRARY_LIB%\libpng_static.lib lib\png.lib if errorlevel 1 exit 1 -set LIB=%LIB%;.\lib -set LIBPATH=%LIBPATH%;.\lib -set INCLUDE=%LIBRARY_INC%;%LIBRARY_INC%\freetype2;%INCLUDE% +set MPLBASEDIRLIST=%LIBRARY_PREFIX%;. :: debug... set From 5ac30449199afa5af23848af177aba0d7706c0fd Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 15:11:24 +0100 Subject: [PATCH 09/18] BLD: also find newer freetype --- setupext.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/setupext.py b/setupext.py index 7bc52ff9b61e..488abc52e72e 100755 --- a/setupext.py +++ b/setupext.py @@ -918,7 +918,10 @@ def check(self): return "Using local version for testing" if sys.platform == 'win32': - check_include_file(get_include_dirs(), 'ft2build.h', 'freetype') + try: + check_include_file(get_include_dirs(), 'ft2build.h', 'freetype') + except CheckFailed: + check_include_file(get_include_dirs(), 'freetype2\\ft2build.h', 'freetype') return 'Using unknown version found on system.' status, output = getstatusoutput("freetype-config --ftversion") From da4a60398ce792fcf2855495eebd3ce569f734db Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 16:34:28 +0100 Subject: [PATCH 10/18] BLD: Find tcl/tk on conda windows --- setupext.py | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/setupext.py b/setupext.py index 488abc52e72e..b3438fa8cf1c 100755 --- a/setupext.py +++ b/setupext.py @@ -1594,14 +1594,22 @@ def hardcoded_tcl_config(self): def add_flags(self, ext): if sys.platform == 'win32': - major, minor1, minor2, s, tmp = sys.version_info - if sys.version_info[0:2] < (3, 4): - ext.include_dirs.extend(['win32_static/include/tcl85']) + if os.getenv('CONDA_DEFAULT_ENV'): + # We are in conda and conda builds against tcl85 for all versions + # includes are directly in the conda\library\include dir and + # libs in DLL or lib + ext.include_dirs.extend(['include']) ext.libraries.extend(['tk85', 'tcl85']) + ext.library_dirs.extend(['dlls']) # or lib? else: - ext.include_dirs.extend(['win32_static/include/tcl86']) - ext.libraries.extend(['tk86t', 'tcl86t']) - ext.library_dirs.extend([os.path.join(sys.prefix, 'dlls')]) + major, minor1, minor2, s, tmp = sys.version_info + if sys.version_info[0:2] < (3, 4): + ext.include_dirs.extend(['win32_static/include/tcl85']) + ext.libraries.extend(['tk85', 'tcl85']) + else: + ext.include_dirs.extend(['win32_static/include/tcl86']) + ext.libraries.extend(['tk86t', 'tcl86t']) + ext.library_dirs.extend([os.path.join(sys.prefix, 'dlls')]) elif sys.platform == 'darwin': # this config section lifted directly from Imaging - thanks to From 99e71f74692556ee0ca64b4418f5dde581c28882 Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 16:35:04 +0100 Subject: [PATCH 11/18] CI: Enable tk again --- appveyor.yml | 2 +- ci/conda_recipe/bld.bat | 8 -------- ci/conda_recipe/cfg.patch | 13 ------------- ci/conda_recipe/meta.yaml | 16 ++++++++++------ ci/conda_recipe/run_test.py | 3 +-- ci/conda_recipe/setupext.patch | 30 ------------------------------ 6 files changed, 12 insertions(+), 60 deletions(-) delete mode 100644 ci/conda_recipe/cfg.patch delete mode 100644 ci/conda_recipe/setupext.patch diff --git a/appveyor.yml b/appveyor.yml index 49ae80792367..f44c89510562 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -52,7 +52,7 @@ install: # this is now the downloaded conda... - conda info -a # same things as in tools/conda_recipe - - cmd: conda create -y -q -n test-environment python=%PYTHON_VERSION% pip setuptools numpy python-dateutil freetype=2.5 msinttypes pyparsing pytz tornado libpng zlib pyqt cycler nose mock + - cmd: conda create -y -q -n test-environment python=%PYTHON_VERSION% pip setuptools numpy python-dateutil freetype=2.5 msinttypes tk pyparsing pytz tornado libpng zlib pyqt cycler nose mock - activate test-environment # This is needed for the installer to find the dlls... - set LIBRARY_LIB=%CONDA_DEFAULT_ENV%\Library\lib diff --git a/ci/conda_recipe/bld.bat b/ci/conda_recipe/bld.bat index cd1ccc534666..fb7909de3362 100644 --- a/ci/conda_recipe/bld.bat +++ b/ci/conda_recipe/bld.bat @@ -17,11 +17,3 @@ if errorlevel 1 exit 1 rd /s /q %SP_DIR%\dateutil rd /s /q %SP_DIR%\numpy - -if "%ARCH%"=="64" ( - set PLAT=win-amd64 -) else ( - set PLAT=win32 -) - -::copy C:\Tcl%ARCH%\bin\t*.dll %SP_DIR%\matplotlib-%PKG_VERSION%-py%PY_VER%-%PLAT%.egg\matplotlib\backends diff --git a/ci/conda_recipe/cfg.patch b/ci/conda_recipe/cfg.patch deleted file mode 100644 index 765e878812f5..000000000000 --- a/ci/conda_recipe/cfg.patch +++ /dev/null @@ -1,13 +0,0 @@ -diff --git setup.cfg.template setup.cfg.template -index ba4cde3..8d8b7c5 100644 ---- setup.cfg.template -+++ setup.cfg.template -@@ -63,7 +63,7 @@ - #macosx = auto - #pyside = auto - #qt4agg = auto --#tkagg = auto -+tkagg = True - #windowing = auto - #wxagg = auto - diff --git a/ci/conda_recipe/meta.yaml b/ci/conda_recipe/meta.yaml index 262d2b9667de..16101f30131e 100644 --- a/ci/conda_recipe/meta.yaml +++ b/ci/conda_recipe/meta.yaml @@ -1,4 +1,5 @@ # stolen from https://github.com/conda/conda-recipes/tree/master/matplotlib +# selectors [py27] and comments need to be `# [selector] comment` not `[sel] # comment` package: name: matplotlib-test @@ -6,15 +7,16 @@ package: source: path: ../../ - + patches: - # off for now until there is a way to get the dlls tkagg... - #- setupext.patch - # - cfg.patch + # don't run nosetest - cfg_notests.patch + # nake Qt4Agg the default backend - cfg_qt4agg.patch [not osx] - rctmp_pyside.patch [not osx] + # tk work on OSX - osx-tk.patch [osx] + # dynamic version from git - condaversion.patch requirements: @@ -33,7 +35,8 @@ requirements: - msinttypes # this package is from the conda-forge channel! - pyqt [not osx] - cycler - #- functools32 [py27] # this is actually not available + - tk + #- functools32 [py27] # this is currently not available run: - python @@ -46,7 +49,8 @@ requirements: - libpng [unix] - pyqt [not osx] - cycler - + - tk + test: requires: - nose diff --git a/ci/conda_recipe/run_test.py b/ci/conda_recipe/run_test.py index aa921f2ec384..37c11af85bf9 100644 --- a/ci/conda_recipe/run_test.py +++ b/ci/conda_recipe/run_test.py @@ -12,8 +12,7 @@ import matplotlib.backends._backend_agg import matplotlib.ft2font import matplotlib.ttconv -# currently not working... -#import matplotlib.backends._tkagg +import matplotlib.backends._tkagg import pylab import mpl_toolkits diff --git a/ci/conda_recipe/setupext.patch b/ci/conda_recipe/setupext.patch deleted file mode 100644 index 85268872db3a..000000000000 --- a/ci/conda_recipe/setupext.patch +++ /dev/null @@ -1,30 +0,0 @@ -diff --git setupext.py setupext.py -index 0ae553a..66c6e02 100755 ---- setupext.py -+++ setupext.py -@@ -1425,6 +1425,7 @@ class BackendTkAgg(OptionalBackendPackage): - tk.destroy() - - # Save directories and version string to cache -+# tcl_lib_dir = tk_lib_dir = r'C:\Tcl%d' % (8 * tuple.__itemsize__) - self.tcl_tk_cache = tcl_lib_dir, tk_lib_dir, str(Tkinter.TkVersion)[:3] - return self.tcl_tk_cache - -@@ -1531,13 +1532,10 @@ class BackendTkAgg(OptionalBackendPackage): - def add_flags(self, ext): - if sys.platform == 'win32': - major, minor1, minor2, s, tmp = sys.version_info -- if sys.version_info[0:2] < (3, 4): -- ext.include_dirs.extend(['win32_static/include/tcl85']) -- ext.libraries.extend(['tk85', 'tcl85']) -- else: -- ext.include_dirs.extend(['win32_static/include/tcl86']) -- ext.libraries.extend(['tk86t', 'tcl86t']) -- ext.library_dirs.extend([os.path.join(sys.prefix, 'dlls')]) -+ tcl_dir = r'C:\Tcl%d' % (8 * tuple.__itemsize__) -+ ext.include_dirs.append(os.path.join(tcl_dir, 'include')) -+ ext.library_dirs.append(os.path.join(tcl_dir, 'lib')) -+ ext.libraries.extend(['tk85', 'tcl85']) - - elif sys.platform == 'darwin': - # this config section lifted directly from Imaging - thanks to From cdca87950d886804fa380c79122ecf5a217f7afb Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 17:18:49 +0100 Subject: [PATCH 12/18] CI: move travis files to one directory under ci --- .travis.yml | 14 +++++++------- {.travis => ci/travis}/build_children.sh | 0 {.travis => ci/travis}/matplotlibDeployKey.enc | Bin {.travis => ci/travis}/setup.cfg | 0 {.travis => ci/travis}/travis_after_all.py | 0 {tools => ci/travis}/travis_tools.sh | 0 6 files changed, 7 insertions(+), 7 deletions(-) rename {.travis => ci/travis}/build_children.sh (100%) mode change 100755 => 100644 rename {.travis => ci/travis}/matplotlibDeployKey.enc (100%) rename {.travis => ci/travis}/setup.cfg (100%) rename {.travis => ci/travis}/travis_after_all.py (100%) rename {tools => ci/travis}/travis_tools.sh (100%) diff --git a/.travis.yml b/.travis.yml index b749e95781ac..717c6c181187 100644 --- a/.travis.yml +++ b/.travis.yml @@ -50,7 +50,7 @@ matrix: - python: "nightly" before_install: - - source tools/travis_tools.sh + - source ci/travis/travis_tools.sh # Install into our own pristine virtualenv - virtualenv --python=python venv - source venv/bin/activate @@ -90,7 +90,7 @@ install: fc-cache -f -v else # Use the special local version of freetype for testing - cp .travis/setup.cfg . + cp ci/travis/setup.cfg . fi; - pip install -e . @@ -130,10 +130,10 @@ after_success: if [[ $TRAVIS_PULL_REQUEST == false && $TRAVIS_REPO_SLUG == 'matplotlib/matplotlib' && $BUILD_DOCS == true && $TRAVIS_BRANCH == 'master' ]]; then cd $TRAVIS_BUILD_DIR echo "Uploading documentation" - openssl aes-256-cbc -K $encrypted_cc802e084cd0_key -iv $encrypted_cc802e084cd0_iv -in .travis/matplotlibDeployKey.enc -out .travis/matplotlibDeployKey -d + openssl aes-256-cbc -K $encrypted_cc802e084cd0_key -iv $encrypted_cc802e084cd0_iv -in ci/travis/matplotlibDeployKey.enc -out ci/travis/matplotlibDeployKey -d eval `ssh-agent -s` - chmod 600 .travis/matplotlibDeployKey - ssh-add .travis/matplotlibDeployKey + chmod 600 ci/travis/matplotlibDeployKey + ssh-add ci/travis/matplotlibDeployKey cd .. git clone git@github.com:matplotlib/devdocs.git cd devdocs @@ -154,12 +154,12 @@ after_success: [[ $TRAVIS_REPO_SLUG == 'matplotlib/matplotlib' ]] && \ [[ $TRAVIS_BRANCH == 'master' ]]; then cd $TRAVIS_BUILD_DIR - python .travis/travis_after_all.py + python ci/travis/travis_after_all.py export $(cat .to_export_back) if [ "$BUILD_LEADER" = "YES" ]; then if [ "$BUILD_AGGREGATE_STATUS" = "others_succeeded" ]; then echo "All Succeeded! Triggering OSX build..." - ./.travis/build_children.sh + ./ci/travis/build_children.sh else echo "Some Failed; no OSX build" fi diff --git a/.travis/build_children.sh b/ci/travis/build_children.sh old mode 100755 new mode 100644 similarity index 100% rename from .travis/build_children.sh rename to ci/travis/build_children.sh diff --git a/.travis/matplotlibDeployKey.enc b/ci/travis/matplotlibDeployKey.enc similarity index 100% rename from .travis/matplotlibDeployKey.enc rename to ci/travis/matplotlibDeployKey.enc diff --git a/.travis/setup.cfg b/ci/travis/setup.cfg similarity index 100% rename from .travis/setup.cfg rename to ci/travis/setup.cfg diff --git a/.travis/travis_after_all.py b/ci/travis/travis_after_all.py similarity index 100% rename from .travis/travis_after_all.py rename to ci/travis/travis_after_all.py diff --git a/tools/travis_tools.sh b/ci/travis/travis_tools.sh similarity index 100% rename from tools/travis_tools.sh rename to ci/travis/travis_tools.sh From 52a198ebd29f988aa445c96ae8b07d7549330afc Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 17:22:31 +0100 Subject: [PATCH 13/18] CI: make result_images available on appveyor --- appveyor.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/appveyor.yml b/appveyor.yml index f44c89510562..8f25b847a604 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -92,3 +92,7 @@ after_test: artifacts: - path: dist\* name: packages + + - path: result_images\* + name: test result images + type: zip From 1179df765bfb999e91d3087bdc92c2b7216e21e5 Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 17:55:01 +0100 Subject: [PATCH 14/18] TST: workaround for windows --- lib/matplotlib/tests/test_font_manager.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index a02b094d2bfd..a511af1e8718 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -29,9 +29,13 @@ def test_font_priority(): def test_json_serialization(): - with tempfile.NamedTemporaryFile() as temp: - json_dump(fontManager, temp.name) - copy = json_load(temp.name) + # on windows, we can't open a file twice, so save the name and unlink + # manually... + with tempfile.NamedTemporaryFile(delete=False) as temp: + name = temp.name + json_dump(fontManager, name) + copy = json_load(name) + os.remove(name) with warnings.catch_warnings(): warnings.filterwarnings('ignore', 'findfont: Font family.*not found') for prop in ({'family': 'STIXGeneral'}, From b32f9c13a743f4dd70ce9676182cc286d2ab0eef Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 17:56:04 +0100 Subject: [PATCH 15/18] CI: enable py3.5 builds on windows and switch to NP1.10 --- appveyor.yml | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 8f25b847a604..202e26cb4d22 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -18,7 +18,13 @@ environment: PYTHON_VERSION: "3.4" PYTHON_ARCH: "64" CONDA_PY: "34" - CONDA_NPY: "18" + CONDA_NPY: "110" + + - PYTHON: "C:\\Python35_64" + PYTHON_VERSION: "3.5" + PYTHON_ARCH: "64" + CONDA_PY: "35" + CONDA_NPY: "110" - PYTHON: "C:\\Python27_64" PYTHON_VERSION: "2.7" From 1d1660f74e84f334c6241a938a8338c9faefd3ba Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 18:45:37 +0100 Subject: [PATCH 16/18] TST: better workaround for NamedTempfile problem on windows from https://github.com/matplotlib/matplotlib/pull/5278#discussion_r42749345 --- lib/matplotlib/tests/test_font_manager.py | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lib/matplotlib/tests/test_font_manager.py b/lib/matplotlib/tests/test_font_manager.py index a511af1e8718..bb87bebeb999 100644 --- a/lib/matplotlib/tests/test_font_manager.py +++ b/lib/matplotlib/tests/test_font_manager.py @@ -31,11 +31,15 @@ def test_font_priority(): def test_json_serialization(): # on windows, we can't open a file twice, so save the name and unlink # manually... - with tempfile.NamedTemporaryFile(delete=False) as temp: - name = temp.name - json_dump(fontManager, name) - copy = json_load(name) - os.remove(name) + try: + name = None + with tempfile.NamedTemporaryFile(delete=False) as temp: + name = temp.name + json_dump(fontManager, name) + copy = json_load(name) + finally: + if name and os.path.exists(name): + os.remove(name) with warnings.catch_warnings(): warnings.filterwarnings('ignore', 'findfont: Font family.*not found') for prop in ({'family': 'STIXGeneral'}, From 14fcb76ef437fd5cc5b1733b37bd602790d2c0ad Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Thu, 3 Dec 2015 19:33:10 +0100 Subject: [PATCH 17/18] CI: use default env vars on py35 3.5 does not need a sdk, so don't set the variables in that case... --- ci/appveyor/run_with_env.cmd | 57 ++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 15 deletions(-) diff --git a/ci/appveyor/run_with_env.cmd b/ci/appveyor/run_with_env.cmd index 3a472bc836c3..5000c483f2f9 100644 --- a/ci/appveyor/run_with_env.cmd +++ b/ci/appveyor/run_with_env.cmd @@ -17,31 +17,58 @@ :: :: Author: Olivier Grisel :: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ -@ECHO OFF +::@ECHO OFF SET COMMAND_TO_RUN=%* SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows -SET MAJOR_PYTHON_VERSION="%PYTHON_VERSION:~0,1%" -IF %MAJOR_PYTHON_VERSION% == "2" ( - SET WINDOWS_SDK_VERSION="v7.0" -) ELSE IF %MAJOR_PYTHON_VERSION% == "3" ( - SET WINDOWS_SDK_VERSION="v7.1" +:: unquote +call :unquote PYTHON_VERSION %PYTHON_VERSION% +SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1% +IF "%PYTHON_VERSION:~1,1%" == "." ( + :: CONDA_PY style, such as 27, 34 etc. + SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~1,1% +) ELSE ( + IF "%PYTHON_VERSION:~3,1%" == "." ( + SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% + ) ELSE ( + SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2% + ) +) +SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% +set USE_MS_SDK=N +IF %MAJOR_PYTHON_VERSION% == 2 ( + SET WINDOWS_SDK_VERSION=v7.0 + set USE_MS_SDK=Y +) ELSE IF %MAJOR_PYTHON_VERSION% == 3 ( + rem py3.5 does not need a sdk set... + IF %MINOR_PYTHON_VERSION% LEQ 4 ( + SET WINDOWS_SDK_VERSION=v7.1 + set USE_MS_SDK=Y + ) ) ELSE ( ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" EXIT 1 ) +SET WINDOWS_SDK_VERSION=%WINDOWS_SDK_VERSION% IF "%PYTHON_ARCH%"=="64" ( - ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture - SET DISTUTILS_USE_SDK=1 - SET MSSdk=1 - "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% - "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release - ECHO Executing: %COMMAND_TO_RUN% - call %COMMAND_TO_RUN% || EXIT 1 + IF "%USE_MS_SDK%" == "N" ( + echo Using the happy new world of py35+ auto configuring compilers.... + ) ELSE ( + ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION%.%MINOR_PYTHON_VERSION% on a 64 bit architecture + SET DISTUTILS_USE_SDK=1 + SET MSSdk=1 + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% + "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release + ) ) ELSE ( ECHO Using default MSVC build environment for 32 bit architecture - ECHO Executing: %COMMAND_TO_RUN% - call %COMMAND_TO_RUN% || EXIT 1 ) +ECHO Executing: %COMMAND_TO_RUN% +call %COMMAND_TO_RUN% || EXIT 1 +goto :EOF + +:unquote + set %1=%~2 + goto :EOF From 3d942f7442b552c9cda1a8862af5c22280d8e4a3 Mon Sep 17 00:00:00 2001 From: Jan Schulz Date: Fri, 4 Dec 2015 01:43:04 +0100 Subject: [PATCH 18/18] CI: replace the run_with_env.cmd script I have no idea what is wrong with it and the easiest way would be to replace it with one which is known to work: https://github.com/pelson/Obvious-CI/blob/master/scripts/obvci_appveyor_python_build_env.cmd --- ci/appveyor/run_with_env.cmd | 91 ++++++++++++++++++++++-------------- 1 file changed, 56 insertions(+), 35 deletions(-) diff --git a/ci/appveyor/run_with_env.cmd b/ci/appveyor/run_with_env.cmd index 5000c483f2f9..848f4608c862 100644 --- a/ci/appveyor/run_with_env.cmd +++ b/ci/appveyor/run_with_env.cmd @@ -1,3 +1,7 @@ +:: EXPECTED ENV VARS: PYTHON_ARCH (either x86 or x64) +:: CONDA_PY (either 27, 33, 35 etc. - only major version is extracted) +:: +:: :: To build extensions for 64 bit Python 3, we need to configure environment :: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of: :: MS Windows SDK for Windows 7 and .NET Framework 4 (SDK v7.1) @@ -6,7 +10,8 @@ :: variables to use the MSVC 2008 C++ compilers from GRMSDKX_EN_DVD.iso of: :: MS Windows SDK for Windows 7 and .NET Framework 3.5 (SDK v7.0) :: -:: 32 bit builds do not require specific environment configurations. +:: 32 bit builds, and 64-bit builds for 3.5 and beyond, do not require specific +:: environment configurations. :: :: Note: this script needs to be run with the /E:ON and /V:ON flags for the :: cmd interpreter, at least for (SDK v7.0) @@ -15,60 +20,76 @@ :: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows :: http://stackoverflow.com/a/13751649/163740 :: -:: Author: Olivier Grisel +:: Author: Phil Elson +:: Original Author: Olivier Grisel (https://github.com/ogrisel/python-appveyor-demo) :: License: CC0 1.0 Universal: http://creativecommons.org/publicdomain/zero/1.0/ -::@ECHO OFF +:: +:: Notes about batch files for Python people: +:: +:: Quotes in values are literally part of the values: +:: SET FOO="bar" +:: FOO is now five characters long: " b a r " +:: If you don't want quotes, don't include them on the right-hand side. +:: +:: The CALL lines at the end of this file look redundant, but if you move them +:: outside of the IF clauses, they do not run properly in the SET_SDK_64==Y +:: case, I don't know why. +:: originally from https://github.com/pelson/Obvious-CI/blob/master/scripts/obvci_appveyor_python_build_env.cmd +@ECHO OFF SET COMMAND_TO_RUN=%* SET WIN_SDK_ROOT=C:\Program Files\Microsoft SDKs\Windows -:: unquote -call :unquote PYTHON_VERSION %PYTHON_VERSION% -SET MAJOR_PYTHON_VERSION=%PYTHON_VERSION:~0,1% -IF "%PYTHON_VERSION:~1,1%" == "." ( +:: Extract the major and minor versions, and allow for the minor version to be +:: more than 9. This requires the version number to have two dots in it. +SET MAJOR_PYTHON_VERSION=%CONDA_PY:~0,1% + +IF "%CONDA_PY:~2,1%" == "" ( :: CONDA_PY style, such as 27, 34 etc. - SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~1,1% + SET MINOR_PYTHON_VERSION=%CONDA_PY:~1,1% ) ELSE ( - IF "%PYTHON_VERSION:~3,1%" == "." ( - SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% + IF "%CONDA_PY:~3,1%" == "." ( + SET MINOR_PYTHON_VERSION=%CONDA_PY:~2,1% ) ELSE ( - SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,2% + SET MINOR_PYTHON_VERSION=%CONDA_PY:~2,2% ) ) -SET MINOR_PYTHON_VERSION=%PYTHON_VERSION:~2,1% -set USE_MS_SDK=N + +:: Based on the Python version, determine what SDK version to use, and whether +:: to set the SDK for 64-bit. IF %MAJOR_PYTHON_VERSION% == 2 ( - SET WINDOWS_SDK_VERSION=v7.0 - set USE_MS_SDK=Y -) ELSE IF %MAJOR_PYTHON_VERSION% == 3 ( - rem py3.5 does not need a sdk set... - IF %MINOR_PYTHON_VERSION% LEQ 4 ( - SET WINDOWS_SDK_VERSION=v7.1 - set USE_MS_SDK=Y - ) + SET WINDOWS_SDK_VERSION="v7.0" + SET SET_SDK_64=Y ) ELSE ( - ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" - EXIT 1 + IF %MAJOR_PYTHON_VERSION% == 3 ( + SET WINDOWS_SDK_VERSION="v7.1" + IF %MINOR_PYTHON_VERSION% LEQ 4 ( + SET SET_SDK_64=Y + ) ELSE ( + SET SET_SDK_64=N + ) + ) ELSE ( + ECHO Unsupported Python version: "%MAJOR_PYTHON_VERSION%" + EXIT /B 1 + ) ) -SET WINDOWS_SDK_VERSION=%WINDOWS_SDK_VERSION% IF "%PYTHON_ARCH%"=="64" ( - IF "%USE_MS_SDK%" == "N" ( - echo Using the happy new world of py35+ auto configuring compilers.... - ) ELSE ( - ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION%.%MINOR_PYTHON_VERSION% on a 64 bit architecture + IF %SET_SDK_64% == Y ( + ECHO Configuring Windows SDK %WINDOWS_SDK_VERSION% for Python %MAJOR_PYTHON_VERSION% on a 64 bit architecture SET DISTUTILS_USE_SDK=1 SET MSSdk=1 "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Setup\WindowsSdkVer.exe" -q -version:%WINDOWS_SDK_VERSION% "%WIN_SDK_ROOT%\%WINDOWS_SDK_VERSION%\Bin\SetEnv.cmd" /x64 /release + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT /B 1 + ) ELSE ( + ECHO Using default MSVC build environment for 64 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT /B 1 ) ) ELSE ( ECHO Using default MSVC build environment for 32 bit architecture + ECHO Executing: %COMMAND_TO_RUN% + call %COMMAND_TO_RUN% || EXIT /B 1 ) -ECHO Executing: %COMMAND_TO_RUN% -call %COMMAND_TO_RUN% || EXIT 1 -goto :EOF - -:unquote - set %1=%~2 - goto :EOF