Blob Blame History Raw
# This package is rather exotic. The compiled library is a typical shared
# library with a C API. However, it has only a tiny bit of C source code. Most
# of the library is written in TypeScript, which is transpiled to C, via LLVM
# IR, using llparse (https://github.com/nodejs/llparse)—all of which happens
# within the NodeJS ecosystem.
#
# The package therefore “builds like” a NodeJS package, and to the extent they
# are relevant we apply the NodeJS packaging guidelines. However, the result of
# the build “installs like” a traditional C library package and has no NodeJS
# dependencies, including bundled ones.
#
# Furthermore, the package is registered with npm as “llhttp”, but current
# releases are not published there, so we use the GitHub archive as the
# canonical source and use a custom bundler script based on
# nodejs-packaging-bundler to fetch NodeJS build dependencies.
#
# Overall, we cherry-pick from the standard and NodeJS packaging guidelines as
# each seems to best apply, understanding that this package does not fit well
# into any of the usual patterns or templates.

# Upstream has been asked to provide a proper .so version:
# https://github.com/nodejs/llhttp/issues/140
# …but for now, we must version the shared library downstream.
%global downstream_soversion 0.1

Name:           llhttp
Version:        6.0.6
Release:        %autorelease
Summary:        Port of http_parser to llparse

# License of llhttp is MIT; nothing from the NodeJS dependency bundle is
# installed, so its contents do not contribute to the license of the binary
# RPMs, and we do not need a file llhttp-%%{version}-bundled-licenses.txt.
License:        MIT
URL:            https://github.com/nodejs/llhttp
Source0:        %{url}/archive/v%{version}/llhttp-%{version}.tar.gz

# Based closely on nodejs-packaging-bundler, except:
#
# - The GitHub source tarball specified in this spec file is used since the
#   current version is not typically published on npm
# - No production dependency bundle is generated, since none is needed—and
#   therefore, no bundled licenses text file is generated either
Source1:        llhttp-packaging-bundler
# Created with llhttp-packaging-bundler (Source1):
Source2:        llhttp-%{version}-nm-dev.tgz

# While nothing in the dev bundle is installed, we still choose to audit for
# null licenses at build time and to keep manually-approved exceptions in a
# file.
Source3:        check-null-licenses
Source4:        audited-null-licenses.toml

# The compiled RPM does not depend on NodeJS at all, but we cannot *build* it
# on architectures without NodeJS.
ExclusiveArch:  %{nodejs_arches}

# For generating the C source “release” from TypeScript:
BuildRequires:  nodejs-devel
BuildRequires:  make

# For compiling the C library
BuildRequires:  cmake
BuildRequires:  gcc

# For tests
BuildRequires:  clang

# For check-null-licenses
BuildRequires:  python3-devel
BuildRequires:  python3dist(toml)

%description
This project is a port of http_parser to TypeScript. llparse is used to
generate the output C source file, which could be compiled and linked with the
embedder's program (like Node.js).

This copy of the library is compiled with LLHTTP_STRICT_MODE set to 0
(disabled), which is the default.


%package devel
Summary:        Development files for llhttp

Requires:       llhttp%{?_isa} = %{?epoch:%{epoch}:}%{version}-%{release}

%description devel
The llhttp-devel package contains libraries and header files for
developing applications that use llhttp.


%prep
%autosetup

# Set up bundled (dev) node modules required to generate the C sources from the
# TypeScript sources.
tar -xzf '%{SOURCE2}'
mkdir -p node_modules
pushd node_modules
ln -s ../node_modules_dev/* .
ln -s ../node_modules_dev/.bin .
popd

# We run ts-node out of node_modules/.bin rather than using npx (which we will
# not have available).
sed -r -i 's@\bnpx[[:blank:]](ts-node)\b@node_modules/.bin/\1@' Makefile


%build
# Generate the C source “release” from TypeScript using the “node_modules_dev”
# bundle.
%make_build release
# Apply downstream .so versioning
cat >> release/CMakeLists.txt <<'EOF'
set_target_properties(llhttp PROPERTIES SOVERSION %{downstream_soversion})
EOF
# Fix multilib install paths. We hoped this change would be sufficient, but it
# seems to fix the install paths of the CMake files only, so we still need to
# move the libraries after they are installed.
sed -r -i 's@\b(DESTINATION[[:blank:]]+)lib($|/)@\1%{_libdir}\2@' \
    release/CMakeLists.txt

# To help prove that nothing from the bundled NodeJS dependencies is included
# in the binary packages, remove the “node_modules” symlinks.
rm -rvf node_modules

cd release
%cmake -DBUILD_SHARED_LIBS:BOOL=ON
%cmake_build


%install
cd release
%cmake_install
if [ '%{_prefix}/lib' != '%{_libdir}' ]
then
  mv -v %{buildroot}%{_prefix}/lib/libllhttp.so* '%{buildroot}/%{_libdir}'
  # Document the expectation that this directory is now empty:
  rmdir '%{buildroot}%{_prefix}/lib'
fi


%check
# Symlink the NodeJS bundle again so that we can test with Mocha
mkdir -p node_modules
pushd node_modules
ln -s ../node_modules_dev/* .
ln -s ../node_modules_dev/.bin .
popd

# Verify that no bundled dev dependency has a null license field, unless we
# already audited it by hand. This reduces the chance of accidentally including
# code with license problems in the source RPM.
%{python3} '%{SOURCE3}' --exceptions '%{SOURCE4}' --with dev node_modules_dev

# See scripts.mocha in package.json:
NODE_ENV=test ./node_modules/.bin/mocha \
    -r ts-node/register/type-check \
    test/*-test.ts


%files
%license release/LICENSE-MIT
%{_libdir}/libllhttp.so.%{downstream_soversion}


%files devel
%doc release/README.md
%{_includedir}/llhttp.h
%{_libdir}/libllhttp.so
%{_libdir}/cmake/llhttp


%changelog
%autochangelog