Test the installed package, not just the build tree
Found by building a consumer against a fresh install: an installed libakstdlib was not usable. akstdlibConfig.cmake calls find_dependency(akerror), and the top-level build pulls the submodule in EXCLUDE_FROM_ALL, so `cmake --install` on this project installs only this project and leaves that dependency unresolvable. CI had been hiding it by installing libakerror@main in a separate step -- a different libakerror from the one actually compiled, which is the inconsistency TODO.md 2.3 recorded and the previous commit removed. Removing it exposed the real gap. CI now installs deps/libakerror, the same commit the top-level build compiles, so there is one libakerror in play and the install is consumable. tests/consumer/ is the check that would have caught it: a standalone project, configured against CMAKE_PREFIX_PATH rather than as part of this build, because being part of this build is exactly what would let it pass without testing anything. It exercises what only an install has -- find_package with a version request against the generated version file, find_dependency(akerror) resolving, and the exported akstdlib::akstdlib target -- and touches one function from each of the four sources, so a library installed with a source file missing from its link line fails there rather than in the next consumer to find it. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
73
tests/consumer/main.c
Normal file
73
tests/consumer/main.c
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* Smoke test for the installed package. See CMakeLists.txt beside this file.
|
||||
*
|
||||
* Deliberately touches one function from each translation unit -- the version
|
||||
* entry points, a string buffer, a formatted append and a print -- so that a
|
||||
* library installed with a source file missing from its link line fails here
|
||||
* rather than in whatever consumer discovers it next.
|
||||
*
|
||||
* Returns a distinct status per step, so a CI failure names the step.
|
||||
*/
|
||||
|
||||
#include <akstdlib.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
akerr_ErrorContext *e = NULL;
|
||||
aksl_StrBuf buf;
|
||||
const char *text = NULL;
|
||||
size_t len = 0;
|
||||
uint32_t hash = 0;
|
||||
int count = 0;
|
||||
|
||||
/* The header and the .so have to agree, which is the whole point of the
|
||||
* version machinery: the soname catches this first in normal use, and this
|
||||
* catches a hand-install that bypassed it. */
|
||||
e = AKSL_VERSION_CHECK();
|
||||
if ( e != NULL ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* src/collections.c */
|
||||
e = aksl_strbuf_init(&buf, 0);
|
||||
if ( e != NULL ) {
|
||||
return 2;
|
||||
}
|
||||
e = aksl_strbuf_appendf(&buf, "libakstdlib %s, soname %s",
|
||||
aksl_version_string(), aksl_version_soname());
|
||||
if ( e != NULL ) {
|
||||
return 3;
|
||||
}
|
||||
e = aksl_strbuf_cstr(&buf, &text);
|
||||
if ( e != NULL ) {
|
||||
return 4;
|
||||
}
|
||||
|
||||
/* src/string.c */
|
||||
e = aksl_strlen(text, &len);
|
||||
if ( e != NULL ) {
|
||||
return 5;
|
||||
}
|
||||
|
||||
/* src/stdlib.c */
|
||||
e = aksl_strhash_djb2(text, len, &hash);
|
||||
if ( e != NULL ) {
|
||||
return 6;
|
||||
}
|
||||
e = aksl_printf(&count, "%s (%zu bytes, djb2 %u)\n", text, len, hash);
|
||||
if ( e != NULL ) {
|
||||
return 7;
|
||||
}
|
||||
|
||||
/* src/stream.c */
|
||||
e = aksl_fflush(NULL);
|
||||
if ( e != NULL ) {
|
||||
return 8;
|
||||
}
|
||||
|
||||
e = aksl_strbuf_free(&buf);
|
||||
if ( e != NULL ) {
|
||||
return 9;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user