Skip to content

Commit 8b2ede0

Browse files
committed
Merge pull request pypa#191 from pfmoore/appveyor-revision
Revise and simplify Appveyor usage instructions
2 parents 49b1365 + 52f0bbb commit 8b2ede0

File tree

5 files changed

+173
-235
lines changed

5 files changed

+173
-235
lines changed

source/appveyor.rst

Lines changed: 125 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
=================================================
2-
Building Binary Wheels for Windows using Appveyor
3-
=================================================
1+
=================================
2+
Supporting Windows using Appveyor
3+
=================================
44

55
:Page Status: Incomplete
6-
:Last Reviewed: 2014-09-27
6+
:Last Reviewed: 2015-12-03
77

88
This section covers how to use the free `Appveyor`_ continuous integration
9-
service to build Windows-targeted binary wheels for your project.
9+
service to provide Windows support for your project. This includes testing
10+
the code on Windows, and building Windows-targeted binaries for projects
11+
that use C extensions.
1012

1113
.. contents:: Contents
1214
:local:
@@ -15,19 +17,23 @@ service to build Windows-targeted binary wheels for your project.
1517
Background
1618
==========
1719

18-
Windows users typically do not have access to a C compiler, and therefore are
19-
reliant on projects that use C extensions distributing binary wheels on PyPI in
20-
order for the distribution to be installable via ``pip install dist``.
21-
However, it is often the case that projects which are intended to be
22-
cross-platform are developed on Unix, and so the project developers *also* have
23-
the problem of lack of access to a Windows compiler.
20+
Many projects are developed on Unix by default, and providing Windows support
21+
can be a challenge, because setting up a suitable Windows test environment is
22+
non-trivial, and may require buying software licenses.
2423

2524
The Appveyor service is a continuous integration service, much like the
2625
better-known `Travis`_ service that is commonly used for testing by projects
2726
hosted on `Github`_. However, unlike Travis, the build workers on Appveyor are
2827
Windows hosts and have the necessary compilers installed to build Python
2928
extensions.
3029

30+
Windows users typically do not have access to a C compiler, and therefore are
31+
reliant on projects that use C extensions distributing binary wheels on PyPI in
32+
order for the distribution to be installable via ``pip install <dist>``. By
33+
using Appveyor as a build service (even if not using it for testing) it is
34+
possible for projects without a dedicated Windows environment to provide
35+
Windows-targeted binaries.
36+
3137
Setting Up
3238
==========
3339

@@ -52,6 +58,13 @@ In order to define how Appveyor should build your project, you need to add an
5258
in the file are covered in the Appveyor documentation. This guide will provide
5359
the details necessary to set up wheel builds.
5460

61+
Appveyor includes by default all of the compiler toolchains needed to build
62+
extensions for Python. For Python 2.7, 3.5+ and 32-bit versions of 3.3 and 3.4,
63+
the tools work out of the box. But for 64-bit versions of Python 3.3 and 3.4,
64+
there is a small amount of additional configuration needed to let distutils
65+
know where to find the 64-bit compilers. (From 3.5 onwards, the version of
66+
Visual Studio used includes 64-bit compilers with no additional setup).
67+
5568
appveyor.yml
5669
------------
5770

@@ -65,54 +78,59 @@ The ``appveyor.yml`` file must be located in the root directory of your
6578
project. It is in ``YAML`` format, and consists of a number of sections.
6679

6780
The ``environment`` section is the key to defining the Python versions for
68-
which your wheels will be created. Appveyor comes with Python 2.7, 3.3 and 3.4
69-
installed, in both 32-bit and 64-bit builds. The example file builds for all of
70-
these environments.
71-
72-
The ``install`` section installs any additional software that the project may
73-
require. The supplied code installs ``pip`` (if needed) and ``wheel``. Projects
74-
may wish to customise this code in certain circumstances (for example, to install
75-
additional build packages such as ``Cython``, or test tools such as ``tox``).
81+
which your wheels will be created. Appveyor comes with Python 2.6, 2.7, 3.3,
82+
3.4 and 3.5 installed, in both 32-bit and 64-bit builds. The example file
83+
builds for all of these environments except Python 2.6. Installing for Python
84+
2.6 is more complex, as it does not come with pip included. We don't support
85+
2.6 in this document (as Windows users still using Python 2 are generally able
86+
to move to Python 2.7 without too much difficulty).
87+
88+
The ``install`` section uses pip to install any additional software that the
89+
project may require. The only requirement for building wheels is the ``wheel``
90+
project, but projects may wish to customise this code in certain circumstances
91+
(for example, to install additional build packages such as ``Cython``, or test
92+
tools such as ``tox``).
7693

