-
Problem report
-
Resolution: Unresolved
-
Major
-
None
-
None
-
None
-
Support backlog
Zabbix has, as part of its source tree, a collection of m4 macro packages for finding library dependencies.
There are a number of issues with their implementations.
Some of the macro packages rely on pkg.m4 (an m4 macro package distributed with pkg-config) for finding library dependencies and determining compiler and linker flags for building with the library. This package provides macros for finding the pkg-config utility, searching for modules (module is pkg-config terminology for a variant of a library), retrieving module specific compiler and linker flags, as well as convenience macros for doing the previous, and in addition, adding appropriate "--with-" options to the final configure script, and defining automake conditionals and autconf variables (i.e. HAVE_... and $with_...).
Some of these macro packages, namely libopenssl.m4 and libmodbus.m4, rely on macros from pkg.m4 for function, and error if the pkg-config utility has not been found (which is searched for and recorded in $PKG_CONFIG by the PKG_PROG_PKG_CONFIG macro)[1][2].
This, in effect, means that we require pkg-config to be present on the system when building from source.
In the top-level autoconf template, we check whether the macro PKG_PROG_PKG_CONFIG is defined, and if not, we define it with an empty body.
This macro is defined by the pkg.m4 macro package, and performs the search for the pkg-config utility, and sets the $PKG_CONFIG variable to point to that utility. This macro is called by other PKG_* macros if $PKG_CONFIG is unset or empty.
This is apparently done to work around systems that don't have pkg-config and pkg.m4 installed. This is pointless, as we just trick macros asking for that definition to then call it, which accomplishes nothing, and terminate because $PKG_CONFIG is empty anyway.
Traditionally, AC_ARG_WITH is used to define --with- and --without- flag variants for a given module, and takes a single, optional, argument - 'yes', 'no', 'auto'/'check' (use-if-available case).
In Zabbix' case, the argument, if not any of the previous, is interpreted as the root of the installation for the particular package (i.e. if given --with-pkg=/some/root, /some/root/include will be passed via an -I flag as the include directory, and /some/root/include/lib via the -L as the library search path)[3]. These can be further controlled with the flags --with-pkg-(lib|include) for a given module.
This is incorrect, and should be accomplished by specifying any secondary pkg-config database directories via the PKG_CONFIG_PATH environment variable, as described in pkg-config.1, which are honored by the pkg.m4 macros when used with autoconf.
This also leads to issues such as ZBX-22607, where the user became confused as to why the paths they passed to --with-pkg-* flags had no effect.
There are even subtler bugs stemming from this. For example, in the case of the PCRE libraries, even though we perform a test with the correct compiler and link flags, we then update the environment such that these paths are appended to the list of directories to be searched, when building.
As an example, this becomes an issue when the user is building with PostgreSQL as the database backend, as in its configuration, CFLAGS and LDFLAGS start with paths to the (system) compiler default directories. In this scenario, the user will build against the system installation of the library, not the staging installation as they intended to.
The proposal is to stop pretending pkg-config doesn't exist and just use it, as well as drop the use of --with-pkg-(include|lib) flags and just make use of pkg-config's accepted environment. The macro packages would lose about 90% of their contents. Many of these macro packages can be replaced by ones provided by the dependencies themselves, or the autoconf-archive package[4], and redistributed with the tarball. Candidates for this are packages such as iconv.m4, libssh.m4, libssh2.m4, pcre.m4, pcre2.m4, libxml.m4, and the MySQL, PostgreSQL, and SQLite3 macro packages that are already (outdated and modified) copies of macro packages from the autoconf-archive.
[1]: libopenssl.m4
[2]: libmodbus.m4
[3]: This is very unlikely to work on multilib systems, where 64-bit and 32-bit libraries often reside in different directories, such as lib64 and lib32. RHEL is a big one.
[4]: autoconf-archive
- mentioned in
-
Page Loading...