Files
patches/nss/nss-3.122-meson-build.patch
2026-05-26 02:08:47 -05:00

774 lines
18 KiB
Diff

diff --git a/nss/meson.build b/nss/meson.build
new file mode 100644
--- /dev/null
+++ b/nss/meson.build
@@ -0,0 +1,147 @@
+project('nss', 'c')
+
+py = import('python').find_installation('python3')
+sh = find_program('sh')
+
+buildtype = get_option('buildtype')
+if buildtype == 'debug'
+ nss_target = 'Debug'
+else
+ nss_target = 'Release'
+endif
+
+build_args = []
+if buildtype != 'debug'
+ build_args += ['--opt']
+endif
+if not get_option('build_tests')
+ build_args += ['--disable-tests']
+endif
+if get_option('enable_fips')
+ build_args += ['--enable-fips']
+endif
+if get_option('enable_libpkix')
+ build_args += ['--enable-libpkix']
+endif
+if get_option('enable_legacy_db')
+ build_args += ['--enable-legacy-db']
+endif
+if get_option('system_sqlite')
+ build_args += ['--system-sqlite']
+endif
+
+nspr_version = get_option('nspr_version')
+if nspr_version == 'auto'
+ nspr_dep = dependency('nspr', required : false)
+ if not nspr_dep.found()
+ nspr_dep = dependency('nspr4', required : false)
+ endif
+ if not nspr_dep.found()
+ error('Unable to determine the NSPR version. Install pkg-config metadata for NSPR or configure with -Dnspr_version=...')
+ endif
+ nspr_version = nspr_dep.version()
+endif
+
+version_cmd = [
+ '-c',
+ '''import pathlib,re,sys
+text = pathlib.Path(sys.argv[1]).read_text()
+match = re.search(r'#define\s+NSS_VERSION\s+"([^"]+)"', text)
+if not match:
+ raise SystemExit('unable to parse NSS_VERSION')
+version = match.group(1)
+parts = (version.split('.') + ['0', '0'])[:3]
+print(version)
+print(parts[0])
+print(parts[1])
+print(parts[2])
+''',
+ join_paths(meson.current_source_dir(), 'lib', 'nss', 'nss.h'),
+]
+version_info = run_command(py, version_cmd, check : true).stdout().strip().split('\n')
+nss_version = version_info[0]
+nss_major_version = version_info[1]
+nss_minor_version = version_info[2]
+nss_patch_version = version_info[3]
+
+prefix = get_option('prefix')
+exec_prefix = prefix
+libdir = join_paths(prefix, get_option('libdir'))
+includedir = join_paths(prefix, get_option('includedir'), 'nss')
+
+pkgconf = configuration_data()
+pkgconf.set('prefix', prefix)
+pkgconf.set('exec_prefix', exec_prefix)
+pkgconf.set('libdir', libdir)
+pkgconf.set('includedir', includedir)
+pkgconf.set('NSS_VERSION', nss_version)
+pkgconf.set('NSPR_VERSION', nspr_version)
+
+scriptconf = configuration_data()
+scriptconf.set('prefix', prefix)
+scriptconf.set('MOD_MAJOR_VERSION', nss_major_version)
+scriptconf.set('MOD_MINOR_VERSION', nss_minor_version)
+scriptconf.set('MOD_PATCH_VERSION', nss_patch_version)
+
+configure_file(
+ input : 'meson/nss.pc.in',
+ output : 'nss.pc',
+ configuration : pkgconf,
+ install : true,
+ install_dir : join_paths(get_option('libdir'), 'pkgconfig'),
+)
+
+configure_file(
+ input : 'meson/nss-config.in',
+ output : 'nss-config',
+ configuration : scriptconf,
+ install : true,
+ install_dir : get_option('bindir'),
+ install_mode : 'rwxr-xr-x',
+)
+
+nss_build_root = join_paths(meson.current_build_dir(), 'nss-build')
+
+custom_target(
+ 'nss-build',
+ output : 'nss-build.stamp',
+ command : [
+ sh,
+ files('meson/build_nss.sh'),
+ '--source-dir',
+ meson.current_source_dir(),
+ '--build-root',
+ nss_build_root,
+ '--gyp',
+ get_option('gyp'),
+ '--nspr',
+ get_option('nspr'),
+ '--stamp',
+ '@OUTPUT@',
+ '--',
+ ] + build_args,
+ build_by_default : true,
+ build_always_stale : true,
+ console : true,
+)
+
+meson.add_install_script(
+ py,
+ files('meson/install_nss.py'),
+ '--build-root',
+ nss_build_root,
+ '--target',
+ nss_target,
+ '--libdir',
+ get_option('libdir'),
+ '--bindir',
+ get_option('bindir'),
+ '--includedir',
+ get_option('includedir'),
+ '--install-private-headers',
+ get_option('install_private_headers') ? 'true' : 'false',
+ '--install-tools',
+ get_option('install_tools') ? 'true' : 'false',
+ '--install-ckbi',
+ get_option('install_ckbi') ? 'true' : 'false',
+)
diff --git a/nss/meson_options.txt b/nss/meson_options.txt
new file mode 100644
--- /dev/null
+++ b/nss/meson_options.txt
@@ -0,0 +1,66 @@
+option(
+ 'build_tests',
+ type : 'boolean',
+ value : false,
+ description : 'Build NSS tests and the extra test-only helper binaries'
+)
+option(
+ 'enable_fips',
+ type : 'boolean',
+ value : false,
+ description : 'Enable FIPS checks in the GYP build'
+)
+option(
+ 'enable_libpkix',
+ type : 'boolean',
+ value : false,
+ description : 'Build libpkix support'
+)
+option(
+ 'enable_legacy_db',
+ type : 'boolean',
+ value : false,
+ description : 'Build the legacy DB module'
+)
+option(
+ 'system_sqlite',
+ type : 'boolean',
+ value : false,
+ description : 'Link against the system sqlite library'
+)
+option(
+ 'install_private_headers',
+ type : 'boolean',
+ value : false,
+ description : 'Install headers from dist/private/nss in addition to the public API'
+)
+option(
+ 'install_tools',
+ type : 'boolean',
+ value : true,
+ description : 'Install the NSS command-line tools from dist/<cfg>/bin'
+)
+option(
+ 'install_ckbi',
+ type : 'boolean',
+ value : false,
+ description : 'Install libnssckbi.so; disable by default to avoid conflicts with p11-kit trust modules'
+)
+option(
+ 'gyp',
+ type : 'string',
+ value : 'auto',
+ description : 'Path to the gyp executable, or auto to resolve gyp/gyp-next from PATH'
+)
+option(
+ 'nspr',
+ type : 'string',
+ value : 'auto',
+ description : 'NSPR include:lib pair for build.sh, or auto to resolve it with pkg-config'
+)
+option(
+ 'nspr_version',
+ type : 'string',
+ value : 'auto',
+ description : 'NSPR version string to embed in nss.pc when pkg-config metadata is unavailable'
+)
diff --git a/nss/meson/build_nss.sh b/nss/meson/build_nss.sh
new file mode 100644
--- /dev/null
+++ b/nss/meson/build_nss.sh
@@ -0,0 +1,243 @@
+#!/bin/sh
+
+set -eu
+
+source_dir=
+build_root=
+gyp_bin=auto
+nspr=auto
+stamp=
+build_args=
+
+append_arg() {
+ if [ -n "$build_args" ]; then
+ build_args="$build_args
+$1"
+ else
+ build_args=$1
+ fi
+}
+
+while [ $# -gt 0 ]; do
+ case "$1" in
+ --source-dir)
+ source_dir=$2
+ shift 2
+ ;;
+ --build-root)
+ build_root=$2
+ shift 2
+ ;;
+ --gyp)
+ gyp_bin=$2
+ shift 2
+ ;;
+ --nspr)
+ nspr=$2
+ shift 2
+ ;;
+ --stamp)
+ stamp=$2
+ shift 2
+ ;;
+ --)
+ shift
+ break
+ ;;
+ *)
+ echo "Unknown option: $1" >&2
+ exit 2
+ ;;
+ esac
+done
+
+while [ $# -gt 0 ]; do
+ append_arg "$1"
+ shift
+done
+
+if [ -z "$source_dir" ] || [ -z "$build_root" ] || [ -z "$stamp" ]; then
+ echo "Missing required arguments" >&2
+ exit 2
+fi
+
+resolve_gyp() {
+ if [ "$gyp_bin" != "auto" ]; then
+ echo "$gyp_bin"
+ return 0
+ fi
+
+ if [ -n "${GYP:-}" ]; then
+ echo "$GYP"
+ return 0
+ fi
+
+ if command -v gyp >/dev/null 2>&1; then
+ command -v gyp
+ return 0
+ fi
+
+ if command -v gyp-next >/dev/null 2>&1; then
+ command -v gyp-next
+ return 0
+ fi
+
+ echo "Unable to find gyp. Configure Meson with -Dgyp=/path/to/gyp." >&2
+ exit 1
+}
+
+pkg_config_var() {
+ package=$1
+ variable=$2
+ if pkg-config --exists "$package" 2>/dev/null; then
+ pkg-config --variable="$variable" "$package"
+ return 0
+ fi
+ return 1
+}
+
+resolve_nspr() {
+ if [ "$nspr" != "auto" ]; then
+ case "$nspr" in
+ *:*)
+ echo "$nspr"
+ return 0
+ ;;
+ *)
+ echo "The -Dnspr option must use the form <include>:<lib>." >&2
+ exit 1
+ ;;
+ esac
+ fi
+
+ for package in nspr nspr4; do
+ include_dir=$(pkg_config_var "$package" includedir || true)
+ lib_dir=$(pkg_config_var "$package" libdir || true)
+ if [ -n "$include_dir" ] && [ -n "$lib_dir" ]; then
+ echo "$include_dir:$lib_dir"
+ return 0
+ fi
+ done
+
+ echo "Unable to resolve NSPR. Configure Meson with -Dnspr=<include>:<lib>." >&2
+ exit 1
+}
+
+detect_jobs() {
+ if [ -n "${MESON_NUM_PROCESSES:-}" ]; then
+ echo "$MESON_NUM_PROCESSES"
+ return 0
+ fi
+
+ if command -v getconf >/dev/null 2>&1; then
+ jobs=$(getconf _NPROCESSORS_ONLN 2>/dev/null || true)
+ if [ -n "$jobs" ]; then
+ echo "$jobs"
+ return 0
+ fi
+ fi
+
+ echo 1
+}
+
+detect_target_arch() {
+ "${PYTHON:-python3}" "$source_dir/coreconf/detect_host_arch.py"
+}
+
+gyp_bin=$(resolve_gyp)
+nspr=$(resolve_nspr)
+jobs=$(detect_jobs)
+target_arch=$(detect_target_arch)
+target=Debug
+disable_tests=0
+enable_fips=0
+enable_libpkix=0
+enable_legacy_db=0
+system_sqlite=0
+
+if [ -n "$build_args" ]; then
+ old_ifs=$IFS
+ IFS='
+'
+ for arg in $build_args; do
+ case "$arg" in
+ --opt)
+ target=Release
+ ;;
+ --disable-tests)
+ disable_tests=1
+ ;;
+ --enable-fips)
+ enable_fips=1
+ ;;
+ --enable-libpkix)
+ enable_libpkix=1
+ ;;
+ --enable-legacy-db)
+ enable_legacy_db=1
+ ;;
+ --system-sqlite)
+ system_sqlite=1
+ ;;
+ *)
+ echo "Unsupported build option: $arg" >&2
+ exit 1
+ ;;
+ esac
+ done
+ IFS=$old_ifs
+fi
+
+dist_dir=$build_root/dist
+out_dir=$build_root/out
+target_dir=$out_dir/$target
+mkdir -p "$dist_dir" "$target_dir"
+
+nspr_include_dir=${nspr%%:*}
+nspr_lib_dir=${nspr#*:}
+
+set -- \
+ --depth="$source_dir" \
+ --generator-output="$build_root" \
+ -Dtarget_arch="$target_arch" \
+ -Dnss_dist_dir="$dist_dir" \
+ -Dnss_dist_obj_dir="$dist_dir/$target" \
+ -Dnspr_include_dir="$nspr_include_dir" \
+ -Dnspr_lib_dir="$nspr_lib_dir" \
+ -Denable_sslkeylogfile=1
+
+if [ "$disable_tests" = 1 ]; then
+ set -- "$@" -Ddisable_tests=1
+fi
+if [ "$enable_fips" = 1 ]; then
+ set -- "$@" -Ddisable_fips=0
+fi
+if [ "$enable_libpkix" = 1 ]; then
+ set -- "$@" -Ddisable_libpkix=0
+fi
+if [ "$enable_legacy_db" = 1 ]; then
+ set -- "$@" -Ddisable_dbm=0
+fi
+if [ "$system_sqlite" = 1 ]; then
+ set -- "$@" -Duse_system_sqlite=1
+fi
+
+(
+ cd "$source_dir"
+ "$gyp_bin" -f ninja "$@" "$source_dir/nss.gyp"
+)
+if command -v ninja-build >/dev/null 2>&1; then
+ ninja_bin=$(command -v ninja-build)
+elif command -v ninja >/dev/null 2>&1; then
+ ninja_bin=$(command -v ninja)
+else
+ echo "Unable to find ninja." >&2
+ exit 1
+fi
+
+(
+ cd "$source_dir"
+ "$ninja_bin" -C "$target_dir" -j "$jobs"
+)
+
+printf '%s\n' "$build_root" >"$stamp"
diff --git a/nss/meson/install_nss.py b/nss/meson/install_nss.py
new file mode 100644
--- /dev/null
+++ b/nss/meson/install_nss.py
@@ -0,0 +1,105 @@
+#!/usr/bin/env python3
+
+import argparse
+import os
+import pathlib
+import shutil
+
+
+def bool_arg(value: str) -> bool:
+ return value.lower() in {'1', 'true', 'yes', 'on'}
+
+
+def install_root(prefix: pathlib.Path, path: str) -> pathlib.Path:
+ candidate = pathlib.Path(path)
+ if candidate.is_absolute():
+ return candidate
+ return prefix / candidate
+
+
+def install_entry(src: pathlib.Path, dst: pathlib.Path) -> None:
+ dst.parent.mkdir(parents=True, exist_ok=True)
+ if dst.exists() or dst.is_symlink():
+ if dst.is_dir() and not dst.is_symlink():
+ shutil.rmtree(dst)
+ else:
+ dst.unlink()
+
+ if src.is_symlink():
+ dst.symlink_to(os.readlink(src))
+ elif src.is_dir():
+ shutil.copytree(src, dst, symlinks=True)
+ else:
+ shutil.copy2(src, dst)
+
+
+def install_tree(src: pathlib.Path, dst: pathlib.Path) -> None:
+ if not src.exists():
+ return
+
+ for entry in sorted(src.iterdir()):
+ install_entry(entry, dst / entry.name)
+
+
+def install_filtered_libs(src: pathlib.Path, dst: pathlib.Path, install_ckbi: bool) -> None:
+ if not src.exists():
+ return
+
+ for entry in sorted(src.iterdir()):
+ if entry.name.endswith('.TOC'):
+ continue
+ if not install_ckbi and entry.name.startswith('libnssckbi.so'):
+ continue
+ if entry.suffix in {'.a', '.chk', '.so'} or '.so.' in entry.name:
+ install_entry(entry, dst / entry.name)
+
+
+def install_tools(src: pathlib.Path, dst: pathlib.Path) -> None:
+ if not src.exists():
+ return
+
+ for entry in sorted(src.iterdir()):
+ if entry.is_dir():
+ continue
+ if os.access(entry, os.X_OK):
+ install_entry(entry, dst / entry.name)
+
+
+def main() -> int:
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--build-root', required=True)
+ parser.add_argument('--target', required=True)
+ parser.add_argument('--libdir', required=True)
+ parser.add_argument('--bindir', required=True)
+ parser.add_argument('--includedir', required=True)
+ parser.add_argument('--install-private-headers', required=True)
+ parser.add_argument('--install-tools', required=True)
+ parser.add_argument('--install-ckbi', required=True)
+ args = parser.parse_args()
+
+ install_prefix = pathlib.Path(
+ os.environ.get('MESON_INSTALL_DESTDIR_PREFIX', os.environ['MESON_INSTALL_PREFIX'])
+ )
+ libdir = install_root(install_prefix, args.libdir)
+ bindir = install_root(install_prefix, args.bindir)
+ includedir = install_root(install_prefix, args.includedir)
+
+ build_root = pathlib.Path(args.build_root)
+ dist_root = build_root / 'dist'
+ public_headers = dist_root / 'public' / 'nss'
+ private_headers = dist_root / 'private' / 'nss'
+ target_root = dist_root / args.target
+
+ install_tree(public_headers, includedir / 'nss')
+ if bool_arg(args.install_private_headers):
+ install_tree(private_headers, includedir / 'nss-private')
+
+ install_filtered_libs(target_root / 'lib', libdir, bool_arg(args.install_ckbi))
+ if bool_arg(args.install_tools):
+ install_tools(target_root / 'bin', bindir)
+
+ return 0
+
+
+if __name__ == '__main__':
+ raise SystemExit(main())
diff --git a/nss/meson/nss-config.in b/nss/meson/nss-config.in
new file mode 100644
--- /dev/null
+++ b/nss/meson/nss-config.in
@@ -0,0 +1,144 @@
+#!/bin/sh
+
+prefix=@prefix@
+
+major_version=@MOD_MAJOR_VERSION@
+minor_version=@MOD_MINOR_VERSION@
+patch_version=@MOD_PATCH_VERSION@
+
+usage()
+{
+ cat <<EOF
+Usage: nss-config [OPTIONS] [LIBRARIES]
+Options:
+ [--prefix[=DIR]]
+ [--exec-prefix[=DIR]]
+ [--includedir[=DIR]]
+ [--libdir[=DIR]]
+ [--version]
+ [--libs]
+ [--cflags]
+Dynamic Libraries:
+ nss
+ nssutil
+ ssl
+ smime
+EOF
+ exit $1
+}
+
+if test $# -eq 0; then
+ usage 1 1>&2
+fi
+
+lib_ssl=yes
+lib_smime=yes
+lib_nss=yes
+lib_nssutil=yes
+
+while test $# -gt 0; do
+ case "$1" in
+ -*=*) optarg=`echo "$1" | sed 's/[-_a-zA-Z0-9]*=//'` ;;
+ *) optarg= ;;
+ esac
+
+ case $1 in
+ --prefix=*)
+ prefix=$optarg
+ ;;
+ --prefix)
+ echo_prefix=yes
+ ;;
+ --exec-prefix=*)
+ exec_prefix=$optarg
+ ;;
+ --exec-prefix)
+ echo_exec_prefix=yes
+ ;;
+ --includedir=*)
+ includedir=$optarg
+ ;;
+ --includedir)
+ echo_includedir=yes
+ ;;
+ --libdir=*)
+ libdir=$optarg
+ ;;
+ --libdir)
+ echo_libdir=yes
+ ;;
+ --version)
+ echo ${major_version}.${minor_version}.${patch_version}
+ ;;
+ --cflags)
+ echo_cflags=yes
+ ;;
+ --libs)
+ echo_libs=yes
+ ;;
+ ssl)
+ lib_ssl=yes
+ ;;
+ smime)
+ lib_smime=yes
+ ;;
+ nss)
+ lib_nss=yes
+ ;;
+ nssutil)
+ lib_nssutil=yes
+ ;;
+ *)
+ usage 1 1>&2
+ ;;
+ esac
+ shift
+done
+
+# Set variables that may be dependent upon other variables
+if test -z "$exec_prefix"; then
+ exec_prefix=`pkg-config --variable=exec_prefix nss`
+fi
+if test -z "$includedir"; then
+ includedir=`pkg-config --variable=includedir nss`
+fi
+if test -z "$libdir"; then
+ libdir=`pkg-config --variable=libdir nss`
+fi
+
+if test "$echo_prefix" = "yes"; then
+ echo $prefix
+fi
+
+if test "$echo_exec_prefix" = "yes"; then
+ echo $exec_prefix
+fi
+
+if test "$echo_includedir" = "yes"; then
+ echo $includedir
+fi
+
+if test "$echo_libdir" = "yes"; then
+ echo $libdir
+fi
+
+if test "$echo_cflags" = "yes"; then
+ echo -I$includedir
+fi
+
+if test "$echo_libs" = "yes"; then
+ libdirs="-Wl,-rpath-link,$libdir -L$libdir"
+ if test -n "$lib_ssl"; then
+ libdirs="$libdirs -lssl${major_version}"
+ fi
+ if test -n "$lib_smime"; then
+ libdirs="$libdirs -lsmime${major_version}"
+ fi
+ if test -n "$lib_nss"; then
+ libdirs="$libdirs -lnss${major_version}"
+ fi
+ if test -n "$lib_nssutil"; then
+ libdirs="$libdirs -lnssutil${major_version}"
+ fi
+ echo $libdirs
+fi
diff --git a/nss/meson/nss.pc.in b/nss/meson/nss.pc.in
new file mode 100644
--- /dev/null
+++ b/nss/meson/nss.pc.in
@@ -0,0 +1,11 @@
+prefix=@prefix@
+exec_prefix=@exec_prefix@
+libdir=@libdir@
+includedir=@includedir@
+
+Name: NSS
+Description: Network Security Services
+Version: @NSS_VERSION@
+Requires: nspr >= @NSPR_VERSION@
+Libs: -L${libdir} -lssl3 -lsmime3 -lnss3 -lnssutil3
+Cflags: -I${includedir}
diff --git a/nss/readme.md b/nss/readme.md
--- a/nss/readme.md
+++ b/nss/readme.md
@@ -44,6 +44,23 @@
See [help.txt](https://hg.mozilla.org/projects/nss/raw-file/tip/help.txt) for
more information on using build.sh.
+## Building and Installing with Meson
+
+NSS also ships a Meson wrapper that drives the existing `build.sh`/GYP build
+and installs the resulting headers, libraries, tools, `nss.pc`, and
+`nss-config`.
+
+ meson setup build -Dgyp=/path/to/gyp
+ meson compile -C build
+ meson install -C build
+
+If NSPR is not available via `pkg-config`, pass it explicitly as
+`-Dnspr=/path/to/include:/path/to/lib`. Meson keeps the GYP output inside the
+Meson build tree and installs public headers to `${includedir}/nss`. The
+Meson install defaults to skipping `libnssckbi.so` to avoid file conflicts
+with `p11-kit` trust module packages; enable `-Dinstall_ckbi=true` if you
+explicitly want NSS to install that module.
+
## Building NSS (legacy build system)
After changing into the NSS directory a typical build of 32-bit NSS is done as