7794
The ``build`` section simply switches off builds - there is no build step needed
7895
for Python, unlike languages like ``C#``.
7996

80-
The ``test_script`` section is technically not needed. The supplied file runs
81-
your test suite using ``setup.py test``. You may wish to use another test tool
82-
such as ``tox`` or ``py.test``. Or you could skip the test (but why would you,
83-
unless your tests are expected to fail on Windows?) by replacing the script with
84-
a simple ``echo Skipped`` command.
97+
The main sections that will need to be tailored to your project are ``test_script``
98+
and ``after_test``.
99+
100+
The ``test_script`` section is where you will run your project's tests. The
101+
supplied file runs your test suite using ``setup.py test``. If you are only
102+
interested in building wheels, and not in running your tests on Windows, you
103+
can replace this section with a dummy command such as ``echo Skipped Tests``.
104+
You may wish to use another test tool, such as ``nose`` or ``py.test``. Or you
105+
may wish to use a test driver like ``tox`` - however if you are using ``tox``
106+
there are some additional configuration changes you will need to consider,
107+
which are described below.
85108

86-
The ``after_test`` command is where the wheels are built. Assuming your project
87-
uses the recommended tools (specifically, ``setuptools``) then the
88-
``setup.py bdist_wheel`` command will build your wheels.
109+
The ``after_test`` runs once your tests have completed, and so is where the
110+
wheels should be built. Assuming your project uses the recommended tools
111+
(specifically, ``setuptools``) then the ``setup.py bdist_wheel`` command
112+
will build your wheels.
89113

90114
Note that wheels will only be built if your tests succeed. If you expect your
91115
tests to fail on Windows, you can skip them as described above.
92116

93117

94-
Support scripts
95-
---------------
118+
Support script
119+
--------------
96120

97-
The ``appveyor.yml`` file relies on two support scripts. The code assumes that
98-
these will be placed in a subdirectory named ``appveyor`` at the root of your
99-
project.
121+
The ``appveyor.yml`` file relies on a single support script, which sets up the
122+
environment to use the SDK compiler for 64-bit builds on Python 3.3 and 3.4.
123+
For projects which do not need a compiler, or which don't support 3.3 or 3.4 on
124+
64-bit Windows, only the ``appveyor.yml`` file is needed.
100125

101-
`appveyor/run_with_compiler.cmd <https://raw.githubusercontent.com/pypa/python-packaging-user-guide/master/source/code/run_with_compiler.cmd>`__
126+
`build.cmd <https://raw.githubusercontent.com/pypa/python-packaging-user-guide/master/source/code/build.cmd>`__
102127
is a Windows batch script that runs a single command in an environment with the
103-
appropriate compiler for the selected Python version.
128+
appropriate compiler for the selected Python version. All you need to do is to
129+
set the single environment variable ``DISTUTILS_USE_SDK`` to a value of ``1``
130+
and the script does the rest. It sets up the SDK needed for 64-bit builds of
131+
Python 3.3 or 3.4, so don't set the environment variable for any other builds.
104132

105-
`appveyor/install.ps1 <https://raw.githubusercontent.com/pypa/python-packaging-user-guide/master/source/code/install.ps1>`__ is a Powershell
106-
script that downloads and installs any missing Python versions, installs
107-
``pip`` into the Python ``site-packages`` and downloads and installs the latest
108-
``wheel`` distribution. Steps that are not needed are omitted, so in practice,
109-
the Python install will never be run (it is present for advanced users who want
110-
to install additional versions of Python not supplied by Appveyor) and the
111-
``pip`` install will be omitted for Python 3.4, where pip is installed as
112-
standard.
113-
114-
You can simply download these two files and include them in your project
115-
unchanged.
133+
You can simply download the batch file and include it in your project unchanged.
116134

117135

118136
Access to the built wheels
@@ -128,6 +146,57 @@ wheels and upload them to PyPI as part of your release process.
128146
Additional Notes
129147
================
130148

