ww build: honor output directories
This commit is contained in:
233
cmd/ww/main.c
233
cmd/ww/main.c
@@ -25,7 +25,7 @@
|
||||
static const char *usage =
|
||||
"usage: ww [-V] <subcommand> [args...]\n"
|
||||
" -V print version and exit\n"
|
||||
" build [-S] [-w DIR] [-I DIR] [-o FILE] [path ...] build local package graphs\n"
|
||||
" build [-S] [-w DIR] [-I DIR] [-o FILE|DIR] [path ...] build local package graphs\n"
|
||||
" run [path] ... build then exec, passing extra args to the program\n"
|
||||
" test [-S -o STEM] [-w DIR] [options] [path ...] build/run tests; -S emits package asm\n"
|
||||
" version print version and exit\n"
|
||||
@@ -34,7 +34,8 @@ static const char *usage =
|
||||
" foo.ww literal file\n"
|
||||
" foo search cwd, -I dirs, then the source library for foo.ww or foo/\n"
|
||||
" lib/foo directory: build its package sources\n"
|
||||
" -o publishes a non-main archive FILE + FILE.wwi\n"
|
||||
" -o FILE publishes a non-main archive FILE + FILE.wwi\n"
|
||||
" -o DIR publishes each selected command beneath DIR\n"
|
||||
" lib/... every eligible package under lib, recursively\n"
|
||||
" . build the cwd's <basename>.ww\n";
|
||||
|
||||
@@ -1256,6 +1257,7 @@ struct seppkg {
|
||||
int ngenerated_targets;
|
||||
int generated_targetcap;
|
||||
int failed; /* discovery/compile failure reaches this action */
|
||||
int action; /* reached by this request's semantic action list */
|
||||
int test_support; /* compiler-generated -T support package */
|
||||
int loaded; /* directory membership/name loaded exactly once */
|
||||
int export_changed; /* staged export differs from committed export */
|
||||
@@ -1306,6 +1308,7 @@ struct sepproduct {
|
||||
int variant;
|
||||
int directory_product;
|
||||
int no_tests;
|
||||
int build_action; /* loaded product retained in the action list */
|
||||
int context;
|
||||
int root;
|
||||
int variant_root; /* retained single-unit root outside directory products */
|
||||
@@ -2847,7 +2850,8 @@ static int
|
||||
sep_validate_artifact_paths(struct sepgraph *g, const char *scratch)
|
||||
{
|
||||
for (int i = 0; i < g->n; i++) {
|
||||
if (g->pkg[i].failed || !g->pkg[i].loaded) continue;
|
||||
if (g->pkg[i].failed || !g->pkg[i].loaded || !g->pkg[i].action)
|
||||
continue;
|
||||
if (g->pkg[i].storage == NULL
|
||||
&& sep_assign_storage(&g->pkg[i], scratch) < 0) return -1;
|
||||
}
|
||||
@@ -2855,9 +2859,11 @@ sep_validate_artifact_paths(struct sepgraph *g, const char *scratch)
|
||||
do {
|
||||
changed = 0;
|
||||
for (int i = 0; i < g->n && !changed; i++) {
|
||||
if (g->pkg[i].failed || !g->pkg[i].loaded) continue;
|
||||
if (g->pkg[i].failed || !g->pkg[i].loaded
|
||||
|| !g->pkg[i].action) continue;
|
||||
for (int j = i + 1; j < g->n; j++) {
|
||||
if (g->pkg[j].failed || !g->pkg[j].loaded
|
||||
|| !g->pkg[j].action
|
||||
|| strcmp(g->pkg[i].storage,
|
||||
g->pkg[j].storage) != 0)
|
||||
continue;
|
||||
@@ -2932,7 +2938,8 @@ sep_validate_workdir_owners(const struct sepgraph *g, const char *scratch)
|
||||
{
|
||||
char unit[SEP_ARTIFACT_MAX];
|
||||
for (int i = 0; i < g->n; i++) {
|
||||
if (g->pkg[i].failed || !g->pkg[i].loaded) continue;
|
||||
if (g->pkg[i].failed || !g->pkg[i].loaded || !g->pkg[i].action)
|
||||
continue;
|
||||
if (sep_fname(g, i, scratch, ".unit.ww", unit, sizeof unit) < 0)
|
||||
return -1;
|
||||
if (sep_validate_unit_owner(unit, &g->pkg[i]) < 0) return -1;
|
||||
@@ -3833,6 +3840,13 @@ sep_clone_for_test(struct sepgraph *g, int original, const char *owner,
|
||||
p->is_dir = src->is_dir;
|
||||
p->variant = SEP_VARIANT_TEST_COPY;
|
||||
p->role = src->role;
|
||||
/* A test copy is a product-scoped action even when its replaced source
|
||||
* node is not in the final action closure. Preserve its established
|
||||
* complete-action locator without relying on a collision with that
|
||||
* inactive source node during artifact validation. */
|
||||
p->storage = sep_storage_digest(p);
|
||||
p->storage_hashed = 1;
|
||||
if (p->storage == NULL) goto fail;
|
||||
p->loaded = src->loaded;
|
||||
p->failed = src->failed;
|
||||
p->test_support = src->test_support;
|
||||
@@ -5222,7 +5236,8 @@ sep_validate_request_staging(struct sepgraph *g, const char *scratch, int warm,
|
||||
".o.new", ".a.new", ".init.unit.new", ".init.s.new",
|
||||
".init.o.new" };
|
||||
for (int pi = 0; pi < g->n; pi++) {
|
||||
if (g->pkg[pi].failed || !g->pkg[pi].loaded) continue;
|
||||
if (g->pkg[pi].failed || !g->pkg[pi].loaded
|
||||
|| !g->pkg[pi].action) continue;
|
||||
for (size_t si = 0; si < nelem(suffix); si++) {
|
||||
char path[SEP_ARTIFACT_MAX];
|
||||
if (sep_fname(g, pi, scratch, suffix[si], path,
|
||||
@@ -5365,14 +5380,16 @@ sep_discard_request_staging(struct sepgraph *g, const char *scratch, int warm,
|
||||
".init.unit.ww", ".init.s", ".init.o" };
|
||||
const char **suffix = warm ? warm_suffix : cold_suffix;
|
||||
int rc = 0;
|
||||
for (int pi = 0; pi < g->n; pi++)
|
||||
for (int pi = 0; pi < g->n; pi++) {
|
||||
if (!g->pkg[pi].action) continue;
|
||||
for (size_t i = 0; i < nelem(warm_suffix); i++) {
|
||||
char path[SEP_ARTIFACT_MAX];
|
||||
if (sep_fname(g, pi, scratch, suffix[i], path,
|
||||
sizeof path) < 0
|
||||
|| (unlink(path) != 0 && errno != ENOENT))
|
||||
rc = -1;
|
||||
rc = -1;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < nproducts; i++) {
|
||||
const char *path[] = { products[i].stage_out,
|
||||
products[i].stage_publish, products[i].stage_iface,
|
||||
@@ -5474,6 +5491,8 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
||||
int require_command, int is_test,
|
||||
struct sepproduct *products, int nproducts, int emit_asm,
|
||||
const char *workdir, int create_workdir, const char *create_output_dir,
|
||||
const char *default_output_dir, int output_path_error,
|
||||
const char *output_collision_base, const char *output_collision_dir,
|
||||
char *scratchout, size_t scratchoutsz,
|
||||
struct sepgraph **graphout)
|
||||
{
|
||||
@@ -5927,10 +5946,6 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
||||
int root_package = !is_test && nproducts == 1
|
||||
&& !g->pkg[products[0].root].failed
|
||||
&& !sep_root_is_command(&g->pkg[products[0].root]);
|
||||
if (sep_validate_artifact_paths(g, scratch) < 0)
|
||||
return 1;
|
||||
if (warm && workdir_exists && sep_validate_workdir_owners(g, scratch) < 0)
|
||||
return 1;
|
||||
int *order = calloc((size_t)g->n, sizeof *order);
|
||||
int *stack = calloc((size_t)g->n, sizeof *stack);
|
||||
int norder = 0;
|
||||
@@ -5980,6 +5995,24 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!is_test && create_output_dir != NULL) {
|
||||
int actions = 0;
|
||||
for (int i = 0; i < nproducts; i++) {
|
||||
int root = products[i].root;
|
||||
if (g->pkg[root].failed) {
|
||||
free(stack); free(order);
|
||||
return 1;
|
||||
}
|
||||
products[i].build_action =
|
||||
sep_root_is_command(&g->pkg[root]);
|
||||
if (products[i].build_action) actions++;
|
||||
}
|
||||
if (actions == 0) {
|
||||
fputs("ww: no main packages to build\n", stderr);
|
||||
free(stack); free(order);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!g->pkg[products[0].root].failed
|
||||
&& root_package && publish_package && !emit_asm
|
||||
&& validate_package_output_path(out) < 0) {
|
||||
@@ -5989,12 +6022,23 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
||||
for (int pi = 0; pi < g->n; pi++) g->pkg[pi].color = 0;
|
||||
for (int i = 0; i < nproducts; i++) {
|
||||
int root = products[i].root;
|
||||
if (!g->pkg[root].failed
|
||||
if (products[i].build_action && !g->pkg[root].failed
|
||||
&& sep_topo_visit(g, root, order, &norder, stack, 0) < 0) {
|
||||
free(stack); free(order); return 1;
|
||||
}
|
||||
}
|
||||
free(stack);
|
||||
for (int pi = 0; pi < g->n; pi++) g->pkg[pi].action = 0;
|
||||
for (int oi = 0; oi < norder; oi++) g->pkg[order[oi]].action = 1;
|
||||
if (sep_validate_artifact_paths(g, scratch) < 0) {
|
||||
free(order);
|
||||
return 1;
|
||||
}
|
||||
if (warm && workdir_exists
|
||||
&& sep_validate_workdir_owners(g, scratch) < 0) {
|
||||
free(order);
|
||||
return 1;
|
||||
}
|
||||
/* Propagate already-known package-load failures through the union before
|
||||
* acquiring scratch or completion state. Independent sibling roots may
|
||||
* remain viable for deterministic staging/diagnosis, but any failed product
|
||||
@@ -6007,11 +6051,34 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
||||
}
|
||||
int viable_product = 0;
|
||||
for (int i = 0; i < nproducts; i++)
|
||||
if (!g->pkg[products[i].root].failed) viable_product = 1;
|
||||
if (products[i].build_action
|
||||
&& !g->pkg[products[i].root].failed) viable_product = 1;
|
||||
if (!viable_product) {
|
||||
free(order);
|
||||
return 1;
|
||||
}
|
||||
if (!is_test && !emit_asm && output_path_error) {
|
||||
fputs("ww: command output path is too long\n", stderr);
|
||||
free(order);
|
||||
return 1;
|
||||
}
|
||||
if (!is_test && !emit_asm && output_collision_base != NULL) {
|
||||
fputs("ww: multiple commands produce output basename ", stderr);
|
||||
sep_put_quoted(output_collision_base);
|
||||
fputs(" in directory ", stderr);
|
||||
sep_put_quoted(output_collision_dir);
|
||||
fputc('\n', stderr);
|
||||
free(order);
|
||||
return 1;
|
||||
}
|
||||
if (!is_test && !emit_asm && default_output_dir != NULL && nproducts == 1
|
||||
&& sep_root_is_command(&g->pkg[products[0].root])) {
|
||||
fprintf(stderr,
|
||||
"ww: build output \"%s\" already exists and is a directory\n",
|
||||
default_output_dir);
|
||||
free(order);
|
||||
return 1;
|
||||
}
|
||||
if (sep_validate_request_staging(g, scratch, warm, products, nproducts,
|
||||
root_package, publish_package, emit_asm, is_test) < 0) {
|
||||
sep_free_product_staging(products, nproducts);
|
||||
@@ -6023,8 +6090,8 @@ build_one_sep_impl(const char *src, int entry_is_dir,
|
||||
* output paths, and action closures have passed their pre-tool checks. */
|
||||
struct sep_created_dirs created_output = {0};
|
||||
struct sep_created_dirs created_work = {0};
|
||||
if (create_output_dir != NULL && create_output_dir[0] != '\0'
|
||||
&& sep_mkdirs(create_output_dir, is_test ? 0777 : 0700,
|
||||
if (!emit_asm && create_output_dir != NULL && create_output_dir[0] != '\0'
|
||||
&& sep_mkdirs(create_output_dir, 0777,
|
||||
&created_output) != 0) {
|
||||
fprintf(stderr, is_test
|
||||
? "ww: cannot create test output directory %s\n"
|
||||
@@ -6704,7 +6771,8 @@ build_one_sep(const char *src, int entry_is_dir, const char *root_identity,
|
||||
const struct seplinkflags *linkflags, int publish_package,
|
||||
int require_command, int is_test,
|
||||
int root_variant, const char *test_package, int emit_asm,
|
||||
int keepscratch, const char *workdir)
|
||||
int keepscratch, const char *workdir, const char *create_output_dir,
|
||||
const char *default_output_dir, int output_path_error)
|
||||
{
|
||||
char scratch[PATH_MAX] = {0};
|
||||
struct sepgraph *g = NULL;
|
||||
@@ -6717,6 +6785,7 @@ build_one_sep(const char *src, int entry_is_dir, const char *root_identity,
|
||||
.publish = NULL,
|
||||
.artifact = NULL,
|
||||
.variant = root_variant,
|
||||
.build_action = 1,
|
||||
.root = -1,
|
||||
.variant_root = -1,
|
||||
.support = -1,
|
||||
@@ -6725,7 +6794,8 @@ build_one_sep(const char *src, int entry_is_dir, const char *root_identity,
|
||||
product.artifact = "__root";
|
||||
int r = build_one_sep_impl(src, entry_is_dir, out, objstem,
|
||||
extra_includes, linkflags, publish_package, require_command, is_test,
|
||||
&product, 1, emit_asm, workdir, 0, NULL, scratch,
|
||||
&product, 1, emit_asm, workdir, 0, create_output_dir,
|
||||
default_output_dir, output_path_error, NULL, NULL, scratch,
|
||||
sizeof scratch, &g);
|
||||
sep_graph_free(g);
|
||||
if (!keepscratch && scratch[0]) {
|
||||
@@ -6761,7 +6831,9 @@ build_package_tests(const char *src, const char *root_identity,
|
||||
const char *extra_includes, const char *workdir,
|
||||
struct sepproduct *products, int nproducts, int is_test,
|
||||
int publish_package, const struct seplinkflags *linkflags, int emit_asm,
|
||||
int create_workdir, const char *create_output_dir)
|
||||
int create_workdir, const char *create_output_dir,
|
||||
const char *default_output_dir, int output_path_error,
|
||||
const char *output_collision_base, const char *output_collision_dir)
|
||||
{
|
||||
char scratch[PATH_MAX] = {0};
|
||||
struct sepgraph *g = NULL;
|
||||
@@ -6770,7 +6842,9 @@ build_package_tests(const char *src, const char *root_identity,
|
||||
int r = build_one_sep_impl(src, 1, products[0].out,
|
||||
products[0].out, extra_includes, linkflags, publish_package, 0, is_test,
|
||||
products, nproducts, emit_asm, workdir, create_workdir,
|
||||
create_output_dir, scratch, sizeof scratch, &g);
|
||||
create_output_dir, default_output_dir, output_path_error,
|
||||
output_collision_base, output_collision_dir,
|
||||
scratch, sizeof scratch, &g);
|
||||
sep_graph_free(g);
|
||||
return r;
|
||||
}
|
||||
@@ -6818,6 +6892,39 @@ basename_no_ext(const char *path, char *out, size_t outsz)
|
||||
if (dot && strcmp(dot, ".ww") == 0) *dot = '\0';
|
||||
}
|
||||
|
||||
/* Go's build -o directory branch follows an existing destination through
|
||||
* stat, and a trailing platform separator declares a directory which the
|
||||
* request may need to create. WW's platform separator is '/'. */
|
||||
static int
|
||||
build_output_dir(const char *path)
|
||||
{
|
||||
struct stat st;
|
||||
size_t n = strlen(path);
|
||||
if (n != 0 && path[n - 1] == '/') return 1;
|
||||
return stat(path, &st) == 0 && S_ISDIR(st.st_mode);
|
||||
}
|
||||
|
||||
static int
|
||||
build_output_path(const char *dir, const char *src, char *out, size_t outsz)
|
||||
{
|
||||
char base[PATH_MAX];
|
||||
size_t n = strlen(dir);
|
||||
int written;
|
||||
basename_no_ext(src, base, sizeof base);
|
||||
written = snprintf(out, outsz, "%s%s%s", dir,
|
||||
n != 0 && dir[n - 1] == '/' ? "" : "/", base);
|
||||
if (written < 0 || (size_t)written >= outsz) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
build_import_leaf(const char *identity, char *out, size_t outsz)
|
||||
{
|
||||
const char *leaf = strrchr(identity, '.');
|
||||
leaf = leaf ? leaf + 1 : identity;
|
||||
snprintf(out, outsz, "%s", leaf);
|
||||
}
|
||||
|
||||
static int
|
||||
resolve_module(const char *name, const char *incs, char *out, size_t outsz,
|
||||
int *is_dir)
|
||||
@@ -7043,6 +7150,7 @@ do_build(int argc, char **argv)
|
||||
free(incs);
|
||||
return 2;
|
||||
}
|
||||
int add_dot = src == NULL;
|
||||
if (src == NULL) src = ".";
|
||||
if (strstr(src, "...") != NULL || next < argc || saw_terminator) {
|
||||
free(incs);
|
||||
@@ -7060,11 +7168,32 @@ do_build(int argc, char **argv)
|
||||
char out[PATH_MAX];
|
||||
const char *objstem = NULL;
|
||||
int discard_output = strcmp(outflag, "/dev/null") == 0;
|
||||
int output_dir = outflag[0] && !discard_output
|
||||
&& build_output_dir(outflag);
|
||||
const char *root_identity = !literal && is_dir ? src : NULL;
|
||||
if (output_dir && is_dir) {
|
||||
free(incs);
|
||||
return exec_package_command(argc, argv, src,
|
||||
add_dot ? NULL : resolved, root_identity, add_dot, 1);
|
||||
}
|
||||
const char *create_output_dir = NULL;
|
||||
int output_path_error = 0;
|
||||
if (outflag[0] && !discard_output) {
|
||||
/* -o sets both the binary path and the intermediate stem so
|
||||
* artifacts land beside the requested output (T3). */
|
||||
memcpy(out, outflag, strlen(outflag) + 1);
|
||||
if (output_dir) {
|
||||
if (build_output_path(outflag, resolved, out,
|
||||
sizeof out) < 0) {
|
||||
output_path_error = 1;
|
||||
basename_no_ext(resolved, out, sizeof out);
|
||||
}
|
||||
create_output_dir = outflag;
|
||||
} else {
|
||||
memcpy(out, outflag, strlen(outflag) + 1);
|
||||
}
|
||||
objstem = out;
|
||||
} else if (is_dir && root_identity != NULL) {
|
||||
build_import_leaf(root_identity, out, sizeof out);
|
||||
} else if (is_dir) {
|
||||
char tmp[PATH_MAX];
|
||||
memcpy(tmp, resolved, strlen(resolved) + 1);
|
||||
@@ -7075,7 +7204,8 @@ do_build(int argc, char **argv)
|
||||
} else {
|
||||
basename_no_ext(resolved, out, sizeof out);
|
||||
}
|
||||
const char *root_identity = !literal && is_dir ? src : NULL;
|
||||
const char *default_output_dir = !outflag[0] && build_output_dir(out)
|
||||
? out : NULL;
|
||||
if (discard_output) {
|
||||
char tmpdir[PATH_MAX], tmp[PATH_MAX];
|
||||
int dn = snprintf(tmpdir, sizeof tmpdir, "/tmp/ww_build_%d", getpid());
|
||||
@@ -7095,7 +7225,7 @@ do_build(int argc, char **argv)
|
||||
* library compilation still need request-private product paths. */
|
||||
int rc = build_one_sep(resolved, is_dir, root_identity, tmp, tmp, incs,
|
||||
&linkflags, 0, 0, 0, SEP_VARIANT_PRODUCTION, NULL,
|
||||
emit_asm, 0, workdir);
|
||||
emit_asm, 0, workdir, NULL, NULL, 0);
|
||||
int cleanfail = 0;
|
||||
if (unlink(tmp) != 0 && errno != ENOENT) {
|
||||
fputs("ww: cannot remove temporary output\n", stderr);
|
||||
@@ -7111,7 +7241,8 @@ do_build(int argc, char **argv)
|
||||
}
|
||||
int rc = build_one_sep(resolved, is_dir, root_identity, out, objstem, incs,
|
||||
&linkflags, outflag[0] != '\0', 0, 0, SEP_VARIANT_PRODUCTION, NULL,
|
||||
emit_asm, 1, workdir);
|
||||
emit_asm, 1, workdir, create_output_dir, default_output_dir,
|
||||
output_path_error);
|
||||
free(incs);
|
||||
return rc;
|
||||
}
|
||||
@@ -7156,7 +7287,7 @@ do_run(int argc, char **argv)
|
||||
const char *root_identity = !literal && is_dir ? src : NULL;
|
||||
int buildrc = build_one_sep(resolved, is_dir, root_identity, tmp, tmp, incs,
|
||||
&linkflags,
|
||||
0, 1, 0, SEP_VARIANT_PRODUCTION, NULL, 0, 0, NULL);
|
||||
0, 1, 0, SEP_VARIANT_PRODUCTION, NULL, 0, 0, NULL, NULL, NULL, 0);
|
||||
free(incs);
|
||||
if (buildrc != 0) {
|
||||
if (unlink(tmp) != 0 && errno != ENOENT)
|
||||
@@ -7226,6 +7357,10 @@ do_test(int argc, char **argv)
|
||||
int package_publish = 0;
|
||||
int package_create_workdir = 0;
|
||||
const char *package_create_output_dir = NULL;
|
||||
int package_output_path_error = 0;
|
||||
const char *package_default_output_dir = NULL;
|
||||
const char *package_output_collision_base = NULL;
|
||||
const char *package_output_collision_dir = NULL;
|
||||
struct seplinkflags package_linkflags = {0};
|
||||
int afterdash = 0;
|
||||
const char *request_identity = NULL;
|
||||
@@ -7296,6 +7431,34 @@ do_test(int argc, char **argv)
|
||||
return 2;
|
||||
}
|
||||
package_create_output_dir = argv[++i];
|
||||
} else if (strcmp(argv[i],
|
||||
"--ww-command-output-path-error") == 0) {
|
||||
if (package_output_path_error) {
|
||||
fprintf(stderr,
|
||||
"ww test: invalid --ww-command-output-path-error\n");
|
||||
return 2;
|
||||
}
|
||||
package_output_path_error = 1;
|
||||
} else if (strcmp(argv[i], "--ww-default-output-dir") == 0) {
|
||||
if (i + 1 >= argc || package_default_output_dir != NULL
|
||||
|| argv[i + 1][0] == '\0') {
|
||||
fprintf(stderr,
|
||||
"ww test: invalid --ww-default-output-dir\n");
|
||||
return 2;
|
||||
}
|
||||
package_default_output_dir = argv[++i];
|
||||
} else if (strcmp(argv[i],
|
||||
"--ww-command-output-collision") == 0) {
|
||||
if (i + 2 >= argc
|
||||
|| package_output_collision_base != NULL
|
||||
|| argv[i + 1][0] == '\0'
|
||||
|| argv[i + 2][0] == '\0') {
|
||||
fprintf(stderr,
|
||||
"ww test: invalid --ww-command-output-collision\n");
|
||||
return 2;
|
||||
}
|
||||
package_output_collision_base = argv[++i];
|
||||
package_output_collision_dir = argv[++i];
|
||||
} else if (strcmp(argv[i], "--ww-package-test") == 0) {
|
||||
if (i + 9 >= argc) {
|
||||
fprintf(stderr,
|
||||
@@ -7363,6 +7526,7 @@ do_test(int argc, char **argv)
|
||||
products[nproducts].directory_product = 1;
|
||||
products[nproducts].no_tests = test_product
|
||||
&& !has_internal && !has_external;
|
||||
products[nproducts].build_action = 1;
|
||||
products[nproducts].root = -1;
|
||||
products[nproducts].variant_root = -1;
|
||||
products[nproducts].production_root = -1;
|
||||
@@ -7494,6 +7658,12 @@ do_test(int argc, char **argv)
|
||||
fprintf(stderr, "ww test: invalid private directory creation\n");
|
||||
return 2;
|
||||
}
|
||||
if ((package_output_path_error || package_default_output_dir != NULL
|
||||
|| package_output_collision_base != NULL)
|
||||
&& (!package_build || nproducts == 0)) {
|
||||
fprintf(stderr, "ww test: invalid private output preflight\n");
|
||||
return 2;
|
||||
}
|
||||
if (package_create_workdir && nproducts == 0) {
|
||||
fprintf(stderr, "ww test: invalid private directory creation\n");
|
||||
return 2;
|
||||
@@ -7595,7 +7765,10 @@ do_test(int argc, char **argv)
|
||||
incs, workdir, products, nproducts,
|
||||
package_build ? 0 : 1, package_publish,
|
||||
package_build ? &package_linkflags : NULL, emit_asm,
|
||||
package_create_workdir, package_create_output_dir);
|
||||
package_create_workdir, package_create_output_dir,
|
||||
package_default_output_dir, package_output_path_error,
|
||||
package_output_collision_base,
|
||||
package_output_collision_dir);
|
||||
free(products);
|
||||
free(incs);
|
||||
return r;
|
||||
@@ -7643,7 +7816,7 @@ do_test(int argc, char **argv)
|
||||
outstem[0] && !discard_output ? outstem : tmp,
|
||||
incs, NULL, 0, 0, 1,
|
||||
SEP_VARIANT_PRODUCTION, NULL, emit_asm,
|
||||
outstem[0] && !discard_output ? 1 : 0, workdir);
|
||||
outstem[0] && !discard_output ? 1 : 0, workdir, NULL, NULL, 0);
|
||||
if (br != 0) {
|
||||
if (owntmp && unlink(outp) != 0 && errno != ENOENT)
|
||||
fputs("ww: cannot remove temporary output\n", stderr);
|
||||
@@ -7711,7 +7884,7 @@ do_test(int argc, char **argv)
|
||||
int br = build_one_sep(target, 0, NULL, outp,
|
||||
outstem[0] && !discard_output ? outstem : tmp,
|
||||
incs, NULL, 0, 0, 1, SEP_VARIANT_PRODUCTION, NULL, emit_asm,
|
||||
outstem[0] && !discard_output ? 1 : 0, workdir);
|
||||
outstem[0] && !discard_output ? 1 : 0, workdir, NULL, NULL, 0);
|
||||
if (br != 0) {
|
||||
if (owntmp && unlink(outp) != 0 && errno != ENOENT)
|
||||
fputs("ww: cannot remove temporary output\n", stderr);
|
||||
@@ -7759,7 +7932,9 @@ do_test(int argc, char **argv)
|
||||
int r = build_package_tests(target, request_identity, incs, workdir,
|
||||
products, nproducts, package_build ? 0 : 1,
|
||||
package_publish, package_build ? &package_linkflags : NULL,
|
||||
emit_asm, package_create_workdir, package_create_output_dir);
|
||||
emit_asm, package_create_workdir, package_create_output_dir,
|
||||
package_default_output_dir, package_output_path_error,
|
||||
package_output_collision_base, package_output_collision_dir);
|
||||
free(products);
|
||||
free(incs);
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user