public inbox for gentoo-dev@lists.gentoo.org
 help / color / mirror / Atom feed
From: Zurab Kvachadze <zurabid2016@gmail.com>
To: gentoo-dev@lists.gentoo.org
Cc: Zurab Kvachadze <zurabid2016@gmail.com>
Subject: [gentoo-dev] [RFC PATCH 02/19] nginx-module.eclass: Add new eclass for building NGINX external modules
Date: Wed, 17 Jul 2024 15:05:34 +0300	[thread overview]
Message-ID: <20240717120553.31866-3-zurabid2016@gmail.com> (raw)
In-Reply-To: <20240717120553.31866-1-zurabid2016@gmail.com>

Currently, it is impossible for NGINX external modules to be packaged
on their own, separately from the NGINX ebuild. The nginx-module.eclass
enables packaging third party NGINX modules as any other software in the
Gentoo tree.

The eclass builds on the foundation provided by nginx.eclass.

NGINX modules are somewhat special in the way they are built. In
addition to (obviously) requiring NGINX headers, their build system is
the one of NGINX. Actually, they are intended to be built and installed
alongside the NGINX server, but, luckily, it is possible to succesfuly
build a module, given (1) the headers, (2) the build system and the
exact same (3) ./configure flags that have been used to configure NGINX
itself are present. The points (1) and (2) are taken for granted here,
as nginx.eclass takes care of them:

    * headers are installed into /usr/include/nginx

    * build system is installed into /usr/src/nginx

As for the (3) point, the configuration flags are recorder into
ngx_auto_config.h file as preprocessor #define's. The file is also saved
into /usr/include/nginx.

The build process undergoes in the ${WORKDIR}/nginx directory, which
has 3 symlinks:
    * src/        -> /usr/include/nginx
    * configure   -> /usr/src/nginx/configure
    * auto/       -> /usr/src/nginx/auto
The build is the exact same as building a module "in-tree": the
./configure script is called with the '--add-dynamic-module' flag. The
rest of the eclass is really simple; src_compile() executes 'make
modules' and src_install() installs the compiled shared objects into
/usr/$(get_libdir)/nginx/modules.

Closes: https://bugs.gentoo.org/573710
Signed-off-by: Zurab Kvachadze <zurabid2016@gmail.com>
---
 eclass/nginx-module.eclass | 180 +++++++++++++++++++++++++++++++++++++
 1 file changed, 180 insertions(+)
 create mode 100644 eclass/nginx-module.eclass

