Skip to content
Merged
3 changes: 3 additions & 0 deletions .github/workflows/linuxbrew.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -6,6 +6,9 @@ jobs:
strategy:
matrix:
python: ["3.9", "3.10", "3.11", "3.12", "3.13"]
env:
# For some unknown reason, linuxbrew tries to use "gcc-11" by default, which doesn't exist.
CC: gcc
steps:
- uses: actions/checkout@v3
- name: Install brew
Expand Down
1 change: 1 addition & 0 deletions .github/workflows/macosx.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -26,6 +26,7 @@ jobs:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
export PKG_CONFIG_PATH="$(brew --prefix)/opt/libxml2/lib/pkgconfig"
export PYXMLSEC_LIBXML2_VERSION="$(pkg-config --modversion libxml-2.0)"
python -m build
rm -rf build/
- name: Set environment variables
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/manylinux.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,11 +5,11 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
python-abi: [cp36-cp36m, cp37-cp37m, cp38-cp38, cp39-cp39, cp310-cp310, cp311-cp311]
python-abi: [cp38-cp38, cp39-cp39, cp310-cp310, cp311-cp311, cp312-cp312, cp313-cp313]
image:
- manylinux2014_x86_64
- manylinux_2_28_x86_64
- musllinux_1_1_x86_64
- musllinux_1_2_x86_64
container: quay.io/pypa/${{ matrix.image }}
steps:
- uses: actions/checkout@v1
Expand Down
6 changes: 5 additions & 1 deletion .github/workflows/sdist.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -2,7 +2,11 @@ name: sdist
on: [push, pull_request]
jobs:
sdist:
runs-on: ubuntu-latest
# Avoid Ubuntu 24.04 in sdist workflows, because it contains libxmlsec1-dev
# v1.2.39, which has a bug that causes tests/test_pkcs11.py to fail.
# (It thinks the softhsm engine has a public key instead of a private key.)
# libxmlsec1 <=1.2.33 or >=1.2.42 works. TODO: Try 26.04 when available.
runs-on: ubuntu-22.04
strategy:
matrix:
python: ["3.9", "3.10", "3.11", "3.12", "3.13"]
Expand Down
10 changes: 7 additions & 3 deletions .github/workflows/wheels.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,7 +19,11 @@ permissions: {}

jobs:
sdist:
runs-on: ubuntu-latest
# Avoid Ubuntu 24.04 in sdist workflows, because it contains libxmlsec1-dev
# v1.2.39, which has a bug that causes tests/test_pkcs11.py to fail.
# (It thinks the softhsm engine has a public key instead of a private key.)
# libxmlsec1 <=1.2.33 or >=1.2.42 works. TODO: Try 26.04 when available.
runs-on: ubuntu-22.04

permissions:
contents: write
Expand DownExpand Up@@ -100,8 +104,8 @@ jobs:
include: ${{ fromJson(needs.generate-wheels-matrix.outputs.include) }}

env:
PYXMLSEC_LIBXML2_VERSION: 2.13.5
PYXMLSEC_LIBXSLT_VERSION: 1.1.42
PYXMLSEC_LIBXML2_VERSION: 2.14.4
PYXMLSEC_LIBXSLT_VERSION: 1.1.43

steps:
- name: Check out the repo
Expand Down
10 changes: 4 additions & 6 deletions pyproject.toml
Original file line numberDiff line numberDiff line change
Expand Up@@ -54,12 +54,10 @@ skip = [
"*-musllinux_i686",
# LXML doesn't publish wheels for these platforms, which makes it
# difficult for us to build wheels, so we exclude them.
"cp36-manylinux_aarch64",
"cp37-manylinux_aarch64",
"cp36-musllinux_aarch64",
"cp37-musllinux_aarch64",
"cp36-macosx*",
"cp37-macosx*",
"cp36-*",
"cp37-*",
"cp38-manylinux_aarch64",
"cp38-musllinux_aarch64",
"cp38-macosx*",
]
test-command = "pytest -v --color=yes {package}/tests"
Expand Down
2 changes: 1 addition & 1 deletion requirements.txt
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
lxml >= 3.8.0, !=4.7.0 --no-binary=lxml
lxml >= 3.8.0, !=4.7.0
75 changes: 33 additions & 42 deletions setup.py
Original file line numberDiff line numberDiff line change
Expand Up@@ -70,22 +70,18 @@ def latest_release_from_gnome_org_cache(url, lib_name):
return '{}/{}'.format(url, latest_source)


def latest_release_from_github_api(repo):
api_url = 'https://api.github.com/repos/{}/releases'.format(repo)
def latest_release_json_from_github_api(repo):
api_url = 'https://api.github.com/repos/{}/releases/latest'.format(repo)

# if we are running in CI, pass along the GH_TOKEN, so we don't get rate limited
token = os.environ.get("GH_TOKEN")
if token:
log.info("Using GitHub token to avoid rate limiting")
api_releases = make_request(api_url, token, json_response=True)
releases = [r['tarball_url'] for r in api_releases if r['prerelease'] is False and r['draft'] is False]
if not releases:
raise DistutilsError('No release found for {}'.format(repo))
return releases[0]
return make_request(api_url, token, json_response=True)


def latest_openssl_release():
return latest_release_from_github_api('openssl/openssl')
return latest_release_json_from_github_api('openssl/openssl')['tarball_url']


def latest_zlib_release():
Expand All@@ -105,7 +101,9 @@ def latest_libxslt_release():


def latest_xmlsec_release():
return latest_release_from_html('https://www.aleksey.com/xmlsec/download/', re.compile('xmlsec1-(?P<version>.*).tar.gz'))
assets = latest_release_json_from_github_api('lsh123/xmlsec')['assets']
(tar_gz,) = [asset for asset in assets if asset['name'].endswith('.tar.gz')]
return tar_gz['browser_download_url']


