diff --git a/CHANGELOG.md b/CHANGELOG.md index ca3a058..9982f6b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,14 @@ CHANGELOG ========= +1.15.0 +------------------- + +* `phpinfo()` and `php --ri maxminddb` now show whether the extension was built + with the bundled libmaxminddb or links a system library. The + `libmaxminddb library version` row reads, for example, `1.14.0 (bundled)` or + `1.9.1 (system)`. Pull request by Remi Collet. GitHub #289. + 1.14.0 (2026-09-10) ------------------- diff --git a/ext/config.m4 b/ext/config.m4 index 18f9a49..8262e62 100644 --- a/ext/config.m4 +++ b/ext/config.m4 @@ -78,8 +78,15 @@ if test $PHP_MAXMINDDB != "no"; then maxminddb_sources="$maxminddb_sources libmaxminddb/src/maxminddb.c libmaxminddb/src/data-pool.c" - AC_DEFINE([HAVE_LIBMAXMINDDB_BUNDLED], [1], [Use bundled or system libmaxminddb]) + dnl phpinfo() reports this. It is 1 here and 0 in the system branch, + dnl never absent, so maxminddb.c can tell a system build from a + dnl definition that never arrived and refuse to compile. config.w32 + dnl says why that is a real risk on Windows. + AC_DEFINE([HAVE_LIBMAXMINDDB_BUNDLED], [1], [1 if the bundled libmaxminddb is compiled into the extension, 0 if a system libmaxminddb is linked]) else + dnl See the bundled branch above for why this is 0 rather than absent. + AC_DEFINE([HAVE_LIBMAXMINDDB_BUNDLED], [0], [1 if the bundled libmaxminddb is compiled into the extension, 0 if a system libmaxminddb is linked]) + AC_PATH_PROG(PKG_CONFIG, pkg-config, no) AC_MSG_CHECKING(for libmaxminddb) diff --git a/ext/config.w32 b/ext/config.w32 index b405b11..312a5cb 100644 --- a/ext/config.w32 +++ b/ext/config.w32 @@ -12,12 +12,12 @@ if (PHP_MAXMINDDB == "yes") { ERROR("--with-maxminddb-bundled needs the bundled libmaxminddb sources; run \"git submodule update --init\""); } - /* Read the version out of the submodule rather than repeating it here. - * Nothing else checks this file -- there is no Windows workflow in this - * repository -- so a bump that updated config.m4 and forgot this line - * would ship a PACKAGE_VERSION that lies, with nothing to notice it. - * config.m4 keeps a literal because test-bundled.yml compares - * MMDB_LIB_VERSION against configure.ac on every build. */ + /* Read the version out of the submodule so a bump cannot leave this + * line behind. The Unix build keeps a literal in + * ext/bundled-include/maxminddb_config.h instead; that header says + * why. The bundled and windows-bundled jobs in test-bundled.yml check + * both by comparing MMDB_LIB_VERSION against configure.ac on every + * build. */ var maxminddb_ac = file_get_contents(maxminddb_bundled + "\\configure.ac"); /* The match is captured rather than read back out of RegExp.$1, which is * engine-global state shared with every other config.w32 evaluated in @@ -57,6 +57,7 @@ if (PHP_MAXMINDDB == "yes") { * The Windows build never defines HAVE_CONFIG_H, so libmaxminddb * already does the right thing, and defining it here would instead * make our own maxminddb.c include a config.h that does not exist. + * The AC_DEFINE below reaches maxminddb.c by another route; see there. * * MSVC has no unsigned __int128, so the byte array is the only option * for uint128 values. Both this file and config.m4 have to define @@ -82,7 +83,20 @@ if (PHP_MAXMINDDB == "yes") { * ask for it explicitly too, and the dependency is ours now. */ ADD_FLAG("LIBS_MAXMINDDB", "ws2_32.lib"); - AC_DEFINE("HAVE_LIBMAXMINDDB_BUNDLED", 1, "Use bundled or system libmaxminddb"); + /* phpinfo() reports this. It reaches maxminddb.c through php.h, not + * through any config header of ours: as of PHP 8.4, under phpize, + * configure.js writes AC_DEFINE results to + * \include\main\config.pickle.h, which main\config.w32.h + * includes (in a php-src tree they land in that file directly). + * + * It is 1 here and 0 in the system branch below, never absent, + * because config.pickle.h is shared state in the PHP install and + * generate_config_pickle_h() removes only the lines whose keys the + * current run defines. A bundled configure followed by a system one + * would leave this 1 in place and the system build would report + * "bundled". The 0 overwrites it, and maxminddb.c refuses to compile + * if neither arrives. */ + AC_DEFINE("HAVE_LIBMAXMINDDB_BUNDLED", 1, "1 if the bundled libmaxminddb is compiled into the extension, 0 if a system libmaxminddb is linked"); EXTENSION("maxminddb", "maxminddb.c"); @@ -112,6 +126,9 @@ if (PHP_MAXMINDDB == "yes") { "maxminddb", "libmaxminddb"); } else if (CHECK_HEADER_ADD_INCLUDE("maxminddb.h", "CFLAGS_MAXMINDDB", PHP_MAXMINDDB + ";" + PHP_PHP_BUILD + "\\include\\maxminddb") && CHECK_LIB("libmaxminddb.lib;maxminddb.lib", "maxminddb", PHP_MAXMINDDB)) { + /* See the bundled branch above for why this is 0 rather than absent. */ + AC_DEFINE("HAVE_LIBMAXMINDDB_BUNDLED", 0, "1 if the bundled libmaxminddb is compiled into the extension, 0 if a system libmaxminddb is linked"); + EXTENSION("maxminddb", "maxminddb.c"); } else { WARNING('Could not find maxminddb.h, libmaxminddb.lib, or maxminddb.lib; skipping'); diff --git a/ext/maxminddb.c b/ext/maxminddb.c index 32692a2..5c5d35b 100644 --- a/ext/maxminddb.c +++ b/ext/maxminddb.c @@ -26,6 +26,15 @@ #include "ext/standard/info.h" #include +/* Both build files define this as 1 or 0 on every path, so a missing + * definition is a build-file mistake, not a system build. Fail rather than + * report "system" for a bundled object. Unlike php-src's HAVE_GD_BUNDLED, + * which is absent in a system build, this must be tested with #if: #ifdef + * is true for the 0 too. */ +#ifndef HAVE_LIBMAXMINDDB_BUNDLED +#error "HAVE_LIBMAXMINDDB_BUNDLED must be defined by the build files" +#endif + #ifdef ZTS #include #endif @@ -792,18 +801,23 @@ PHP_MINIT_FUNCTION(maxminddb) { } static PHP_MINFO_FUNCTION(maxminddb) { +#if HAVE_LIBMAXMINDDB_BUNDLED + const char *lib_source = "bundled"; +#else + const char *lib_source = "system"; +#endif + char *lib_version; + php_info_print_table_start(); php_info_print_table_row(2, "MaxMind DB Reader", "enabled"); php_info_print_table_row( 2, "maxminddb extension version", PHP_MAXMINDDB_VERSION); - php_info_print_table_row( - 3, "libmaxminddb library version", MMDB_lib_version(), -#ifdef HAVE_LIBMAXMINDDB_BUNDLED - "(bundled)"); -#else - "(system)"); -#endif + + spprintf(&lib_version, 0, "%s (%s)", MMDB_lib_version(), lib_source); + CHECK_ALLOCATED(lib_version); + php_info_print_table_row(2, "libmaxminddb library version", lib_version); + efree(lib_version); php_info_print_table_end(); }