diff --git a/news/674.new.1.rst b/news/674.new.1.rst new file mode 100644 index 00000000..d0b517d2 --- /dev/null +++ b/news/674.new.1.rst @@ -0,0 +1,2 @@ +Add a hook for ``freetype`` that collects the shared library that is +bundled with ``freetype-py`` PyPI wheels. diff --git a/requirements-test-libraries.txt b/requirements-test-libraries.txt index 9a59493f..e1c5e42c 100644 --- a/requirements-test-libraries.txt +++ b/requirements-test-libraries.txt @@ -162,6 +162,7 @@ sspilib==0.1.0 rlp==4.0.0 eth-rlp==1.0.0 z3c.rml==4.4.0 +freetype-py==2.4.0 # ------------------- Platform (OS) specifics diff --git a/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-freetype.py b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-freetype.py new file mode 100644 index 00000000..39705585 --- /dev/null +++ b/src/_pyinstaller_hooks_contrib/hooks/stdhooks/hook-freetype.py @@ -0,0 +1,16 @@ +# ------------------------------------------------------------------ +# Copyright (c) 2023 PyInstaller Development Team. +# +# This file is distributed under the terms of the GNU General Public +# License (version 2.0 or later). +# +# The full license is available in LICENSE.GPL.txt, distributed with +# this software. +# +# SPDX-License-Identifier: GPL-2.0-or-later +# ------------------------------------------------------------------ + +from PyInstaller.utils.hooks import collect_dynamic_libs + +# Collect the bundled freetype shared library, if available. +binaries = collect_dynamic_libs('freetype') diff --git a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py index 73164105..daee18a4 100644 --- a/src/_pyinstaller_hooks_contrib/tests/test_libraries.py +++ b/src/_pyinstaller_hooks_contrib/tests/test_libraries.py @@ -1945,3 +1945,30 @@ def test_z3c_rml_rml2pdf(pyi_builder): pdf_bytes = rml2pdf.parseString(rml) """) + + +@importorskip('freetype') +def test_pyi_freetype(pyi_builder): + pyi_builder.test_source(""" + import sys + import pathlib + + import freetype + + # Ensure that the freetype shared library is bundled with the frozen application; otherwise, freetype might be + # using system-wide library. + + # First, check that freetype.FT_Library_filename is an absolute path; otherwise, it is likely using + # basename-only ctypes fallback. + ft_library_file = pathlib.Path(freetype.FT_Library_filename) + print(f"FT library file (original): {ft_library_file}", file=sys.stderr) + assert ft_library_file.is_absolute(), "FT library file is not an absolute path!" + + # Check that fully-resolved freetype.FT_Library_filename is anchored in fully-resolved frozen application + # directory. + app_dir = pathlib.Path(__file__).resolve().parent + print(f"Application directory: {app_dir}", file=sys.stderr) + ft_library_path = pathlib.Path(ft_library_file).resolve() + print(f"FT library file (resolved): {ft_library_path}", file=sys.stderr) + assert app_dir in ft_library_path.parents, "FT library is not bundled with frozen application!" + """)