class CrossCompileInfo:
Expand DownExpand Up@@ -381,7 +379,7 @@ def prepare_static_build(self, build_platform):
url = latest_xmlsec_release()
self.info('{:10}: {}'.format('xmlsec1', 'PYXMLSEC_XMLSEC1_VERSION unset, downloading latest from {}'.format(url)))
else:
url = 'https://www.aleksey.com/xmlsec/download/xmlsec1-{}.tar.gz'.format(self.xmlsec1_version)
url = 'https://github.com/lsh123/xmlsec/releases/download/{v}/xmlsec1-{v}.tar.gz'.format(v=self.xmlsec1_version)
self.info(
'{:10}: {}'.format(
'xmlsec1', 'PYXMLSEC_XMLSEC1_VERSION={}, downloading from {}'.format(self.xmlsec1_version, url)
Expand DownExpand Up@@ -435,43 +433,41 @@ def prepare_static_build(self, build_platform):
openssl_config_cmd.append(cross_compiling.triplet)
else:
openssl_config_cmd.insert(0, './config')
subprocess.check_output(openssl_config_cmd, cwd=str(openssl_dir), env=env)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(openssl_dir), env=env)
subprocess.check_output(
subprocess.check_call(openssl_config_cmd, cwd=str(openssl_dir), env=env)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(openssl_dir), env=env)
subprocess.check_call(
['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install_sw'], cwd=str(openssl_dir), env=env
)

self.info('Building zlib')
zlib_dir = next(self.build_libs_dir.glob('zlib-*'))
subprocess.check_output(['./configure', prefix_arg], cwd=str(zlib_dir), env=env)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(zlib_dir), env=env)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(zlib_dir), env=env)
subprocess.check_call(['./configure', prefix_arg], cwd=str(zlib_dir), env=env)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(zlib_dir), env=env)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(zlib_dir), env=env)

host_arg = ""
host_arg = []
if cross_compiling:
host_arg = '--host={}'.format(cross_compiling.arch)
host_arg = ['--host={}'.format(cross_compiling.arch)]

self.info('Building libiconv')
libiconv_dir = next(self.build_libs_dir.glob('libiconv-*'))
subprocess.check_output(
subprocess.check_call(
[
'./configure',
prefix_arg,
'--disable-dependency-tracking',
'--disable-shared',
host_arg,
*host_arg,
],
cwd=str(libiconv_dir),
env=env,
)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libiconv_dir), env=env)
subprocess.check_output(
['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libiconv_dir), env=env
)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libiconv_dir), env=env)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libiconv_dir), env=env)

self.info('Building LibXML2')
libxml2_dir = next(self.build_libs_dir.glob('libxml2-*'))
subprocess.check_output(
subprocess.check_call(
[
'./configure',
prefix_arg,
Expand All@@ -481,19 +477,17 @@ def prepare_static_build(self, build_platform):
'--without-python',
'--with-iconv={}'.format(self.prefix_dir),
'--with-zlib={}'.format(self.prefix_dir),
host_arg,
*host_arg,
],
cwd=str(libxml2_dir),
env=env,
)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libxml2_dir), env=env)
subprocess.check_output(
['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libxml2_dir), env=env
)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libxml2_dir), env=env)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libxml2_dir), env=env)

self.info('Building libxslt')
libxslt_dir = next(self.build_libs_dir.glob('libxslt-*'))
subprocess.check_output(
subprocess.check_call(
[
'./configure',
prefix_arg,
Expand All@@ -502,27 +496,26 @@ def prepare_static_build(self, build_platform):
'--without-python',
'--without-crypto',
'--with-libxml-prefix={}'.format(self.prefix_dir),
host_arg,
*host_arg,
],
cwd=str(libxslt_dir),
env=env,
)
subprocess.check_output(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libxslt_dir), env=env)
subprocess.check_output(
['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libxslt_dir), env=env
)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1)], cwd=str(libxslt_dir), env=env)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(libxslt_dir), env=env)

self.info('Building xmlsec1')
ldflags.append('-lpthread')
env['LDFLAGS'] = ' '.join(ldflags)
xmlsec1_dir = next(self.build_libs_dir.glob('xmlsec1-*'))
subprocess.check_output(
subprocess.check_call(
[
'./configure',
prefix_arg,
'--disable-shared',
'--disable-gost',
'--enable-md5',
'--enable-ripemd160',
'--disable-crypto-dl',
'--enable-static=yes',
'--enable-shared=no',
Expand All@@ -531,20 +524,18 @@ def prepare_static_build(self, build_platform):
'--with-openssl={}'.format(self.prefix_dir),
'--with-libxml={}'.format(self.prefix_dir),
'--with-libxslt={}'.format(self.prefix_dir),
host_arg,
*host_arg,
],
cwd=str(xmlsec1_dir),
env=env,
)
subprocess.check_output(
subprocess.check_call(
['make', '-j{}'.format(multiprocessing.cpu_count() + 1)]
+ ['-I{}'.format(str(self.prefix_dir / 'include')), '-I{}'.format(str(self.prefix_dir / 'include' / 'libxml'))],
cwd=str(xmlsec1_dir),
env=env,
)
subprocess.check_output(
['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(xmlsec1_dir), env=env
)
subprocess.check_call(['make', '-j{}'.format(multiprocessing.cpu_count() + 1), 'install'], cwd=str(xmlsec1_dir), env=env)

ext = self.ext_map['xmlsec']
ext.define_macros = [
Expand Down