build: close package variant identity gaps

This commit is contained in:
2026-08-12 22:09:55 +09:00
parent 1724ea086f
commit 2dd6b8a250
5 changed files with 57 additions and 7 deletions

View File

@@ -1182,6 +1182,13 @@ sep_add_generated_main(struct sepgraph *g, struct sepproduct *product,
fprintf(stderr, "ww: generated test-main identity is too long\n");
return -1;
}
for (int i = 0; i < g->n; i++) {
if (strcmp(g->pkg[i].path, p->path) != 0) continue;
fprintf(stderr,
"ww: generated test-main package identity collides with source import %s\n",
p->path);
return -1;
}
snprintf(p->entry, sizeof p->entry, "%s", variantentry);
snprintf(p->name, sizeof p->name, "main");
p->variant = SEP_VARIANT_TEST_MAIN;
@@ -1361,6 +1368,21 @@ sep_topo_visit(struct sepgraph *g, int pi, int *order, int *no,
* with an unrelated normal action in the command-global universe, but never
* in one product. A single link closure must remain an unambiguous package
* namespace. */
static int
sep_internal_replaces_production(const struct sepgraph *g, int a, int b)
{
const struct seppkg *internal = &g->pkg[a];
const struct seppkg *production = &g->pkg[b];
if (internal->variant != SEP_VARIANT_SAME_TEST) {
internal = &g->pkg[b];
production = &g->pkg[a];
}
return internal->variant == SEP_VARIANT_SAME_TEST
&& production->variant == SEP_VARIANT_PRODUCTION
&& production->role != SEP_ROLE_TEST_SUPPORT
&& strcmp(internal->canon, production->canon) == 0;
}
static int
sep_validate_module_closure(struct sepgraph *g, const int *order, int n,
int include_root)
@@ -1372,7 +1394,8 @@ sep_validate_module_closure(struct sepgraph *g, const int *order, int n,
for (int j = i + 1; j < n; j++) {
int b = order[j];
if (!include_root && g->pkg[b].root) continue;
if (strcmp(g->pkg[a].path, g->pkg[b].path) == 0) {
if (strcmp(g->pkg[a].path, g->pkg[b].path) == 0
&& !sep_internal_replaces_production(g, a, b)) {
fprintf(stderr,
"ww: product closure contains multiple packages named %s\n",
g->pkg[a].path);