Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Conda #248

Closed
wants to merge 14 commits into from
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

build/
dist/
conda/out/
tests/output/
tests_old/output/
data/
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pypdfium2 includes helpers to simplify common use cases, while the raw PDFium/ct
* Installing an unofficial distribution

To the authors' knowledge, there currently are no other distributions of pypdfium2 apart from the official wheel releases on PyPI and GitHub.
There is no conda package yet.
There are no official conda releases yet, but integrating conda packaging is currently work in progress.
So far, pypdfium2 has not been included in any operating system repositories. While we are interested in cooperation with external package maintainers to make this possible, the authors of this project have no control over and are not responsible for third-party distributions of pypdfium2.

### Setup magic
Expand Down
56 changes: 56 additions & 0 deletions conda/recipe/meta.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# SPDX-FileCopyrightText: 2023 geisserml <[email protected]>
# SPDX-License-Identifier: BSD-3-Clause or Apache-2.0

# FIXME since conda isolates each build, our data/ cache is no use...

# usage: VERSION=... conda build conda/ --output-folder conda/out/
# use `craft_packages.py --conda` to build for all platforms

{% set pyproject = load_file_data("pyproject.toml") %}

package:
name: pypdfium2
version: {{ environ["VERSION"] }}

source:
# using a local `git_url` instead of `path` so conda excludes generated directories from copying,
# else it would take eternally if a sourcebuild was made previously
git_url: ../..

build:
entry_points:
- pypdfium2 = pypdfium2.__main__:cli_main
script_env:
- PDFIUM_BINARY
script: {{ PYTHON }} -m pip install . -v --no-deps --no-build-isolation
number: 0
# FIXME pypdfium2 is arch specific but python independent
# If we have `noarch: python` we will be python independent but incorrect, if we don't have it we will be correct but tied to a specific python version
# So we see the following options, each with their own complications:
# - Build python specific packages (inelegant, but the only choice supported by conda)
# - Get conda changed (would be clean, but out of our hands)
# - Edit the generated archives (risky, but might achieve what we want)
# For now, we decided to build python specific packages, though it will consume a lot more CI runtime than PyPI packages.

requirements:
build:
- python
- setuptools
- build
- wheel !=0.38.0,!=0.38.1
# TODO consider using the pre-generated bindings file so we don't have to rely on a package of our ctypesgen fork (which is currently supplied by a third party)
- ctypesgen-pypdfium2-team
- pip
run:
- python

about:
summary: {{ pyproject["project"]["description"] }}
license: {{ pyproject["project"]["license"]["text"] }}
license-files: {{ pyproject["tool"]["setuptools"]["license-files"] }}
dev_url: {{ pyproject["project"]["urls"]["homepage"] }}
doc_url: {{ pyproject["project"]["urls"]["documentation"] }}

extra:
recipe-maintainers:
- mara004
5 changes: 4 additions & 1 deletion run
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ function check() {
}

