Skip to content

Commit

Permalink
Harden copy_platfiles()
Browse files Browse the repository at this point in the history
Including lots of changes needed to make this (nicely) possible.
  • Loading branch information
mara004 committed Sep 13, 2022
1 parent 79d51d8 commit 5c53604
Show file tree
Hide file tree
Showing 5 changed files with 97 additions and 65 deletions.
1 change: 0 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ pypdfium2 includes helper classes to simplify common use cases, while the raw PD
python3 -m pip install .
```

<!-- TODO(#136@geisserml) Update instructions when finished. -->
* With a locally built PDFium binary
```bash
python3 setupsrc/pl_setup/build_pdfium.py
Expand Down
15 changes: 6 additions & 9 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@
sys.path.insert(0, join(dirname(abspath(__file__)), "setupsrc"))
from pl_setup import check_deps
from pl_setup.packaging_base import (
HostPlatform,
PlatformNames,
Host,
SourceTree,
BinaryTargetVar,
BinaryTarget_None,
PlatformNames,
)


Expand All @@ -40,19 +40,16 @@ def install_handler(w_presetup):
from pl_setup import update_pdfium
from pl_setup.setup_base import mkwheel

host = HostPlatform()
pl_name = host.get_name()

if pl_name is None:
if Host.platform is None:
# If PDFium had a proper build system, we could trigger a source build here
raise RuntimeError(
"No pre-built binaries available for platform '%s' with libc implementation '%s'. " % (host.plat_info, host.libc_info) +
"No pre-built binaries available for platform '%s' with libc implementation '%s'. " % (Host._plat_info, Host._libc_info) +
"You can attempt a source build, but it's unlikely to work out due to binary toolchain requirements of PDFium's build system. Doing cross-compilation or using a different build system might be possible, though. Please get in touch with the project maintainers."
)

if w_presetup:
update_pdfium.main([pl_name])
mkwheel(pl_name)
update_pdfium.main([Host.platform])
mkwheel(Host.platform)


def packaging_handler(target):
Expand Down
118 changes: 77 additions & 41 deletions setupsrc/pl_setup/packaging_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,53 +52,77 @@
)


class SystemNames:
linux = "linux"
darwin = "darwin"
windows = "windows"


class PlatformNames:
darwin_x64 = "darwin_x64"
darwin_arm64 = "darwin_arm64"
linux_x64 = "linux_x64"
linux_x86 = "linux_x86"
linux_arm64 = "linux_arm64"
linux_arm32 = "linux_arm32"
musllinux_x64 = "musllinux_x64"
musllinux_x86 = "musllinux_x86"
windows_x64 = "windows_x64"
windows_x86 = "windows_x86"
windows_arm64 = "windows_arm64"
sourcebuild = "sourcebuild"
linux_x64 = SystemNames.linux + "_x64"
linux_x86 = SystemNames.linux + "_x86"
linux_arm64 = SystemNames.linux + "_arm64"
linux_arm32 = SystemNames.linux + "_arm32"
linux_musl_x64 = SystemNames.linux + "_musl_x64"
linux_musl_x86 = SystemNames.linux + "_musl_x86"
darwin_x64 = SystemNames.darwin + "_x64"
darwin_arm64 = SystemNames.darwin + "_arm64"
windows_x64 = SystemNames.windows + "_x64"
windows_x86 = SystemNames.windows + "_x86"
windows_arm64 = SystemNames.windows + "_arm64"
sourcebuild = "sourcebuild"


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

LibnameForSystem = {
SystemNames.linux: "pdfium",
SystemNames.darwin: "pdfium.dylib",
SystemNames.windows: "pdfium.dll",
}

BinaryPlatforms = list(ReleaseNames.keys())
BinarySystems = list(LibnameForSystem.keys())

def plat_to_system(pl_name):
result = [s for s in BinarySystems if pl_name.startswith(s)]
assert len(result) == 1
return result[0]


class HostPlatform:
class _host_platform:

def __init__(self):

# `libc_ver()` currently returns an empty string on libc implementations other than glibc - hence, we assume musl if it's not glibc
# FIXME is there some function to actually detect musl?
self.plat_info = sysconfig.get_platform().lower().replace("-", "_").replace(".", "_")
self.libc_info, self.is_glibc = None, None
if self.plat_info.startswith("linux"):
self.libc_info = platform.libc_ver()
self.is_glibc = (self.libc_info[0] == "glibc")
self._plat_info = sysconfig.get_platform().lower().replace("-", "_").replace(".", "_")
self._libc_info, self._is_glibc = None, None
if self._plat_info.startswith("linux"):
self._libc_info = platform.libc_ver()
self._is_glibc = (self._libc_info[0] == "glibc")

self.platform = self._get_platform()
self.system = None
if self.platform is not None:
self.system = plat_to_system(self.platform)

def _is_plat(self, start, end):
return self.plat_info.startswith(start) and self.plat_info.endswith(end)
return self._plat_info.startswith(start) and self._plat_info.endswith(end)

def get_name(self):
def _get_platform(self):
if self._is_plat("macosx", "arm64"):
return PlatformNames.darwin_arm64
elif self._is_plat("macosx", "x86_64"):
Expand All @@ -108,9 +132,9 @@ def get_name(self):
elif self._is_plat("linux", "aarch64"):
return PlatformNames.linux_arm64
elif self._is_plat("linux", "x86_64"):
return PlatformNames.linux_x64 if self.is_glibc else PlatformNames.musllinux_x64
return PlatformNames.linux_x64 if self._is_glibc else PlatformNames.linux_musl_x64
elif self._is_plat("linux", "i686"):
return PlatformNames.linux_x86 if self.is_glibc else PlatformNames.musllinux_x86
return PlatformNames.linux_x86 if self._is_glibc else PlatformNames.linux_musl_x86
elif self._is_plat("win", "arm64"):
return PlatformNames.windows_arm64
elif self._is_plat("win", "amd64"):
Expand All @@ -121,6 +145,9 @@ def get_name(self):
return None


