char *list = talloc_strdup(m, "");
struct ccan_file *i;
- /* Object from all the C files. */
+ /* Objects from all the C files. */
list_for_each(&m->c_files, i, list)
- list = talloc_asprintf_append(list, "%.*s.o ",
- strlen(i->name) - 2, i->name);
+ list = talloc_asprintf_append(list, "%s ", i->compiled);
return list;
}
-/* We leave this object file around after ccanlint runs, all built. */
static void *do_build(struct manifest *m)
{
+ char *filename, *err;
+
if (list_empty(&m->c_files)) {
/* No files? No score, but we "pass". */
build.total_score = 0;
return NULL;
}
- return run_command(m, "ld -r -o ../%s.o %s", m->basename, obj_list(m));
+ filename = link_objects(m, obj_list(m), &err);
+ if (filename) {
+ char *realname = talloc_asprintf(m, "../%s.o", m->basename);
+ /* We leave this object file around, all built. */
+ if (rename(filename, realname) != 0)
+ return talloc_asprintf(m, "Failed to rename %s to %s",
+ filename, realname);
+ return NULL;
+ }
+ return err;
}
static const char *describe_build(struct manifest *m, void *check_result)
return NULL;
}
-static bool compile_obj(struct ccan_file *c_file, char *objfile, char **report)
-{
- char *err;
-
- err = compile_object(objfile, objfile, c_file->name);
- if (err) {
- if (*report)
- *report = talloc_append_string(*report, err);
- else
- *report = err;
- return false;
- }
- return true;
-}
-
-static int cleanup_obj(char *objfile)
-{
- unlink(objfile);
- return 0;
-}
-
static void *check_objs_build(struct manifest *m)
{
char *report = NULL;
struct ccan_file *i;
- /* One point for each obj file. */
- list_for_each(&m->c_files, i, list)
- build_objs.total_score++;
-
list_for_each(&m->c_files, i, list) {
- char *objfile = talloc_strdup(m, i->name);
- objfile[strlen(objfile)-1] = 'o';
+ char *err;
+
+ /* One point for each obj file. */
+ build_objs.total_score++;
- if (compile_obj(i, objfile, &report))
- talloc_set_destructor(objfile, cleanup_obj);
+ i->compiled = compile_object(m, i->name, &err);
+ if (!i->compiled) {
+ if (report)
+ report = talloc_append_string(report, err);
+ else
+ report = err;
+ }
}
return report;
}
static const char *describe_objs_build(struct manifest *m, void *check_result)
{
- return talloc_asprintf(check_result,
- "%s", (char *)check_result);
+ return check_result;
}
struct ccanlint build_objs = {
static void *check_includes_build(struct manifest *m)
{
char *contents;
- char *tmpfile, *objfile;
+ char *tmpfile, *err;
int fd;
tmpfile = temp_file(m, ".c");
- objfile = temp_file(m, ".o");
fd = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600);
if (fd < 0)
}
close(fd);
- return compile_object(m, objfile, tmpfile);
+ if (compile_object(m, tmpfile, &err))
+ return NULL;
+ return err;
}
static const char *describe_includes_build(struct manifest *m,
return NULL;
}
-static char *objname(const void *ctx, const char *cfile)
+static char *compile(struct manifest *m, struct ccan_file *cfile)
{
- return talloc_asprintf(ctx, "%.*s.o ", strlen(cfile) - 2, cfile);
-}
-
-static char *compile(struct manifest *m, const char *cfile)
-{
- char *obj;
+ char *err;
- obj = objname(m, cfile);
- return compile_object(m, obj, cfile);
+ cfile->compiled = compile_object(m, cfile->name, &err);
+ if (cfile->compiled)
+ return NULL;
+ return err;
}
static void *do_compile_test_helpers(struct manifest *m)
list_for_each(&m->other_test_c_files, i, list) {
compile_tests.total_score++;
- cmdout = compile(m, i->name);
+ cmdout = compile(m, i);
if (cmdout)
return talloc_asprintf(m,
"Failed to compile helper C"
static char *obj_list(const struct manifest *m, bool link_with_module)
{
- char *list = talloc_strdup(m, "../tap.o");
+ char *list;
struct ccan_file *i;
+ /* We expect to be linked with tap, unless that's us. */
+ if (!streq(m->basename, "tap"))
+ list = talloc_strdup(m, "../tap.o");
+ else
+ list = talloc_strdup(m, "");
+
/* Objects from any other C files. */
list_for_each(&m->other_test_c_files, i, list)
- list = talloc_asprintf_append(list, " %.*s.o",
- strlen(i->name) - 2, i->name);
+ list = talloc_asprintf_append(list, " %s", i->compiled);
if (link_with_module)
list = talloc_asprintf_append(list, " ../%s.o", m->basename);
list_for_each(&m->compile_fail_tests, i, list) {
compile_tests.total_score++;
- cmdout = compile(list, m, i, true, false);
+ cmdout = compile(list, m, i, false, false);
if (cmdout) {
res = talloc(list, struct compile_tests_result);
res->filename = i->name;
res->output = talloc_steal(res, cmdout);
list_add_tail(list, &res->list);
} else {
- cmdout = compile(list, m, i, false, false);
+ cmdout = compile(list, m, i, true, false);
if (!cmdout) {
res = talloc(list, struct compile_tests_result);
res->filename = i->name;
#include <stdlib.h>
/* Compile multiple object files into a single. Returns errmsg if fails. */
-char *link_objects(const void *ctx, const char *outfile, const char *objs)
+char *link_objects(const void *ctx, const char *objs, char **errmsg)
{
- return run_command(ctx, "cc " CFLAGS " -c -o %s %s", outfile, objs);
+ char *file = temp_file(ctx, ".o");
+
+ *errmsg = run_command(ctx, "ld -r -o %s %s", file, objs);
+ if (*errmsg) {
+ talloc_free(file);
+ return NULL;
+ }
+ return file;
}
/* Compile a single C file to an object file. Returns errmsg if fails. */
-char *compile_object(const void *ctx, const char *outfile, const char *cfile)
+char *compile_object(const void *ctx, const char *cfile, char **errmsg)
{
- return run_command(ctx, "cc " CFLAGS " -c -o %s %s", outfile, cfile);
+ char *file = temp_file(ctx, ".o");
+
+ *errmsg = run_command(ctx, "cc " CFLAGS " -c -o %s %s", file, cfile);
+ if (*errmsg) {
+ talloc_free(file);
+ return NULL;
+ }
+ return file;
}
/* Compile and link single C file, with object files.
/* Ensure stderr gets to us too. */
cmd = talloc_asprintf_append(cmd, " 2>&1");
-
+
pipe = popen(cmd, "r");
if (!pipe)
return talloc_asprintf(ctx, "Failed to run '%s'", cmd);
{
char cmd[strlen(dir) + sizeof("rm -rf ")];
sprintf(cmd, "rm -rf %s", dir);
-// system(cmd);
+ system(cmd);
return 0;
}
char *run_command(const void *ctx, const char *fmt, ...);
char *temp_file(const void *ctx, const char *extension);
-/* From compile.c. */
-/* Compile multiple object files into a single. Returns errmsg if fails. */
-char *link_objects(const void *ctx, const char *outfile, const char *objs);
+/* From compile.c.
+ *
+ * These all compile into a temporary dir, and return the filename.
+ * On failure they return NULL, and errmsg is set to compiler output.
+ */
+/* Compile multiple object files into a single. */
+char *link_objects(const void *ctx, const char *objs, char **errmsg);
/* Compile a single C file to an object file. Returns errmsg if fails. */
-char *compile_object(const void *ctx, const char *outfile, const char *cfile);
-/* Compile and link single C file, with object files.
- * Returns name of result, or NULL (and fills in errmsg). */
+char *compile_object(const void *ctx, const char *cfile, char **errmsg);
+/* Compile and link single C file, with object files, libs, etc. */
char *compile_and_link(const void *ctx, const char *cfile, const char *objs,
const char *extra_cflags, const char *libs,
char **errmsg);