diff --git a/src/ahriman/core/exceptions.py b/src/ahriman/core/exceptions.py index b052302d..870e64c1 100644 --- a/src/ahriman/core/exceptions.py +++ b/src/ahriman/core/exceptions.py @@ -95,6 +95,19 @@ class DuplicateRunError(RuntimeError): self, "Another application instance is run. This error can be suppressed by using --force flag.") +class EncodeError(ValueError): + """ + exception used for bytes encoding errors + """ + + def __init__(self, encodings: list[str]) -> None: + """ + Args: + encodings(list[str]): list of encodings tried + """ + ValueError.__init__(self, f"Could not encode bytes by using {encodings}") + + class ExitCode(RuntimeError): """ special exception which has to be thrown to return non-zero status without error message diff --git a/src/ahriman/models/pkgbuild.py b/src/ahriman/models/pkgbuild.py index 23cb48a2..242accd4 100644 --- a/src/ahriman/models/pkgbuild.py +++ b/src/ahriman/models/pkgbuild.py @@ -24,6 +24,7 @@ from pathlib import Path from typing import Any, IO, Self from ahriman.core.alpm.pkgbuild_parser import PkgbuildParser, PkgbuildToken +from ahriman.core.exceptions import EncodeError from ahriman.models.pkgbuild_patch import PkgbuildPatch @@ -33,11 +34,14 @@ class Pkgbuild(Mapping[str, Any]): model and proxy for PKGBUILD properties Attributes: + DEFAULT_ENCODINGS(list[str]): (class attribute) list of encoding to be applied on the file content fields(dict[str, PkgbuildPatch]): PKGBUILD fields """ fields: dict[str, PkgbuildPatch] + DEFAULT_ENCODINGS = ["utf8", "latin-1"] + @property def variables(self) -> dict[str, str]: """ @@ -54,18 +58,34 @@ class Pkgbuild(Mapping[str, Any]): } @classmethod - def from_file(cls, path: Path) -> Self: + def from_file(cls, path: Path, encodings: list[str] | None = None) -> Self: """ parse PKGBUILD from the file Args: path(Path): path to the PKGBUILD file + encodings(list[str] | None, optional): the encoding of the file (Default value = None) Returns: Self: constructed instance of self + + Raises: + EncodeError: if encoding is unknown """ - with path.open(encoding="utf8") as input_file: - return cls.from_io(input_file) + # read raw bytes from file + with path.open("rb") as input_file: + content = input_file.read() + + # decode bytes content based on either + encodings = encodings or cls.DEFAULT_ENCODINGS + for encoding in encodings: + try: + io = StringIO(content.decode(encoding)) + return cls.from_io(io) + except ValueError: + pass + + raise EncodeError(encodings) @classmethod def from_io(cls, stream: IO[str]) -> Self: diff --git a/tests/ahriman/core/test_utils.py b/tests/ahriman/core/test_utils.py index 6156aa28..ac5b90dd 100644 --- a/tests/ahriman/core/test_utils.py +++ b/tests/ahriman/core/test_utils.py @@ -471,6 +471,7 @@ def test_walk(resource_path_root: Path) -> None: resource_path_root / "models" / "package_ahriman_pkgbuild", resource_path_root / "models" / "package_gcc10_pkgbuild", resource_path_root / "models" / "package_jellyfin-ffmpeg6-bin_pkgbuild", + resource_path_root / "models" / "package_pacman-static_pkgbuild", resource_path_root / "models" / "package_python-pytest-loop_pkgbuild", resource_path_root / "models" / "package_tpacpi-bat-git_pkgbuild", resource_path_root / "models" / "package_vim-youcompleteme-git_pkgbuild", diff --git a/tests/ahriman/models/test_pkgbuild.py b/tests/ahriman/models/test_pkgbuild.py index eed7c0bd..349590de 100644 --- a/tests/ahriman/models/test_pkgbuild.py +++ b/tests/ahriman/models/test_pkgbuild.py @@ -1,9 +1,11 @@ import pytest -from io import StringIO +from io import BytesIO, StringIO from pathlib import Path from pytest_mock import MockerFixture +from unittest.mock import MagicMock +from ahriman.core.exceptions import EncodeError from ahriman.models.pkgbuild import Pkgbuild from ahriman.models.pkgbuild_patch import PkgbuildPatch @@ -23,13 +25,39 @@ def test_from_file(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None: must correctly load from file """ open_mock = mocker.patch("pathlib.Path.open") + open_mock.return_value.__enter__.return_value = BytesIO(b"content") load_mock = mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_io", return_value=pkgbuild_ahriman) assert Pkgbuild.from_file(Path("local")) - open_mock.assert_called_once_with(encoding="utf8") + open_mock.assert_called_once_with("rb") load_mock.assert_called_once_with(pytest.helpers.anyvar(int)) +def test_from_file_latin(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None: + """ + must correctly load from file with latin encoding + """ + open_mock = mocker.patch("pathlib.Path.open") + open_mock.return_value.__enter__.return_value = BytesIO("contĂŠnt".encode("latin-1")) + load_mock = mocker.patch("ahriman.models.pkgbuild.Pkgbuild.from_io", return_value=pkgbuild_ahriman) + + assert Pkgbuild.from_file(Path("local")) + open_mock.assert_called_once_with("rb") + load_mock.assert_called_once_with(pytest.helpers.anyvar(int)) + + +def test_from_file_unknown_encoding(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None: + """ + must raise exception when encoding is unknown + """ + open_mock = mocker.patch("pathlib.Path.open") + io_mock = open_mock.return_value.__enter__.return_value = MagicMock() + io_mock.read.return_value.decode.side_effect = EncodeError(pkgbuild_ahriman.DEFAULT_ENCODINGS) + + with pytest.raises(EncodeError): + assert Pkgbuild.from_file(Path("local")) + + def test_from_io(pkgbuild_ahriman: Pkgbuild, mocker: MockerFixture) -> None: """ must correctly load from io @@ -461,9 +489,7 @@ def test_parse_python_pytest_loop(resource_path_root: Path) -> None: "pkgbase": "python-pytest-loop", "_pname": "${pkgbase#python-}", "_pyname": "${_pname//-/_}", - "pkgname": [ - "python-${_pname}", - ], + "pkgname": ["python-${_pname}"], "pkgver": "1.0.13", "pkgrel": "1", "pkgdesc": "Pytest plugin for looping test execution.", @@ -487,3 +513,98 @@ def test_parse_python_pytest_loop(resource_path_root: Path) -> None: "98365f49606d5068f92350f1d2569a5f", ], } + + +def test_parse_pacman_static(resource_path_root: Path) -> None: + """ + must parse real PKGBUILDs correctly (pacman-static) + """ + pkgbuild = Pkgbuild.from_file(resource_path_root / "models" / "package_pacman-static_pkgbuild") + values = {key: value.value for key, value in pkgbuild.fields.items() if not value.is_function} + print(values) + assert values == { + "pkgbase": "pacman-static", + "pkgname": "pacman-static", + "pkgver": "7.0.0.r6.gc685ae6", + "_cares_ver": "1.34.4", + "_nghttp2_ver": "1.64.0", + "_curlver": "8.12.1", + "_sslver": "3.4.1", + "_zlibver": "1.3.1", + "_xzver": "5.6.4", + "_bzipver": "1.0.8", + "_zstdver": "1.5.6", + "_libarchive_ver": "3.7.7", + "_gpgerrorver": "1.51", + "_libassuanver": "3.0.0", + "_gpgmever": "1.24.2", + "pkgrel": "15", + "_git_tag": "7.0.0", + "_git_patch_level_commit": "c685ae6412af04cae1eaa5d6bda8c277c7ffb8c8", + "pkgdesc": "Statically-compiled pacman (to fix or install systems without libc)", + "arch": [ + "i486", + "i686", + "pentium4", + "x86_64", + "arm", + "armv6h", + "armv7h", + "aarch64" + ], + "url": "https://www.archlinux.org/pacman/", + "license": ["GPL-2.0-or-later"], + "depends": ["pacman"], + "makedepends": [ + "meson", + "musl", + "kernel-headers-musl", + "git", + ], + "options": [ + "!emptydirs", + "!lto", + ], + "source": [ + "git+https://gitlab.archlinux.org/pacman/pacman.git#tag=v${_git_tag}?signed", + "pacman-revertme-makepkg-remove-libdepends-and-libprovides.patch::https://gitlab.archlinux.org/pacman/pacman/-/commit/354a300cd26bb1c7e6551473596be5ecced921de.patch", + ], + "validpgpkeys": [ + "6645B0A8C7005E78DB1D7864F99FFE0FEAE999BD", + "B8151B117037781095514CA7BBDFFC92306B1121", + ], + "sha512sums": [ + "44e00c2bc259fe6a85de71f7fd8a43fcfd1b8fb7d920d2267bd5b347e02f1dab736b3d96e31faf7b535480398e2348f7c0b9914e51ca7e12bab2d5b8003926b4", + "1a108c4384b6104e627652488659de0b1ac3330640fc3250f0a283af7c5884daab187c1efc024b2545262da1911d2b0b7b0d5e4e5b68bb98db25a760c9f1fb1a", + "b544196c3b7a55faacd11700d11e2fe4f16a7418282c9abb24a668544a15293580fd1a2cc5f93367c8a17c7ee45335c6d2f5c68a72dd176d516fd033f203eeec", + "3285e14d94bc736d6caddfe7ad7e3c6a6e69d49b079c989bb3e8aba4da62c022e38229d1e691aaa030b7d3bcd89e458d203f260806149a71ad9adb31606eae02", + "SKIP", + "9fcdcceab8bce43e888db79a38c775ff15790a806d3cc5cc96f396a829c6da2383b258481b5642153da14087943f6ef607af0aa3b75df6f41b95c6cd61d835eb", + "SKIP", + "1de6307c587686711f05d1e96731c43526fa3af51e4cd94c06c880954b67f6eb4c7db3177f0ea5937d41bc1f8cadcf5bce75025b5c1a46a469376960f1001c5f", + "SKIP", + "b1873dbb7a49460b007255689102062756972de5cc2d38b12cc9f389b6be412da6797579b1acd3717a8cd2ee118fd9801b94e55f063d4328f050f0876a5eb53c", + "b5887ea77417fae49b6cb1e9fa782d3021f268d5219701d87a092235964f73fa72a31428b630445517f56f2bb69dcbbb24119ef9dbf8b4e40a753369a9f9a16f", + "580677aad97093829090d4b605ac81c50327e74a6c2de0b85dd2e8525553f3ddde17556ea46f8f007f89e435493c9a20bc997d1ef1c1c2c23274528e3c46b94f", + "SKIP", + "e3216eca5fae2c9ce419e698bfbe186903088dad0a579749cb49bcde8f9d4073b98bf1570fe69190a9a41feb2a7c9814498ec9b867527de1c74ff75a1cbdfc17", + "083f5e675d73f3233c7930ebe20425a533feedeaaa9d8cc86831312a6581cefbe6ed0d08d2fa89be81082f2a5abdabca8b3c080bf97218a1bd59dc118a30b9f3", + "SKIP", + "21f9da445afd76acaf3acb22d216c2b584d95e8c68e00f5cb3f6673f2d556dd14a7593344adf8ffd194bba3314387ee0e486d6248f6c935abca2edd8a4cf95ed", + "SKIP", + "4489f615c6a0389577a7d1fd7d3917517bb2fe032abd9a6d87dfdbd165dabcf53f8780645934020bf27517b67a064297475888d5b368176cf06bc22f1e735e2b", + "SKIP", + "7c5c95c1b85bef2d4890c068a5a8ea8a1fe0d8def6ab09e5f34fc2746d8808bbb0fc168e3bd66d52ee5ed799dcf9f258f4125cda98c8384f6411bcad8d8b3139", + "SKIP", + "ad69101d1fceef6cd1dd6d5348f6f2be06912da6b6a7d0fece3ce08cf35054e6953b80ca9c4748554882892faa44e7c54e705cf25bbf2b796cd4ad12b09da185", + "SKIP", + "2524f71f4c2ebc254a1927279be3394e820d0a0c6dec7ef835a862aa08c35756edaa4208bcdc710dd092872b59c200b555b78670372e2830822e278ff1ec4e4a", + "SKIP", + ], + "LDFLAGS": "$LDFLAGS -static", + "CC": "musl-gcc -fno-stack-protector", + "CXX": "musl-gcc -fno-stack-protector", + "CFLAGS": "${CFLAGS/-fstack-protector-strong/}", + "CXXFLAGS": "${CXXFLAGS/-fstack-protector-strong/}", + "PKGEXT": ".pkg.tar.xz", + } diff --git a/tests/testresources/models/package_pacman-static_pkgbuild b/tests/testresources/models/package_pacman-static_pkgbuild new file mode 100644 index 00000000..a8caac83 --- /dev/null +++ b/tests/testresources/models/package_pacman-static_pkgbuild @@ -0,0 +1,356 @@ +# Maintainer: Eli Schwartz + +# All my PKGBUILDs are managed at https://github.com/eli-schwartz/pkgbuilds + +pkgname=pacman-static +pkgver=7.0.0.r6.gc685ae6 +_cares_ver=1.34.4 +_nghttp2_ver=1.64.0 +_curlver=8.12.1 +_sslver=3.4.1 +_zlibver=1.3.1 +_xzver=5.6.4 +_bzipver=1.0.8 +_zstdver=1.5.6 +_libarchive_ver=3.7.7 +_gpgerrorver=1.51 +_libassuanver=3.0.0 +_gpgmever=1.24.2 +pkgrel=15 +# use annotated tag and patch level commit from release branch (can be empty for no patches) +_git_tag=7.0.0 +_git_patch_level_commit=c685ae6412af04cae1eaa5d6bda8c277c7ffb8c8 +pkgdesc="Statically-compiled pacman (to fix or install systems without libc)" +arch=('i486' 'i686' 'pentium4' 'x86_64' 'arm' 'armv6h' 'armv7h' 'aarch64') +url="https://www.archlinux.org/pacman/" +license=('GPL-2.0-or-later') +depends=('pacman') +makedepends=('meson' 'musl' 'kernel-headers-musl' 'git') +options=('!emptydirs' '!lto') + +# pacman +source=("git+https://gitlab.archlinux.org/pacman/pacman.git#tag=v${_git_tag}?signed" + pacman-revertme-makepkg-remove-libdepends-and-libprovides.patch::https://gitlab.archlinux.org/pacman/pacman/-/commit/354a300cd26bb1c7e6551473596be5ecced921de.patch) + +validpgpkeys=('6645B0A8C7005E78DB1D7864F99FFE0FEAE999BD' # Allan McRae + 'B8151B117037781095514CA7BBDFFC92306B1121') # Andrew Gregory (pacman) +# nghttp2 +source+=("https://github.com/nghttp2/nghttp2/releases/download/v$_nghttp2_ver/nghttp2-$_nghttp2_ver.tar.xz") +# c-ares +source+=("https://github.com/c-ares/c-ares/releases/download/v${_cares_ver}/c-ares-${_cares_ver}.tar.gz"{,.asc}) +validpgpkeys+=('27EDEAF22F3ABCEB50DB9A125CC908FDB71E12C2' # Daniel Stenberg + 'DA7D64E4C82C6294CB73A20E22E3D13B5411B7CA') # Brad House +# curl +source+=("https://curl.haxx.se/download/curl-${_curlver}.tar.gz"{,.asc}) +validpgpkeys+=('27EDEAF22F3ABCEB50DB9A125CC908FDB71E12C2') # Daniel Stenberg +# openssl +source+=("https://github.com/openssl/openssl/releases/download/openssl-${_sslver}/openssl-${_sslver}.tar.gz"{,.asc} + "ca-dir.patch" + "openssl-3.0.7-no-atomic.patch") +validpgpkeys+=('8657ABB260F056B1E5190839D9C4D26D0E604491' + '7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C' + 'A21FAB74B0088AA361152586B8EF1A6BA9DA2D5C' + 'EFC0A467D613CB83C7ED6D30D894E2CE8B3D79F5' + 'BA5473A2B0587B07FB27CF2D216094DFD0CB81EF') + +validpgpkeys+=('8657ABB260F056B1E5190839D9C4D26D0E604491' # Matt Caswell + '7953AC1FBC3DC8B3B292393ED5E9E43F7DF9EE8C' # Matt Caswell + 'A21FAB74B0088AA361152586B8EF1A6BA9DA2D5C' # Tomá? Mráz + 'EFC0A467D613CB83C7ED6D30D894E2CE8B3D79F5') # OpenSSL security team key +# zlib +source+=("https://zlib.net/zlib-${_zlibver}.tar.gz"{,.asc}) +validpgpkeys+=('5ED46A6721D365587791E2AA783FCD8E58BCAFBA') # Mark Adler +# xz +source+=("git+https://github.com/tukaani-project/xz#tag=v${_xzver}") +validpgpkeys+=('3690C240CE51B4670D30AD1C38EE757D69184620') # Lasse Collin +# bzip2 +source+=("https://sourceware.org/pub/bzip2/bzip2-${_bzipver}.tar.gz"{,.sig}) +validpgpkeys+=('EC3CFE88F6CA0788774F5C1D1AA44BE649DE760A') # Mark Wielaard +# zstd +source+=("https://github.com/facebook/zstd/releases/download/v${_zstdver}/zstd-${_zstdver}.tar.zst"{,.sig}) +validpgpkeys+=('4EF4AC63455FC9F4545D9B7DEF8FE99528B52FFD') # Zstandard Release Signing Key +# libgpg-error +source+=("https://gnupg.org/ftp/gcrypt/libgpg-error/libgpg-error-${_gpgerrorver}.tar.bz2"{,.sig}) +validpgpkeys+=('D8692123C4065DEA5E0F3AB5249B39D24F25E3B6' # Werner Koch + '031EC2536E580D8EA286A9F22071B08A33BD3F06' # NIIBE Yutaka (GnuPG Release Key) + '6DAA6E64A76D2840571B4902528897B826403ADA') # "Werner Koch (dist signing 2020)" +# libassuan +source+=("https://gnupg.org/ftp/gcrypt/libassuan/libassuan-${_libassuanver}.tar.bz2"{,.sig}) +# gpgme +source+=("https://www.gnupg.org/ftp/gcrypt/gpgme/gpgme-${_gpgmever}.tar.bz2"{,.sig}) +validpgpkeys+=('AC8E115BF73E2D8D47FA9908E98E9B2D19C6C8BD') # Niibe Yutaka (GnuPG Release Key) +# libarchive +source+=("https://github.com/libarchive/libarchive/releases/download/v${_libarchive_ver}/libarchive-${_libarchive_ver}.tar.xz"{,.asc}) +validpgpkeys+=('A5A45B12AD92D964B89EEE2DEC560C81CEC2276E' # Martin Matuska + 'DB2C7CF1B4C265FAEF56E3FC5848A18B8F14184B') # Martin Matuska + +sha512sums=('44e00c2bc259fe6a85de71f7fd8a43fcfd1b8fb7d920d2267bd5b347e02f1dab736b3d96e31faf7b535480398e2348f7c0b9914e51ca7e12bab2d5b8003926b4' + '1a108c4384b6104e627652488659de0b1ac3330640fc3250f0a283af7c5884daab187c1efc024b2545262da1911d2b0b7b0d5e4e5b68bb98db25a760c9f1fb1a' + 'b544196c3b7a55faacd11700d11e2fe4f16a7418282c9abb24a668544a15293580fd1a2cc5f93367c8a17c7ee45335c6d2f5c68a72dd176d516fd033f203eeec' + '3285e14d94bc736d6caddfe7ad7e3c6a6e69d49b079c989bb3e8aba4da62c022e38229d1e691aaa030b7d3bcd89e458d203f260806149a71ad9adb31606eae02' + 'SKIP' + '9fcdcceab8bce43e888db79a38c775ff15790a806d3cc5cc96f396a829c6da2383b258481b5642153da14087943f6ef607af0aa3b75df6f41b95c6cd61d835eb' + 'SKIP' + '1de6307c587686711f05d1e96731c43526fa3af51e4cd94c06c880954b67f6eb4c7db3177f0ea5937d41bc1f8cadcf5bce75025b5c1a46a469376960f1001c5f' + 'SKIP' + 'b1873dbb7a49460b007255689102062756972de5cc2d38b12cc9f389b6be412da6797579b1acd3717a8cd2ee118fd9801b94e55f063d4328f050f0876a5eb53c' + 'b5887ea77417fae49b6cb1e9fa782d3021f268d5219701d87a092235964f73fa72a31428b630445517f56f2bb69dcbbb24119ef9dbf8b4e40a753369a9f9a16f' + '580677aad97093829090d4b605ac81c50327e74a6c2de0b85dd2e8525553f3ddde17556ea46f8f007f89e435493c9a20bc997d1ef1c1c2c23274528e3c46b94f' + 'SKIP' + 'e3216eca5fae2c9ce419e698bfbe186903088dad0a579749cb49bcde8f9d4073b98bf1570fe69190a9a41feb2a7c9814498ec9b867527de1c74ff75a1cbdfc17' + '083f5e675d73f3233c7930ebe20425a533feedeaaa9d8cc86831312a6581cefbe6ed0d08d2fa89be81082f2a5abdabca8b3c080bf97218a1bd59dc118a30b9f3' + 'SKIP' + '21f9da445afd76acaf3acb22d216c2b584d95e8c68e00f5cb3f6673f2d556dd14a7593344adf8ffd194bba3314387ee0e486d6248f6c935abca2edd8a4cf95ed' + 'SKIP' + '4489f615c6a0389577a7d1fd7d3917517bb2fe032abd9a6d87dfdbd165dabcf53f8780645934020bf27517b67a064297475888d5b368176cf06bc22f1e735e2b' + 'SKIP' + '7c5c95c1b85bef2d4890c068a5a8ea8a1fe0d8def6ab09e5f34fc2746d8808bbb0fc168e3bd66d52ee5ed799dcf9f258f4125cda98c8384f6411bcad8d8b3139' + 'SKIP' + 'ad69101d1fceef6cd1dd6d5348f6f2be06912da6b6a7d0fece3ce08cf35054e6953b80ca9c4748554882892faa44e7c54e705cf25bbf2b796cd4ad12b09da185' + 'SKIP' + '2524f71f4c2ebc254a1927279be3394e820d0a0c6dec7ef835a862aa08c35756edaa4208bcdc710dd092872b59c200b555b78670372e2830822e278ff1ec4e4a' + 'SKIP') + +export LDFLAGS="$LDFLAGS -static" +export CC=musl-gcc +export CXX=musl-gcc + +# https://www.openwall.com/lists/musl/2014/11/05/3 +# fstack-protector and musl do not get along but only on i686 +if [[ $CARCH = i686 || $CARCH = pentium4 || $CARCH = i486 ]]; then + # silly build systems have configure checks or buildtime programs that don't CFLAGS but do do CC + export CC="musl-gcc -fno-stack-protector" + export CXX="musl-gcc -fno-stack-protector" + export CFLAGS="${CFLAGS/-fstack-protector-strong/}" + export CXXFLAGS="${CXXFLAGS/-fstack-protector-strong/}" +fi + +# to enable func64 interface in musl for 64-bit file system functions +export CFLAGS+=' -D_LARGEFILE64_SOURCE' +export CXXFLAGS+=' -D_LARGEFILE64_SOURCE' + +# keep using xz-compressed packages, because one use of the package is to +# recover on systems with broken zstd support in libarchive +[[ $PKGEXT = .pkg.tar.zst ]] && PKGEXT=.pkg.tar.xz + +prepare() { + cd "${srcdir}/pacman" + + # apply patch level commits on top of annotated tag for pacman + if [[ -n ${_git_patch_level_commit} ]]; then + if [[ v${_git_tag} != $(git describe --tags --abbrev=0 "${_git_patch_level_commit}") ]] then + error "patch level commit ${_git_patch_level_commit} is not a descendant of v${_git_tag}" + exit 1 + fi + git rebase "${_git_patch_level_commit}" + fi + + # handle local pacman patches + local -a patches + patches=($(printf '%s\n' "${source[@]}" | grep 'pacman-.*.patch')) + patches=("${patches[@]%%::*}") + patches=("${patches[@]##*/}") + + if (( ${#patches[@]} != 0 )); then + for patch in "${patches[@]}"; do + if [[ $patch =~ revertme-* ]]; then + msg2 "Reverting patch $patch..." + patch -RNp1 < "../$patch" + else + msg2 "Applying patch $patch..." + patch -Np1 < "../$patch" + fi + done + fi + + # openssl + cd "${srcdir}"/openssl-${_sslver} + patch -Np1 -i "${srcdir}/ca-dir.patch" + case ${CARCH} in + arm|armv6h|armv7h) + # special patch to omit -latomic when installing pkgconfig files + msg2 "Applying openssl patch openssl-3.0.7-no-atomic.patch..." + patch -Np1 -i "${srcdir}/openssl-3.0.7-no-atomic.patch" + esac +} + +build() { + export PKG_CONFIG_PATH="${srcdir}"/temp/usr/lib/pkgconfig + export PATH="${srcdir}/temp/usr/bin:${PATH}" + + # openssl + cd "${srcdir}"/openssl-${_sslver} + case ${CARCH} in + x86_64) + openssltarget='linux-x86_64' + optflags='enable-ec_nistp_64_gcc_128' + ;; + pentium4) + openssltarget='linux-elf' + optflags='' + ;; + i686) + openssltarget='linux-elf' + optflags='no-sse2' + ;; + i486) + openssltarget='linux-elf' + optflags='386 no-threads' + ;; + arm|armv6h|armv7h) + openssltarget='linux-armv4' + optflags='' + ;; + aarch64) + openssltarget='linux-aarch64' + optflags='no-afalgeng' + ;; + esac + # mark stack as non-executable: http://bugs.archlinux.org/task/12434 + ./Configure --prefix="${srcdir}"/temp/usr \ + --openssldir=/etc/ssl \ + --libdir=lib \ + -static \ + no-ssl3-method \ + ${optflags} \ + "${openssltarget}" \ + "-Wa,--noexecstack ${CPPFLAGS} ${CFLAGS} ${LDFLAGS}" + make build_libs + make install_dev + + # xz + cd "${srcdir}"/xz + ./autogen.sh --no-po4a --no-doxygen + ./configure --prefix="${srcdir}"/temp/usr \ + --disable-shared + cd src/liblzma + make + make install + + # bzip2 + cd "${srcdir}"/bzip2-${_bzipver} + sed -i "s|-O2|${CFLAGS}|g;s|CC=gcc|CC=${CC}|g" Makefile + make libbz2.a + install -Dvm644 bzlib.h "${srcdir}"/temp/usr/include/ + install -Dvm644 libbz2.a "${srcdir}"/temp/usr/lib/ + + cd "${srcdir}"/zstd-${_zstdver}/lib + make libzstd.a + make PREFIX="${srcdir}"/temp/usr install-pc install-static install-includes + + # zlib + cd "${srcdir}/"zlib-${_zlibver} + ./configure --prefix="${srcdir}"/temp/usr \ + --static + make libz.a + make install + + # libarchive + cd "${srcdir}"/libarchive-${_libarchive_ver} + CPPFLAGS="-I${srcdir}/temp/usr/include" CFLAGS="-L${srcdir}/temp/usr/lib" \ + ./configure --prefix="${srcdir}"/temp/usr \ + --without-xml2 \ + --without-nettle \ + --disable-{bsdtar,bsdcat,bsdcpio,bsdunzip} \ + --without-expat \ + --disable-shared + make + make install-{includeHEADERS,libLTLIBRARIES,pkgconfigDATA,includeHEADERS} + + # nghttp2 + cd "${srcdir}"/nghttp2-${_nghttp2_ver} + ./configure --prefix="${srcdir}"/temp/usr \ + --disable-shared \ + --disable-examples \ + --disable-python-bindings + make -C lib + make -C lib install + + # c-ares + # needed for curl, which does not use it in the repos + # but seems to be needed for static builds + cd "${srcdir}"/c-ares-${_cares_ver} + ./configure --prefix="${srcdir}"/temp/usr \ + --disable-shared + make -C src/lib + make install-pkgconfigDATA + make -C src/lib install + make -C include install + + # curl + cd "${srcdir}"/curl-${_curlver} + # c-ares is not detected via pkg-config :( + ./configure --prefix="${srcdir}"/temp/usr \ + --disable-shared \ + --with-ca-bundle=/etc/ssl/certs/ca-certificates.crt \ + --disable-{dict,gopher,imap,ldap,ldaps,manual,pop3,rtsp,smb,smtp,telnet,tftp} \ + --without-{brotli,libidn2,librtmp,libssh2,libpsl} \ + --disable-libcurl-option \ + --with-openssl \ + --enable-ares="${srcdir}"/temp/usr + make -C lib + make install-pkgconfigDATA + make -C lib install + make -C include install + + # libgpg-error + cd "${srcdir}"/libgpg-error-${_gpgerrorver} + ./configure --prefix="${srcdir}"/temp/usr \ + --disable-shared + make -C src + make -C src install-{binSCRIPTS,libLTLIBRARIES,nodist_includeHEADERS,pkgconfigDATA} + + # libassuan + cd "${srcdir}"/libassuan-${_libassuanver} + ./configure --prefix="${srcdir}"/temp/usr \ + --disable-shared + make -C src + make -C src install-{binSCRIPTS,libLTLIBRARIES,nodist_includeHEADERS,pkgconfigDATA} + + # gpgme + cd "${srcdir}"/gpgme-${_gpgmever} + ./configure --prefix="${srcdir}"/temp/usr \ + --disable-fd-passing \ + --disable-shared \ + --disable-languages + make -C src + make -C src install-{binSCRIPTS,libLTLIBRARIES,nodist_includeHEADERS,pkgconfigDATA} + + # ew libtool + rm "${srcdir}"/temp/usr/lib/lib*.la + + # Finally, it's a pacman! + mkdir -p "${srcdir}"/pacman + cd "${srcdir}"/pacman + meson --prefix=/usr \ + --includedir=lib/pacman/include \ + --libdir=lib/pacman/lib \ + --buildtype=plain \ + -Dbuildstatic=true \ + -Ddefault_library=static \ + -Ddoc=disabled \ + -Ddoxygen=disabled \ + -Dldconfig=/usr/bin/ldconfig \ + -Dscriptlet-shell=/usr/bin/bash \ + build + meson compile -C build +} + +package() { + cd "${srcdir}"/pacman + DESTDIR="${pkgdir}" meson install -C build + + rm -rf "${pkgdir}"/usr/share "${pkgdir}"/etc + for exe in "${pkgdir}"/usr/bin/*; do + if [[ -f ${exe} && $(head -c4 "${exe}") = $'\x7fELF' ]]; then + mv "${exe}" "${exe}"-static + else + rm "${exe}" + fi + done + + cp -a "${srcdir}"/temp/usr/{bin,include,lib} "${pkgdir}"/usr/lib/pacman/ + sed -i "s@${srcdir}/temp/usr@/usr/lib/pacman@g" \ + "${pkgdir}"/usr/lib/pacman/lib/pkgconfig/*.pc \ + "${pkgdir}"/usr/lib/pacman/bin/* +}