Host = _host_platform()


def _get_linux_tag(arch):
return "manylinux_2_17_%s.manylinux2014_%s" % (arch, arch)

Expand Down Expand Up @@ -159,9 +186,9 @@ def get_wheel_tag(pl_name):
return _get_linux_tag("aarch64")
elif pl_name == PlatformNames.linux_arm32:
return _get_linux_tag("armv7l")
elif pl_name == PlatformNames.musllinux_x64:
elif pl_name == PlatformNames.linux_musl_x64:
return _get_musllinux_tag("x86_64")
elif pl_name == PlatformNames.musllinux_x86:
elif pl_name == PlatformNames.linux_musl_x86:
return _get_musllinux_tag("i686")
elif pl_name == PlatformNames.windows_x64:
return "win_amd64"
Expand Down Expand Up @@ -229,14 +256,23 @@ def clean_artefacts():

def copy_platfiles(pl_name):

# TODO(#136@geisserml) Improve robustness. Explicitly get the relevant files instead of globbing the directory.
if pl_name == PlatformNames.sourcebuild:
system = Host.system
else:
system = plat_to_system(pl_name)

# NOTE this will fail in case of sourcebuild with unknown host system
binary_name = LibnameForSystem[system]

files = [f for f in glob(join(DataTree, pl_name, '*')) if os.path.isfile(f)]
assert len(files) == 2
platfiles = (
join(DataTree, pl_name, BindingsFileName),
join(DataTree, pl_name, binary_name)
)

for src_path in files:
dest_path = join(ModuleDir, basename(src_path))
shutil.copy(src_path, dest_path)
for file in platfiles:
if not os.path.exists(file):
raise RuntimeError("Platform file missing: %s" % file)
shutil.copy(file, join(ModuleDir, basename(file)))


def get_version_ns():
Expand Down
4 changes: 2 additions & 2 deletions setupsrc/pl_setup/update_pdfium.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@

sys.path.insert(0, dirname(dirname(abspath(__file__))))
from pl_setup.packaging_base import (
Host,
DataTree,
VerNamespace,
ReleaseNames,
BinaryPlatforms,
ReleaseURL,
BinaryTarget_Auto,
HostPlatform,
set_version,
get_latest_version,
call_ctypesgen,
Expand Down Expand Up @@ -127,7 +127,7 @@ def main(platforms, robust=False):
raise ValueError("Duplicate platforms not allowed.")
if BinaryTarget_Auto in platforms:
platforms = platforms.copy()
platforms[platforms.index(BinaryTarget_Auto)] = HostPlatform().get_name()
platforms[platforms.index(BinaryTarget_Auto)] = Host.platform

latest = get_latest_version()
handle_versions(str(latest))
Expand Down
24 changes: 12 additions & 12 deletions tests/test_setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,18 +48,18 @@ def test_entrypoint():
# setup_base

ExpectedTags = (
(PlatformNames.darwin_x64, "macosx_10_13_x86_64.macosx_11_0_x86_64.macosx_12_0_x86_64"),
(PlatformNames.darwin_arm64, "macosx_11_0_arm64.macosx_12_0_arm64"),
(PlatformNames.linux_x64, "manylinux_2_17_x86_64.manylinux2014_x86_64"),
(PlatformNames.linux_x86, "manylinux_2_17_i686.manylinux2014_i686"),
(PlatformNames.linux_arm64, "manylinux_2_17_aarch64.manylinux2014_aarch64"),
(PlatformNames.linux_arm32, "manylinux_2_17_armv7l.manylinux2014_armv7l"),
(PlatformNames.musllinux_x64, "musllinux_1_2_x86_64"),
(PlatformNames.musllinux_x86, "musllinux_1_2_i686"),
(PlatformNames.windows_x64, "win_amd64"),
(PlatformNames.windows_arm64, "win_arm64"),
(PlatformNames.windows_x86, "win32"),
(PlatformNames.sourcebuild, sysconfig.get_platform().replace('-','_').replace('.','_')),
(PlatformNames.linux_x64, "manylinux_2_17_x86_64.manylinux2014_x86_64"),
(PlatformNames.linux_x86, "manylinux_2_17_i686.manylinux2014_i686"),
(PlatformNames.linux_arm64, "manylinux_2_17_aarch64.manylinux2014_aarch64"),
(PlatformNames.linux_arm32, "manylinux_2_17_armv7l.manylinux2014_armv7l"),
(PlatformNames.linux_musl_x64, "musllinux_1_2_x86_64"),
(PlatformNames.linux_musl_x86, "musllinux_1_2_i686"),
(PlatformNames.darwin_x64, "macosx_10_13_x86_64.macosx_11_0_x86_64.macosx_12_0_x86_64"),
(PlatformNames.darwin_arm64, "macosx_11_0_arm64.macosx_12_0_arm64"),
(PlatformNames.windows_x64, "win_amd64"),
(PlatformNames.windows_arm64, "win_arm64"),
(PlatformNames.windows_x86, "win32"),
(PlatformNames.sourcebuild, sysconfig.get_platform().replace('-','_').replace('.','_')),
)


Expand Down

0 comments on commit 5c53604

Please sign in to comment.