149+
Testing with tox
150+
----------------
151+
152+
Many projects use the `Tox`_ tool to run their tests. It ensures that tests
153+
are run in an isolated environment using the exact files that will be distributed
154+
by the project.
155+
156+
In order to use ``tox`` on Appveyor there are a couple of additional considerations
157+
(in actual fact, these issues are not specific to Appveyor, and may well affect
158+
other CI systems).
159+
160+
1. By default, ``tox`` only passes a chosen subset of environment variables to the
161+
test processes. Because ``distutils`` uses environment variables to control the
162+
compiler, this "test isolation" feature will cause the tests to use the wrong
163+
compiler by default.
164+
165+
To force ``tox`` to pass the necessary environment variables to the subprocess,
166+
you need to set the ``tox`` configuration option ``passenv`` to list the additional
167+
environment variables to be passed to the subprocess. For the SDK compilers, you
168+
need
169+
170+
- ``DISTUTILS_USE_SDK``
171+
- ``MSSdk``
172+
- ``INCLUDE``
173+
- ``LIB``
174+
175+
The ``passenv`` option can be set in your ``tox.ini``, or if you prefer to avoid
176+
adding Windows-specific settings to your general project files, it can be set by
177+
setting the ``TOX_TESTENV_PASSENV`` environment variable. The supplied ``build.cmd``
178+
script does this by default whenever ``DISTUTILS_USE_SDK`` is set.
179+
180+
2. When used interactively, ``tox`` allows you to run your tests against multiple
181+
environments (often, this means multiple Python versions). This feature is not as
182+
useful in a CI environment like Travis or Appveyor, where all tests are run in
183+
isolated environments for each configuration. As a result, projects often supply
184+
an argument ``-e ENVNAME`` to ``tox`` to specify which environment to use (there
185+
are default environments for most versions of Python).
186+
187+
However, this does *not* work well with a Windows CI system like Appveyor, where
188+
there are (for example) two installations of Python 3.4 (32-bit and 64-bit)
189+
available, but only one ``py34`` environment in ``tox``.
190+
191+
In order to run tests using ``tox``, therefore, projects should probably use the
192+
default ``py`` environment in ``tox``, which uses the Python interpreter that
193+
was used to run ``tox``. This will ensure that when Appveyor runs the tests, they
194+
will be run with the configured interpreter.
195+
196+
In order to support running under the ``py`` environment, it is possible that
197+
projects with complex ``tox`` configurations might need to modify their ``tox.ini``
198+
file. Doing so is, however, outside the scope of this document.
199+
131200
Automatically uploading wheels
132201
------------------------------
133202

@@ -145,32 +214,28 @@ External dependencies
145214
---------------------
146215

147216
The supplied scripts will successfully build any distribution that does not
148-
rely on 3rd party external libraries for the build. It would be possible for an
149-
individual project to add code to the ``install.ps1`` script to make external
150-
libraries available to the build, but this is of necessity specific to
151-
individual projects.
217+
rely on 3rd party external libraries for the build.
218+
219+
It is possible to add steps to the ``appveyor.yml`` configuration (typically
220+
in the "install" section) to download and/or build external libraries needed by
221+
the distribution. And if needed, it is possible to add extra configuration for
222+
the build to supply the location of these libraries to the compiler. However,
223+
this level of configuration is beyond the scope of this document.
152224

153-
Should projects develop scripts showing how to do this, references will be
154-
added to this guide at a later date.
155225

156226
Support scripts
157227
---------------
158228

159-
For reference, the two support scripts are listed here:
229+
For reference, the SDK setup support script is listed here:
160230

161-
``code/run_with_compiler.cmd``
231+
``code/build.cmd``
162232

163-
.. literalinclude:: code/run_with_compiler.cmd
233+
.. literalinclude:: code/build.cmd
164234
:language: bat
165235
:linenos:
166236

167-
``code/install.ps1``
168-
169-
.. literalinclude:: code/install.ps1
170-
:language: powershell
171-
:linenos:
172-
173237
.. _Appveyor: http://www.appveyor.com/
174238
.. _Travis: https://travis-ci.org/
175239
.. _Github: https://github.org/
176240
.. _Bitbucket: https://bitbucket.org/
241+
.. _Tox: http://tox.testrun.org

source/code/appveyor.yml

Lines changed: 27 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,51 @@
11
environment:
22

3-
global:
4-
# SDK v7.0 MSVC Express 2008's SetEnv.cmd script will fail if the
5-
# /E:ON and /V:ON options are not enabled in the batch script intepreter
6-
# See: http://stackoverflow.com/a/13751649/163740
7-
WITH_COMPILER: "cmd /E:ON /V:ON /C .\\appveyor\\run_with_compiler.cmd"
8-
93
matrix:
104

11-
# Pre-installed Python versions, which Appveyor may upgrade to
12-
# a later point release.
13-
# See: http://www.appveyor.com/docs/installed-software#python
5+
# For Python versions available on Appveyor, see
6+
# http://www.appveyor.com/docs/installed-software#python
7+
# The list here is complete (excluding Python 2.6, which
8+
# isn't covered by this document) at the time of writing.
149

