Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 12 additions & 15 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -143,11 +143,7 @@ jobs:

- name: Download and extract Cairo Binary
run: |
#TODO: Change below URL on new cairo release
curl -L https://github.com/preshing/cairo-windows/releases/download/with-tee/cairo-windows-1.17.2.zip -o cairocomplied.zip
7z x cairocomplied.zip
Move-Item 'cairo-windows-*' "cairocomplied"
tree
python tools/download-cairo-win32.py

- name: Set up Python ${{ matrix.python-version }} for x64
uses: actions/setup-python@v2
Expand All @@ -156,12 +152,13 @@ jobs:
architecture: 'x64'

- name: Build x64 Build
shell: cmd
env:
PKG_CONFIG: ${{ github.workspace }}/cairo-prebuild/bin/pkgconf.exe
PKG_CONFIG_PATH: ${{ github.workspace }}/cairo-prebuild/lib/pkgconfig
run: |
$env:INCLUDE="$PWD\cairocomplied\include\"
$env:LIB="$PWD\cairocomplied\lib\x64\"
Copy-Item "$PWD\cairocomplied\lib\x64\cairo.dll" "cairo\cairo.dll"
python -m pip install --upgrade pip
python -m pip install --upgrade wheel
python download-cairo-win32.py
python -m pip install --upgrade pip wheel
python -m pip install --upgrade setuptools
python -m pip install --upgrade pytest flake8 coverage hypothesis
python -m pip install --upgrade pygame
Expand All @@ -171,7 +168,6 @@ jobs:
python setup.py sdist
python setup.py bdist
python setup.py install --root=_root
python setup.py install --root="$(pwd)"/_root_abs
python setup.py bdist_wheel
python setup.py install --root=_root_setup
python -m pip install .
Expand All @@ -186,10 +182,12 @@ jobs:
architecture: 'x86'

- name: Build x86 Build
shell: cmd
env:
PKG_CONFIG: ${{ github.workspace }}/cairo-prebuild/bin/pkgconf.exe
PKG_CONFIG_PATH: ${{ github.workspace }}/cairo-prebuild/lib/pkgconfig
run: |
$env:INCLUDE="$PWD\cairocomplied\include\"
$env:LIB="$PWD\cairocomplied\lib\x86\"
Copy-Item "cairocomplied\lib\x86\cairo.dll" "cairo\cairo.dll"
python tools/download-cairo-win32.py
python -m pip install --upgrade pip
python -m pip install --upgrade wheel
python -m pip install --upgrade setuptools
Expand All @@ -201,7 +199,6 @@ jobs:
python setup.py sdist
python setup.py bdist
python setup.py install --root=_root
python setup.py install --root="$(pwd)"/_root_abs
python setup.py bdist_wheel
python setup.py install --root=_root_setup
python -m pip install .
Expand Down
37 changes: 37 additions & 0 deletions .github/workflows/wheels.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
name: Build

on: [push, pull_request]

jobs:
build_wheels:
name: Build wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [windows-2019]
bitness: [32, 64]
include:
# Run 32 and 64 bit version in parallel for Windows
- os: windows-2019
bitness: 64
platform_id: win_amd64
- os: windows-2019
bitness: 32
platform_id: win32

steps:
- uses: actions/checkout@v3

- name: Build wheels
uses: pypa/cibuildwheel@v2.11.2
env:
CIBW_BEFORE_BUILD: "python {package}/tools/download-cairo-win32.py"
CIBW_BUILD: cp37-${{ matrix.platform_id }} cp38-${{ matrix.platform_id }} cp39-${{ matrix.platform_id }} cp310-${{ matrix.platform_id }} cp311-${{ matrix.platform_id }}
CIBW_TEST_REQUIRES: pytest hypothesis attrs
CIBW_TEST_COMMAND: bash {package}/tools/test-wheels.sh {package}
CIBW_ENVIRONMENT_WINDOWS: PKG_CONFIG_PATH='${{ github.workspace }}/cairo-prebuild/lib/pkgconfig' PKG_CONFIG='${{ github.workspace }}/cairo-prebuild/bin/pkgconf.exe'

