diff --git a/.appveyor.yml b/.appveyor.yml
index 4d2cb81d2..8602293f7 100644
--- a/.appveyor.yml
+++ b/.appveyor.yml
@@ -48,8 +48,7 @@ install:
}
else
{
- $env:PILLOW_DEPS = "C:\pillow-depends\"
- c:\python37\python.exe c:\pillow\winbuild\build_prepare.py
+ c:\python37\python.exe c:\pillow\winbuild\build_prepare.py -v --depends=C:\pillow-depends\
c:\pillow\winbuild\build\build_dep_all.cmd
$host.SetShouldExit(0)
}
diff --git a/.github/workflows/test-windows.yml b/.github/workflows/test-windows.yml
index fe958ad5a..fe0fdc04c 100644
--- a/.github/workflows/test-windows.yml
+++ b/.github/workflows/test-windows.yml
@@ -66,12 +66,9 @@ jobs:
..\pillow-depends\gs950w32.exe /S
Write-Host "::add-path::C:\Program Files (x86)\gs\gs9.50\bin"
- $env:PILLOW_DEPS = "$env:RUNNER_WORKSPACE\pillow-depends\"
xcopy /s ..\pillow-depends\test_images\* $env:GITHUB_WORKSPACE\tests\images\
- $env:PYTHON=$env:pythonLocation
- cd $env:GITHUB_WORKSPACE/winbuild/
- & python.exe $env:GITHUB_WORKSPACE\winbuild\build_prepare.py
+ & python.exe $env:GITHUB_WORKSPACE\winbuild\build_prepare.py -v --depends=$env:RUNNER_WORKSPACE\pillow-depends\ --python=$env:pythonLocation
shell: pwsh
- name: Build dependencies / libjpeg-turbo
diff --git a/setup.py b/setup.py
index b55b1de62..1236b5df5 100755
--- a/setup.py
+++ b/setup.py
@@ -120,7 +120,7 @@ _LIB_IMAGING = (
"codec_fd",
)
-DEBUG = True
+DEBUG = False
class DependencyException(Exception):
diff --git a/winbuild/README.md b/winbuild/README.md
index dabbc359a..45c37e4cb 100644
--- a/winbuild/README.md
+++ b/winbuild/README.md
@@ -19,7 +19,7 @@ The following is a simplified version of the script used on AppVeyor:
```
set PYTHON=C:\Python35\bin
cd /D C:\Pillow\winbuild
-C:\Python37\bin\python.exe build_prepare.py
+C:\Python37\bin\python.exe build_prepare.py -v --depends=C:\pillow-depends
build\build_dep_all.cmd
build\build_pillow.cmd install
cd ..
diff --git a/winbuild/build.rst b/winbuild/build.rst
index f47efb363..465bc2591 100644
--- a/winbuild/build.rst
+++ b/winbuild/build.rst
@@ -23,18 +23,20 @@ Compilers
Download and install:
-* `Microsoft Visual Studio 2017 or newer (with C++ component)
- `_
+* `Microsoft Visual Studio 2017 or newer or Build Tools for Visual Studio 2017 or newer
+ `_
+ (MSVC C++ build tools, and any Windows SDK version required)
-* `CMake 3.13 or newer
- `_
+* `CMake 3.13 or newer `_
+ (also available as Visual Studio component C++ CMake tools for Windows)
* `NASM `_
Any version of Visual Studio 2017 or newer should be supported,
-including Visual Studio 2017 Community.
+including Visual Studio 2017 Community, or Build Tools for Visual Studio 2019.
-Paths to CMake and NASM must be added to the ``PATH`` environment variable.
+Paths to CMake (if standalone) and NASM must be added to the ``PATH`` environment variable.
+Visual Studio is found automatically with ``vswhere.exe``.
Build configuration
-------------------
@@ -47,7 +49,7 @@ behaviour of ``build_prepare.py``:
``build_prepare.py`` will be used. If only ``PYTHON`` is set,
``EXECUTABLE`` defaults to ``python.exe``.
* ``ARCHITECTURE`` is used to select a ``x86`` or ``x64`` build. By default,
- ``x86`` is used, unless ``PYTHON`` contains ``x64``, in which case ``x64``
+ uses same architecture as the version of Python used to run ``build_prepare.py``.
is used.
* ``PILLOW_BUILD`` can be used to override the ``winbuild\build`` directory
path, used to store generated build scripts and compiled libraries.
@@ -55,6 +57,17 @@ behaviour of ``build_prepare.py``:
* ``PILLOW_DEPS`` points to the directory used to store downloaded
dependencies. By default ``winbuild\depends`` is used.
+``build_prepare.py`` also supports the following command line parameters:
+
+* ``-v`` will print generated scripts.
+* ``--no-imagequant`` will skip GPL-licensed ``libimagequant`` optional dependency
+* ``--no-raqm`` will skip optional dependency Raqm (which itself depends on
+ LGPL-licensed ``fribidi``).
+* ``--python=`` and ``--executable=`` override ``PYTHON`` and ``EXECUTABLE``.
+* ``--architecture=`` overrides ``ARCHITECTURE``.
+* ``--dir=`` and ``--depends=`` override ``PILLOW_BUILD``
+ and ``PILLOW_DEPS``.
+
Dependencies
------------
@@ -93,7 +106,7 @@ The following is a simplified version of the script used on AppVeyor:
set PYTHON=C:\Python35\bin
cd /D C:\Pillow\winbuild
- C:\Python37\bin\python.exe build_prepare.py
+ C:\Python37\bin\python.exe build_prepare.py -v --depends=C:\pillow-depends
build\build_dep_all.cmd
build\build_pillow.cmd install
cd ..
diff --git a/winbuild/build_prepare.py b/winbuild/build_prepare.py
index e56b71eb4..475982da2 100644
--- a/winbuild/build_prepare.py
+++ b/winbuild/build_prepare.py
@@ -1,5 +1,6 @@
import os
import shutil
+import struct
import subprocess
import sys
@@ -176,6 +177,8 @@ deps = {
r"builds\windows\vc2010\freetype.vcxproj": {
# freetype setting is /MD for .dll and /MT for .lib, we need /MD
"MultiThreaded": "MultiThreadedDLL", # noqa E501
+ # freetype doesn't specify SDK version, MSBuild may guess incorrectly
+ '': '\n $(WindowsSDKVersion)', # noqa E501
}
},
"build": [
@@ -389,8 +392,9 @@ def write_script(name, lines):
print("Writing " + name)
with open(name, "w") as f:
f.write("\n\r".join(lines))
- for line in lines:
- print(" " + line)
+ if verbose:
+ for line in lines:
+ print(" " + line)
def get_footer(dep):
@@ -438,6 +442,8 @@ def build_dep(name):
def build_dep_all():
lines = ["@echo on"]
for dep_name in deps:
+ if dep_name in disabled:
+ continue
lines.append(r'cmd.exe /c "{{build_dir}}\{}"'.format(build_dep(dep_name)))
lines.append("if errorlevel 1 echo Build failed! && exit /B 1")
lines.append("@echo All Pillow dependencies built successfully!")
@@ -459,6 +465,28 @@ def build_pillow():
if __name__ == "__main__":
+ verbose = False
+ disabled = []
+ for arg in sys.argv[1:]:
+ if arg == "-v":
+ verbose = True
+ elif arg == "--no-imagequant":
+ disabled += ["libimagequant"]
+ elif arg == "--no-raqm":
+ disabled += ["harfbuzz", "fribidi", "libraqm"]
+ elif arg.startswith("--depends="):
+ os.environ["PILLOW_DEPS"] = arg[10:]
+ elif arg.startswith("--python="):
+ os.environ["PYTHON"] = arg[9:]
+ elif arg.startswith("--executable="):
+ os.environ["EXECUTABLE"] = arg[13:]
+ elif arg.startswith("--architecture="):
+ os.environ["ARCHITECTURE"] = arg[15:]
+ elif arg.startswith("--dir="):
+ os.environ["PILLOW_BUILD"] = arg[6:]
+ else:
+ raise ValueError("Unknown parameter: " + arg)
+
# winbuild directory
winbuild_dir = os.path.dirname(os.path.realpath(__file__))
@@ -477,7 +505,7 @@ if __name__ == "__main__":
# use ARCHITECTURE or PYTHON to select architecture
architecture = os.environ.get(
- "ARCHITECTURE", "x64" if "x64" in python_dir else "x86"
+ "ARCHITECTURE", "x86" if struct.calcsize("P") == 4 else "x64"
)
arch_prefs = architectures[architecture]
print("Target Architecture:", architecture)
@@ -528,5 +556,7 @@ if __name__ == "__main__":
"header": sum([header, msvs["header"], ["@echo on"]], []),
}
+ print()
+
build_dep_all()
build_pillow()