1510
- PYTHON: "C:\\Python27"
16-
PYTHON_VERSION: "2.7.x" # currently 2.7.9
17-
PYTHON_ARCH: "32"
18-
1911
- PYTHON: "C:\\Python33"
20-
PYTHON_VERSION: "3.3.x" # currently 3.3.5
21-
PYTHON_ARCH: "32"
22-
2312
- PYTHON: "C:\\Python34"
24-
PYTHON_VERSION: "3.4.x" # currently 3.4.3
25-
PYTHON_ARCH: "32"
26-
13+
- PYTHON: "C:\\Python35"
2714
- PYTHON: "C:\\Python27-x64"
28-
PYTHON_VERSION: "2.7.x" # currently 2.7.9
29-
PYTHON_ARCH: "64"
30-
WINDOWS_SDK_VERSION: "v7.0"
31-
3215
- PYTHON: "C:\\Python33-x64"
33-
PYTHON_VERSION: "3.3.x" # currently 3.3.5
34-
PYTHON_ARCH: "64"
35-
WINDOWS_SDK_VERSION: "v7.1"
36-
16+
DISTUTILS_USE_SDK: "1"
3717
- PYTHON: "C:\\Python34-x64"
38-
PYTHON_VERSION: "3.4.x" # currently 3.4.3
39-
PYTHON_ARCH: "64"
40-
WINDOWS_SDK_VERSION: "v7.1"
41-
42-
# Also build on a Python version not pre-installed by Appveyor.
43-
# See: https://github.com/ogrisel/python-appveyor-demo/issues/10
44-
45-
- PYTHON: "C:\\Python266"
46-
PYTHON_VERSION: "2.6.6"
47-
PYTHON_ARCH: "32"
48-
49-
init:
50-
- "ECHO %PYTHON% %PYTHON_VERSION% %PYTHON_ARCH%"
18+
DISTUTILS_USE_SDK: "1"
19+
- PYTHON: "C:\\Python35-x64"
5120

5221
install:
53-
- "powershell appveyor\\install.ps1"
22+
# We need wheel installed to build wheels
23+
- "%PYTHON%\\python.exe -m pip install wheel"
5424

5525
build: off
5626

5727
test_script:
58-
- "%WITH_COMPILER% %PYTHON%/python setup.py test"
28+
# Put your test command here.
29+
# If you don't need to build C extensions on 64-bit Python 3.3 or 3.4,
30+
# you can remove "build.cmd" from the front of the command, as it's
31+
# only needed to support those cases.
32+
# Note that you must use the environment variable %PYTHON% to refer to
33+
# the interpreter you're using - Appveyor does not do anything special
34+
# to put the Python evrsion you want to use on PATH.
35+
- "build.cmd %PYTHON%\\python.exe setup.py test"
5936

6037
after_test:
61-
- "%WITH_COMPILER% %PYTHON%/python setup.py bdist_wheel"
38+
# This step builds your wheels.
39+
# Again, you only need build.cmd if you're building C extensions for
40+
# 64-bit Python 3.3/3.4. And you need to use %PYTHON% to get the correct
41+
# interpreter
42+
- "build.cmd %PYTHON%\\python.exe setup.py bdist_wheel"
6243

6344
artifacts:
45+
# bdist_wheel puts your built wheel in the dist directory
6446
- path: dist\*
6547

6648
#on_success:
67-
# - TODO: upload the content of dist/*.whl to a public wheelhouse
49+
# You can use this step to upload your artifacts to a public website.
50+
# See Appveyor's documentation for more details. Or you can simply
51+
# access your wheels from the Appveyor "artifacts" tab for your build.

source/code/build.cmd

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
@echo off
2+
:: To build extensions for 64 bit Python 3, we need to configure environment
3+
:: variables to use the MSVC 2010 C++ compilers from GRMSDKX_EN_DVD.iso of:
4+
:: MS Windows SDK for Windows 7 and .NET Framework 4
5+
::
6+
:: More details at:
7+
:: https://github.com/cython/cython/wiki/64BitCythonExtensionsOnWindows
8+
9+
IF "%DISTUTILS_USE_SDK%"=="1" (
10+
ECHO Configuring environment to build with MSVC on a 64bit architecture
11+
ECHO Using Windows SDK 7.1
12+
"C:\Program Files\Microsoft SDKs\Windows\v7.1\Setup\WindowsSdkVer.exe" -q -version:v7.1
13+
CALL "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 /release
14+
SET MSSdk=1
15+
REM Need the following to allow tox to see the SDK compiler
16+
SET TOX_TESTENV_PASSENV=DISTUTILS_USE_SDK MSSdk INCLUDE LIB
17+
) ELSE (
18+
ECHO Using default MSVC build environment
19+
)
20+
21+
CALL %*

0 commit comments

Comments
 (0)