function clean() {
rm -rf src/pypdfium2.egg-info/ dist data/*
rm -rf src/pypdfium2.egg-info/ dist data/* conda/out/*
rm -f tests/output/* src/pypdfium2.egg-info/SOURCES.txt
}

Expand Down Expand Up @@ -57,6 +57,9 @@ clean)
packaging)
packaging;;

packaging-conda)
python3 setupsrc/pypdfium2_setup/craft_packages.py --conda;;

build)
python3 setupsrc/pypdfium2_setup/build_pdfium.py $args;;

Expand Down
60 changes: 49 additions & 11 deletions setupsrc/pypdfium2_setup/craft_packages.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@
ModuleDir,
BindingsFileName,
LibnameForSystem,
BinaryPlatforms,
SourceTree,
BinarySpec_EnvVar,
BinarySpec_V8Indicator,
BinarySpec_VersionSep,
PlatformTarget_None,
ReleaseNames,
VerNamespace,
CondaNames,
CondaDir,
CondaOutDir,
)


Expand Down Expand Up @@ -56,14 +60,25 @@ def pop(self):
self.tmpdir.cleanup()


def run_build(args):
def run_pypi_build(args):
run_cmd([sys.executable, "-m", "build", "--skip-dependency-check", "--no-isolation"] + args, cwd=SourceTree, env=os.environ)


def run_conda_build(binary):
os.environ[BinarySpec_EnvVar] = binary
run_cmd(["conda", "build", CondaDir, "--output-folder", CondaOutDir, "--variants", "{python: [3.8, 3.9, 3.10, 3.11]}"], cwd=SourceTree, env=os.environ)


def main():

parser = argparse.ArgumentParser(
description = "Craft sdist and wheels for pypdfium2, using `python3 -m build`.",
description = "Craft PyPI or conda packages for pypdfium2.",
)
parser.add_argument(
"--conda",
dest = "pypi",
action = "store_false",
help = "If given, build for conda instead of PyPI."
)
parser.add_argument(
"--use-v8",
Expand All @@ -79,16 +94,39 @@ def main():
args.version = get_latest_version()

stash = ArtifactStash()

os.environ[BinarySpec_EnvVar] = PlatformTarget_None
run_build(["--sdist"])
clean_platfiles()

suffix = (BinarySpec_V8Indicator if args.use_v8 else "") + BinarySpec_VersionSep + str(args.version)
for plat in BinaryPlatforms:
os.environ[BinarySpec_EnvVar] = plat + suffix
run_build(["--wheel"])

if args.pypi:

os.environ[BinarySpec_EnvVar] = PlatformTarget_None
run_pypi_build(["--sdist"])
clean_platfiles()

for plat in ReleaseNames.keys():
os.environ[BinarySpec_EnvVar] = plat + suffix
run_pypi_build(["--wheel"])
clean_platfiles()

else:

version = VerNamespace["V_PYPDFIUM2"]
os.environ["VERSION"] = version

platforms = CondaNames.copy()
conda_host = platforms.pop(Host.platform)
host_files = None

for plat, conda_plat in platforms.items():

run_conda_build(plat + suffix)

if host_files is None:
host_files = list((CondaOutDir / conda_host).glob(f"pypdfium2-{version}-*.tar.bz2"))
run_cmd(["conda", "convert", *host_files, "-p", conda_plat, "-o", CondaOutDir], cwd=SourceTree, env=os.environ)
for hf in host_files:
hf.unlink()

run_conda_build(Host.platform + suffix)

stash.pop()

Expand Down
19 changes: 17 additions & 2 deletions setupsrc/pypdfium2_setup/packaging_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@
MajorUpdateFile = AutoreleaseDir / "update_major.txt"
BetaUpdateFile = AutoreleaseDir / "update_beta.txt"
RefBindingsFile = SourceTree / "bindings" / BindingsFileName
CondaDir = SourceTree / "conda"
CondaOutDir = CondaDir / "out"

BinarySpec_EnvVar = "PDFIUM_BINARY"
BinarySpec_VersionSep = ":"
Expand Down Expand Up @@ -78,19 +80,32 @@ class PlatformNames:


ReleaseNames = {
PlatformNames.darwin_x64 : "mac-x64",
PlatformNames.darwin_arm64 : "mac-arm64",
PlatformNames.linux_x64 : "linux-x64",
PlatformNames.linux_x86 : "linux-x86",
PlatformNames.linux_arm64 : "linux-arm64",
PlatformNames.linux_arm32 : "linux-arm",
PlatformNames.linux_musl_x64 : "linux-musl-x64",
PlatformNames.linux_musl_x86 : "linux-musl-x86",
PlatformNames.darwin_x64 : "mac-x64",
PlatformNames.darwin_arm64 : "mac-arm64",
PlatformNames.windows_x64 : "win-x64",
PlatformNames.windows_x86 : "win-x86",
PlatformNames.windows_arm64 : "win-arm64",
}

CondaNames = {
# FIXME not sure if/how conda supports linux_musl
PlatformNames.linux_x64 : "linux-64",
PlatformNames.linux_x86 : "linux-32",
PlatformNames.linux_arm64 : "linux-aarch64",
PlatformNames.linux_arm32 : "linux-armv7l",
PlatformNames.darwin_x64 : "osx-64",
PlatformNames.darwin_arm64 : "osx-arm64",
PlatformNames.windows_x64 : "win-64",
PlatformNames.windows_x86 : "win-32",
PlatformNames.windows_arm64 : "win-arm64",
}

# target names for pypdfium2/ctypesgen
LibnameForSystem = {
SystemNames.linux: "pdfium",
Expand Down
4 changes: 3 additions & 1 deletion src/pypdfium2/version.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# SPDX-FileCopyrightText: 2023 geisserml <[email protected]>
# SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause

# TODO investigate if we could turn this into a yaml file?

__all__ = ("V_PYPDFIUM2", "V_LIBPDFIUM", "V_BUILDNAME", "V_PDFIUM_IS_V8")

V_MAJOR = 4
Expand All @@ -19,6 +21,6 @@
#: String describing the included PDFium binary's origin (pdfium-binaries, source)
V_BUILDNAME = "pdfium-binaries"

# CONSIDER change to V_BUILDTYPE: str ?
# TODO consider changing to V_IS_V8XFA: bool or V_BUILDTYPE: str ?
#: Whether the included PDFium binary was built with V8 support or not
V_PDFIUM_IS_V8 = False