- uses: actions/upload-artifact@v3
with:
path: ./wheelhouse/*.whl
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -65,4 +65,8 @@ stamp-h1
stamp-h.in
poetry.lock

.vscode
.vscode
build-*
.venv
cairo-prebuild/

26 changes: 15 additions & 11 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
PYCAIRO_VERSION = '1.21.1'
CAIRO_VERSION_REQUIRED = '1.15.10'

PYCAIRO_BUILD_NO_PKGCONFIG = os.environ.get("PYCAIRO_BUILD_NO_PKGCONFIG", False)
PYCAIRO_BUILD_MSVC_STATIC = os.environ.get("PYCAIRO_BUILD_MSVC_STATIC", True)


def get_command_class(name):
# in case pip loads with setuptools this returns the extended commands
Expand Down Expand Up @@ -169,12 +172,14 @@ class build_tests(Command):
def initialize_options(self):
self.force = False
self.build_base = None
self.compiler_type = None

def finalize_options(self):
self.set_undefined_options(
'build',
('build_base', 'build_base'))
self.force = bool(self.force)
self.compiler_type = new_compiler().compiler_type

def run(self):
cmd = self.reinitialize_command("build_ext")
Expand Down Expand Up @@ -207,13 +212,14 @@ def run(self):

add_ext_cflags(ext, compiler)

if compiler.compiler_type == "msvc":
ext.libraries += ['cairo']
else:
if not PYCAIRO_BUILD_NO_PKGCONFIG:
pkg_config_version_check('cairo', CAIRO_VERSION_REQUIRED)
ext.include_dirs += pkg_config_parse('--cflags-only-I', 'cairo')
ext.library_dirs += pkg_config_parse('--libs-only-L', 'cairo')
ext.libraries += pkg_config_parse('--libs-only-l', 'cairo')
if self.compiler_type == "msvc" and PYCAIRO_BUILD_MSVC_STATIC:
ext.libraries += ['user32', 'advapi32', 'ole32']
ext.define_macros += [('CAIRO_WIN32_STATIC_BUILD', 1)]

dist = Distribution({"ext_modules": [ext]})

Expand Down Expand Up @@ -459,21 +465,19 @@ def finalize_options(self):
def run(self):
ext = self.extensions[0]

# If we are using MSVC, don't use pkg-config,
# just assume that INCLUDE and LIB contain
# the paths to the Cairo headers and libraries,
# respectively.
if self.compiler_type == "msvc":
ext.libraries += ['cairo']
else:
if not PYCAIRO_BUILD_NO_PKGCONFIG:
pkg_config_version_check('cairo', CAIRO_VERSION_REQUIRED)
ext.include_dirs += pkg_config_parse('--cflags-only-I', 'cairo')
ext.library_dirs += pkg_config_parse('--libs-only-L', 'cairo')
ext.libraries += pkg_config_parse('--libs-only-l', 'cairo')

if not self.compiler_type == "msvc":
compiler = new_compiler(compiler=self.compiler)
customize_compiler(compiler)
add_ext_cflags(ext, compiler)
elif self.compiler_type == "msvc" and PYCAIRO_BUILD_MSVC_STATIC:
# these extra libs are needed since we are linking statically
ext.libraries += ['user32', 'advapi32', 'ole32']
ext.define_macros += [('CAIRO_WIN32_STATIC_BUILD', 1)]

du_build_ext.run(self)

Expand Down
6 changes: 5 additions & 1 deletion tests/test_cmod.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,12 @@
from __future__ import absolute_import

import cairo
import pytest

from . import cmod
try:
from . import cmod
except ImportError:
pytest.skip("cmod not built", allow_module_level=True)


def test_foo():
Expand Down
87 changes: 87 additions & 0 deletions tools/download-cairo-win32.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
from __future__ import annotations
import logging
import os
import re
import shutil
import struct
import tempfile
import zipfile
from pathlib import Path
from urllib.request import urlretrieve as download

CAIRO_VERSION = "1.17.6"


def get_platform() -> str:
if (struct.calcsize("P") * 8) == 32:
return "32"
else:
return "64"


logging.basicConfig(format="%(levelname)s - %(message)s", level=logging.DEBUG)

plat = get_platform()
logging.debug(f"Found Platform as {plat} bit")

download_url = (
"https://github.com/pygobject/cairo-win-build/releases"
f"/download/{CAIRO_VERSION}/cairo-{CAIRO_VERSION}-{plat}.zip"
)
final_location = Path(__file__).parent.parent / "cairo-prebuild"
download_location = Path(tempfile.mkdtemp())
if final_location.exists():
logging.info("Final Location already exists clearing it...")
shutil.rmtree(str(final_location))
final_location.mkdir()
download_file = download_location / "build.zip"
logging.info("Downloading Cairo Binaries for Windows...")
logging.info("Url: %s", download_url)
download(url=download_url, filename=download_file)
logging.info(f"Download complete. Saved to {download_file}.")
logging.info(f"Extracting {download_file} to {download_location}...")
with zipfile.ZipFile(
download_file, mode="r", compression=zipfile.ZIP_DEFLATED
) as file: # noqa: E501
file.extractall(download_location)
os.remove(download_file)
logging.info("Completed Extracting.")
logging.info("Moving Files accordingly.")
plat_location = download_location / ("cairo-x64" if plat == "64" else "cairo-x86")
for src_file in plat_location.glob("*"):
logging.debug(f"Moving {src_file} to {final_location}...")
shutil.move(str(src_file), str(final_location))
logging.info("Moving files Completed")
logging.info("Fixing .pc files")


rex = re.compile("^prefix=(.*)")


def new_place(_: re.Match[str]) -> str:
return f"prefix={str(final_location.as_posix())}"


pc_files = final_location / "lib" / "pkgconfig"
for i in pc_files.glob("*.pc"):
logging.info(f"Writing {i}")
with open(i) as f:
content = f.read()
final = rex.sub(new_place, content)
with open(i, "w") as f:
f.write(final)

logging.info("Getting pkg-config")
download(
url="https://github.com/pygobject/cairo-win-build"
"/releases/download/1.17.6/pkgconf.zip",
filename=download_file,
)
with zipfile.ZipFile(
download_file, mode="r", compression=zipfile.ZIP_DEFLATED
) as file: # noqa: E501
file.extractall(download_location)
shutil.move(
str(download_location / "pkgconf" / "bin" / "pkgconf.exe"),
str(final_location / "bin"),
)
16 changes: 16 additions & 0 deletions tools/test-wheels.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#!/bin/bash

set -e
set -x

project_dir=$1

# Move the $(project_dir)/tests to a temporary directory
# so that the tests doesn't use inplace build.

tmp_dir=$(mktemp -d)
cp -r $project_dir/tests $tmp_dir
cd $tmp_dir/tests

# Run the tests
python -m pytest $tmp_dir/tests