diff --git a/eclass/nginx-module.eclass b/eclass/nginx-module.eclass
new file mode 100644
index 000000000000..4f2a1e6c6ed6
--- /dev/null
+++ b/eclass/nginx-module.eclass
@@ -0,0 +1,180 @@
+# Copyright 1999-2024 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+# @ECLASS: nginx-module.eclass
+# @MAINTAINER:
+# Zurab Kvachadze <zurabid2016@gmail.com>
+# @AUTHOR:
+# Zurab Kvachadze <zurabid2016@gmail.com>
+# @SUPPORTED_EAPIS: 8
+# @PROVIDES: toolchain-funcs flag-o-matic
+# @BLURB: Provides a common set of functions for building NGINX's dynamic modules
+# @DESCRIPTION:
+# The nginx-module.eclass automates configuring, building and installing NGINX's
+# dynamic modules. Using this eclass is as simple as calling 'inherit nginx-module'.
+#
+# This eclass automatically adds dependency on NGINX. If the part of the
+# module's functionality depends on the NGINX configuration (e.g.
+# HMAC generation support depending on http_ssl module being enabled), the
+# corresponding code should be rewritten so that the functionality in question
+# (1) is unconditionally enabled/disabled or (2) could be toggled by a USE flag.
+#
+# If the module makes use of the ngx_devel_kit (NDK), it must make sure to
+# add that to the relevant *DEPEND variables and to call "append-cflags -DNDK",
+# since (obviously) the NDK is not built alongside the module.
+
+case ${EAPI} in
+	8) ;;
+	*) die "${ECLASS}: EAPI ${EAPI:-0} not supported" ;;
+esac
+
+if [[ -z ${_NGINX_MODULE_ECLASS} ]]; then
+_NGINX_MODULE_ECLASS=1
+
+inherit toolchain-funcs flag-o-matic
+
+# @FUNCTION: econf_ngx
+# @USAGE: [<args>...]
+# @DESCRIPTION:
+# Call ./configure, passing the supplied arguments.
+# The NGINX's build system consists of many helper scripts, which are executed
+# relative to the working directory. Therefore, the function only supports
+# executing the configure script from the current working directory. This
+# function also checks whether the script is executable. If any of the above
+# conditions are not satisfied, the function aborts the build process with
+# 'die'. It also fails if the script itself exits with a non-zero exit code,
+# unless the function is called with 'nonfatal'.
+# If running ./configure is required, this is the way it should be done.
+econf_ngx() {
+	debug-print-function "${FUNCNAME[0]}" "$@"
+	[[ ! -x ./configure ]] &&
+		die "./configure is not present in the current working directory or is not executable"
+	echo "./configure ${*@Q}" >&2
+	./configure "$@"
+	# For some reason, NGINX's ./configure returns 1 if it is used with the
+	# '--help' argument.
+	if [[ $? -ne 0 && "$1" != --help ]]; then
+		die -n "./configure ${*@Q} failed"
+	fi
+}
+
+# As per upstream documentation, modules must be rebuilt with each NGINX
+# upgrade.
+DEPEND="
+	www-servers/nginx:=[modules(-)]
+"
+BDEPEND="${DEPEND}"
+RDEPEND="${DEPEND}"
+
+# @ECLASS_VARIABLE: NGINX_MOD_S
+# @DESCRIPTION:
+# Holds the path to the module's build directory, used in the
+# nginx-module_src_configure() phase function. Defaults to ${S}. Can be changed
+# by the ebuild.
+: "${NGINX_MOD_S=${S}}"
+
+# The ${S} variable is set to the path of the directory where the actual build
+# will be performed. In this directory, symbolic links to NGINX's build system
+# and NGINX's headers are created by the nginx-module_src_unpack() phase
+# function.
+S="${WORKDIR}/nginx"
+
+
+# @FUNCTION: nginx-module_src_unpack
+# @DESCRIPTION:
+# Unpacks the sources and sets up the build directory in S=${WORKDIR}/nginx.
+# Creates the following symbolic links (to not copy the files over):
+#  - '${S}/src' -> '/usr/include/nginx',
+#  - '${S}/auto' -> '/usr/src/nginx/auto',
+#  - '${S}/configure' -> '/usr/src/nginx/configure'.
+# For additional information, see nginx.eclass source, namely
+# nginx_src_install() function.
+nginx-module_src_unpack() {
+	default
+	mkdir nginx || die "mkdir failed"
+	ln -s "${BROOT}/usr/src/nginx/configure" nginx/configure || die "ln failed"
+	ln -s "${BROOT}/usr/src/nginx/auto" nginx/auto || die "ln failed"
+	ln -s "${ESYSROOT}/usr/include/nginx" nginx/src || die "ln failed"
+}
+
+# @FUNCTION: nginx-module_src_prepare
+# @DESCRIPTION:
+# Patches module's initialisation code so that any module's preprocessor
+# definitions appear in the separate '__ngx_gentoo_mod_config.h' file inside the
+# 'build' directory. This function also makes module's "config" script clear
+# whatever content build/ngx_auto_config.h may have at the time of invocation.
+# Then, default_src_prepare() is called.
+nginx-module_src_prepare() {
+	sed -i -e '1i\' -e ': > build/ngx_auto_config.h' "${NGINX_MOD_S}/config"
+	echo 'mv build/ngx_auto_config.h build/__ngx_gentoo_mod_config.h' \
+		>> "${NGINX_MOD_S}/config"
+	default_src_prepare
+}
+
+# @FUNCTION: nginx-module_src_configure
+# @DESCRIPTION:
+# Configures the dynamic module(s) by calling NGINX's ./configure script.
+# Custom flags can be supplied via the 'myconf' array, taking precedence over
+# eclass's flags.
+# This assembles ngx_auto_config.h from the system ngx_auto_config.h and
+# __ngx_gentoo_mod_config.h (see nginx-module_src_prepare()), and
+# ngx_auto_headers.h from the system ngx_auto_headers.h.
+nginx-module_src_configure() {
+	local ngx_mod_flags
+	ngx_mod_flags=(
+		--with-cc="$(tc-getCC)"
+		--with-cpp="$(tc-getCPP)"
+		# The '-isystem' flag is used instead of '-I', so as for the installed
+		# (system) modules' headers to be of lower priority than the headers of
+		# the currently built module. This only affects the modules that both
+		# come with and install their own headers, e.g. ngx_devel_kit.
+		--with-cc-opt="-isystem src/modules"
+		--with-ld-opt="${LDFLAGS}"
+		--builddir=build
+		--add-dynamic-module="${NGINX_MOD_S}"
+	)
+
+	# NGINX build system adds directories under src/ to the include path based
+	# on selected modules. Since nginx.eclass does not save/restore the
+	# configuration flags, we have to add the directories to the include path
+	# manually.
+	# The src/os is added automatically by the auto/unix script and the
+	# src/modules directory is included by the '--with-cc-opt' configuration
+	# flag.
+	append-cflags "$(find -H src -mindepth 1 -type d \! \( \( -path 'src/os' -o \
+						-path 'src/modules' \) -prune \) -printf '-I %p ')"
+
+	eval "local -a EXTRA_ECONF=( ${EXTRA_ECONF} )"
+
+	# Setting the required environmental variables to skip the unneeded
+	# execution of certain scripts (see nginx_src_install() in nginx.eclass).
+	_NGINX_GENTOO_SKIP_PHASES=1 econf_ngx \
+		"${ngx_mod_flags[@]}"	\
+		"${myconf[@]}"			\
+		"${EXTRA_ECONF[@]}"
+
+	cat "${ESYSROOT}/usr/include/nginx/ngx_auto_config.h" \
+		build/__ngx_gentoo_mod_config.h > build/ngx_auto_config.h ||
+		die "cat failed"
+	cp "${ESYSROOT}/usr/include/nginx/ngx_auto_headers.h" build ||
+		die "cp failed"
+}
+
+# @FUNCTION: nginx-module_src_compile
+# @DESCRIPTION:
+# Compiles the module(s) by calling "make modules".
+nginx-module_src_compile() {
+	emake modules
+}
+
+# @FUNCTION: nginx-module_src_install
+# @DESCRIPTION:
+# Installs the compiled module(s) into /usr/${libdir}/nginx/modules.
+nginx-module_src_install() {
+	insinto "/usr/$(get_libdir)/nginx/modules"
+	doins build/*.so
+}
+
+fi
+
+EXPORT_FUNCTIONS src_unpack src_prepare src_configure src_compile src_install
-- 
2.44.2



  parent reply	other threads:[~2024-07-17 12:06 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-07-17 12:05 [gentoo-dev] [RFC PATCH 00/19] Rework NGINX packaging in Gentoo by introducing nginx{,-module}.eclass Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 01/19] nginx.eclass: Add new eclass for building the NGINX server Zurab Kvachadze
2024-07-17 12:05 ` Zurab Kvachadze [this message]
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 03/19] www-servers/nginx: add myself as a proxy maintainer; update metadata.xml Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 04/19] www-servers/nginx: add nginx-r5.initd Zurab Kvachadze
2024-07-17 12:41   ` Michael Orlitzky
2024-07-19  9:20     ` Zurab Kvachadze
2024-07-19 10:31       ` Michael Orlitzky
2024-07-19 16:33         ` Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 05/19] www-servers/nginx: add nginx-r1.confd Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 06/19] www-servers/nginx: add nginx-r2.service Zurab Kvachadze
2024-07-20 16:58   ` Alexander Tsoy
2024-07-20 17:15     ` Michael Orlitzky
2024-07-20 17:25       ` Alexander Tsoy
2024-07-20 19:17         ` Alexander Tsoy
2024-07-20 21:07         ` Michael Orlitzky
2024-07-21 21:19           ` Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 07/19] www-servers/nginx: add nginx-r2.logrotate Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 08/19] www-servers/nginx: add nginx-r4.conf Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 09/19] profiles/desc: reword and update nginx_modules_http.desc Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 10/19] profiles/desc: reword and update nginx_modules_mail.desc Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 11/19] profiles/desc: reword and update nginx_modules_stream.desc Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 12/19] profiles/categories: Add www-nginx category for external NGINX modules Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 13/19] www-servers/nginx: revbump 1.26.1-r1 to 1.26.1-r2, use nginx.eclass Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 14/19] www-servers/nginx: revbump 1.27.0-r1 to 1.27.0-r2, " Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 15/19] www-servers/nginx: add 9999 live version, " Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 16/19] www-nginx/ngx_devel_kit: new package, add 0.3.3 Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 17/19] www-nginx/ngx-echo: new package, add 0.63 Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 18/19] www-nginx/ngx-encrypted-session: new package, add 0.09 Zurab Kvachadze
2024-07-17 12:05 ` [gentoo-dev] [RFC PATCH 19/19] www-nginx/ngx-set-misc: new package, add 0.33 Zurab Kvachadze

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240717120553.31866-3-zurabid2016@gmail.com \
    --to=zurabid2016@gmail.com \
    --cc=gentoo-dev@lists.gentoo.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox