core-lightning/tools/headerversions.c
Christian Decker 39022028e9 db: Ensure sqlite3 library minimum version and major version match
We were really strict with the version check, requiring an exact
match. We now check that we are running at least with the version we
were compiled with (distro upgrades continue to work, and repro builds
are built off of an unupdated installation matching this minimum
requirement), and a major version match (since major versions can and
will introduce breaking changes).

Changelog-Fixed: sqlite3: Relaxed the version match requirements to be at least a minimum version and a major version match
2021-10-12 09:15:48 +10:30

88 lines
2.8 KiB
C

/* Updates the given file if any library versions have changed. This
* is important for systemwide updates, such as sqlite3. */
#include "config.h"
#include <ccan/err/err.h>
#include <ccan/read_write_all/read_write_all.h>
#include <ccan/tal/grab_file/grab_file.h>
#include <ccan/tal/str/str.h>
#include <errno.h>
#include <fcntl.h>
#include <gmp.h>
#if HAVE_SQLITE3
# include <sqlite3.h>
# define IF_SQLITE3(...) __VA_ARGS__
#else
# define IF_SQLITE3(...)
#endif
#include <unistd.h>
#include <zlib.h>
static const char template[] =
"/* Generated file by tools/headerversions, do not edit! */\n"
"/* GMP version: %s */\n"
IF_SQLITE3("/* SQLITE3 version: %u */\n")
"/* ZLIB version: %s */\n"
"#include <ccan/err/err.h>\n"
"#include <gmp.h>\n"
IF_SQLITE3("#include <sqlite3.h>\n")
"#include <zlib.h>\n"
"\n"
"static inline void check_linked_library_versions(void)\n"
"{\n"
" char compiled_gmp_version[100];\n"
IF_SQLITE3(
" /* Require at least the version we compiled with. */"
" if (SQLITE_VERSION_NUMBER > sqlite3_libversion_number())\n"
" errx(1, \"SQLITE version mismatch: compiled %%u, now %%u\",\n"
" SQLITE_VERSION_NUMBER, sqlite3_libversion_number());\n"
" /* Ensure the major version matches. */"
" if (SQLITE_VERSION_NUMBER + 1000000 < sqlite3_libversion_number())\n"
" errx(1, \"SQLITE major version mismatch: compiled %%u, now %%u\",\n"
" SQLITE_VERSION_NUMBER, sqlite3_libversion_number());\n"
)
" /* zlib documents that first char alters ABI. Kudos! */\n"
" if (zlibVersion()[0] != ZLIB_VERSION[0])\n"
" errx(1, \"zlib version mismatch: compiled %%s, now %%s\",\n"
" ZLIB_VERSION, zlibVersion());\n"
" /* GMP doesn't say anything, and we have to assemble our own string. */\n"
" snprintf(compiled_gmp_version, sizeof(compiled_gmp_version),\n"
" \"%%u.%%u.%%u\",\n"
" __GNU_MP_VERSION,\n"
" __GNU_MP_VERSION_MINOR,\n"
" __GNU_MP_VERSION_PATCHLEVEL);\n"
" if (strcmp(compiled_gmp_version, gmp_version) != 0)\n"
" errx(1, \"gmp version mismatch: compiled %%s, now %%s\",\n"
" compiled_gmp_version, gmp_version);\n"
"}\n";
int main(int argc, char *argv[])
{
char *file, *new;
/* We don't bother with setup_locale(); we're a build tool */
err_set_progname(argv[0]);
if (argc != 2)
errx(1, "Usage: %s <versionheader>", argv[0]);
file = grab_file(NULL, argv[1]);
if (!file && errno != ENOENT)
err(1, "Reading %s", argv[1]);
new = tal_fmt(NULL, template,
gmp_version,
IF_SQLITE3(sqlite3_libversion_number(),)
zlibVersion());
if (!file || !streq(new, file)) {
int fd = open(argv[1], O_TRUNC|O_WRONLY|O_CREAT, 0666);
if (fd < 0)
err(1, "Writing %s", argv[1]);
if (!write_all(fd, new, strlen(new)))
err(1, "Writing to %s", argv[1]);
close(fd);
}
tal_free(new);
tal_free(file);
return 0;
}