build.total_score = 0;
                return NULL;
        }
-       filename = link_objects(m, obj_list(m), &err);
+       filename = link_objects(m, m->basename, false, obj_list(m), &err);
        if (filename && keep) {
                char *realname = talloc_asprintf(m, "%s.o", m->dir);
                /* We leave this object file around, all built. */
 
 {
        char *contents;
        char *tmpfile;
+       char *basename = talloc_asprintf(m, "%s/example.c", m->dir);
        int fd;
 
-       tmpfile = temp_file(m, ".c");
+       tmpfile = maybe_temp_file(m, ".c", keep, basename);
 
        fd = open(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600);
        if (fd < 0)
        close(fd);
 
        return compile_and_link(m, tmpfile, ccan_dir, obj_list(m), "",
-                               lib_list(m), temp_file(m, ""));
+                               lib_list(m),
+                               maybe_temp_file(m, "", keep, tmpfile));
 }
 
 static const char *describe_use_build(struct manifest *m, void *check_result)
 
                     bool keep,
                     struct ccan_file *cfile)
 {
-       cfile->compiled = maybe_temp_file(m, "", keep, cfile->fullname);
+       cfile->compiled = maybe_temp_file(m, ".o", keep, cfile->fullname);
        return compile_object(m, cfile->fullname, ccan_dir, "",
                              cfile->compiled);
 }
 
 bool compile_verbose = false;
 
 /* Compile multiple object files into a single.  Returns errmsg if fails. */
-char *link_objects(const void *ctx, const char *objs, char **errmsg)
+char *link_objects(const void *ctx, const char *basename, bool in_pwd,
+                  const char *objs, char **errmsg)
 {
-       char *file = temp_file(ctx, ".o");
+       char *file = maybe_temp_file(ctx, ".o", in_pwd, basename);
 
        if (compile_verbose)
                printf("Linking objects into %s\n", file);
 
        if (!info)
                return NULL;
 
-       info_c_file = temp_file(ctx, ".c");
+       info_c_file = maybe_temp_file(ctx, ".c", false, "_info");
        fd = open(info_c_file, O_WRONLY|O_CREAT|O_EXCL, 0600);
        if (fd < 0)
                return NULL;
        ccandir = talloc_dirname(ctx, dir);
        *strrchr(ccandir, '/') = '\0';
 
-       compiled = temp_file(ctx, "");
+       compiled = maybe_temp_file(ctx, "", false, "info");
        if (compile_and_link(ctx, info_c_file, ccandir, "", "", "",
                             compiled))
                return NULL;
 
 #include <errno.h>
 #include <err.h>
 #include <unistd.h>
+#include <assert.h>
 #include "tools.h"
 
 static char *tmpdir = NULL;
-static unsigned int count;
 bool tools_verbose = false;
 
 /* Ten minutes. */
        return tmpdir;
 }
 
-char *temp_file(const void *ctx, const char *extension)
-{
-       char *f = talloc_asprintf(ctx, "%s/%u%s",
-                                 temp_dir(ctx), count++, extension);
-       if (tools_verbose)
-               printf("Created temporary file %s\n", f);
-       return f;
-}
-
 char *maybe_temp_file(const void *ctx, const char *extension, bool keep,
                      const char *srcname)
 {
        size_t baselen;
-       char *f;
+       char *f, *suffix = talloc_strdup(ctx, "");
+       struct stat st;
+       unsigned int count = 0;
 
        if (!keep)
-               return temp_file(ctx, extension);
+               srcname = talloc_basename(ctx, srcname);
+       else
+               assert(srcname[0] == '/');
+
+       if (strrchr(srcname, '.'))
+               baselen = strrchr(srcname, '.') - srcname;
+       else
+               baselen = strlen(srcname);
+
+       do {
+               f = talloc_asprintf(ctx, "%s/%.*s%s%s",
+                                   keep ? "" : temp_dir(ctx),
+                                   baselen, srcname,
+                                   suffix, extension);
+               talloc_free(suffix);
+               suffix = talloc_asprintf(ctx, "-%u", ++count);
+       } while (!keep && lstat(f, &st) == 0);
 
-       baselen = strrchr(srcname, '.') - srcname;
-       f = talloc_asprintf(ctx, "%.*s%s", baselen, srcname, extension);
        if (tools_verbose)
                printf("Creating file %s\n", f);
+
+       talloc_free(suffix);
        return f;
 }
 
 
 char *run_with_timeout(const void *ctx, const char *cmd,
                       bool *ok, unsigned *timeout_ms);
 char *temp_dir(const void *ctx);
-char *temp_file(const void *ctx, const char *extension);
 bool move_file(const char *oldname, const char *newname);
 
 /* From compile.c.
 /* If set, say what we're compiling to. */
 extern bool compile_verbose;
 /* Compile multiple object files into a single. */
-char *link_objects(const void *ctx, const char *objs, char **errmsg);
+char *link_objects(const void *ctx, const char *basename, bool in_pwd,
+                  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 *cfile, const char *ccandir,
                     const char *extra_cflags,
                       const char *objs, const char *extra_cflags,
                       const char *libs, const char *outfile);
 
-/* If keep is false, return a temporary file.  Otherwise, base it on srcname */
-char *maybe_temp_file(const void *ctx, const char *extension, bool keep,
+/* If in_pwd is false, return a file int temp_dir, otherwise a local file. */
+char *maybe_temp_file(const void *ctx, const char *extension, bool in_pwd,
                      const char *srcname);
 
 /* Default wait for run_command.  Should never time out. */