| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102 |
- #include "talloc/talloc.h"
- #include "string/string.h"
- #include "tools.h"
- #include <err.h>
- #include <stdbool.h>
- #include <unistd.h>
- static char ** __attribute__((format(printf, 3, 4)))
- lines_from_cmd(const void *ctx, unsigned int *num, char *format, ...)
- {
- va_list ap;
- char *cmd, *buffer;
- FILE *p;
- va_start(ap, format);
- cmd = talloc_vasprintf(ctx, format, ap);
- va_end(ap);
- p = popen(cmd, "r");
- if (!p)
- err(1, "Executing '%s'", cmd);
- buffer = grab_fd(ctx, fileno(p));
- if (!buffer)
- err(1, "Reading from '%s'", cmd);
- pclose(p);
- return strsplit(ctx, buffer, "\n", num);
- }
- static int unlink_info(char *infofile)
- {
- unlink(infofile);
- return 0;
- }
- /* Be careful about trying to compile over running programs (parallel make) */
- static char *compile_info(const void *ctx, const char *dir)
- {
- char *infofile = talloc_asprintf(ctx, "%s/_info.%u", dir, getpid());
- char *cmd = talloc_asprintf(ctx, "cc " CFLAGS " -o %s %s/_info.c",
- infofile, dir);
- talloc_set_destructor(infofile, unlink_info);
- if (system(cmd) != 0)
- return NULL;
- return infofile;
- }
- static char **get_one_deps(const void *ctx, const char *dir, unsigned int *num)
- {
- char **deps, *cmd, *infofile;
- infofile = compile_info(ctx, dir);
- if (!infofile)
- errx(1, "Could not compile _info for '%s'", dir);
- cmd = talloc_asprintf(ctx, "%s depends", infofile);
- deps = lines_from_cmd(cmd, num, "%s", cmd);
- if (!deps)
- err(1, "Could not run '%s'", cmd);
- return deps;
- }
- static bool have_dep(char **deps, unsigned int num, const char *dep)
- {
- unsigned int i;
- for (i = 0; i < num; i++)
- if (streq(deps[i], dep))
- return true;
- return false;
- }
- /* Gets all the dependencies, recursively. */
- char **get_deps(const void *ctx, const char *dir)
- {
- char **deps;
- unsigned int i, num;
- deps = get_one_deps(ctx, dir, &num);
- for (i = 0; i < num; i++) {
- char **newdeps;
- unsigned int j, newnum;
- if (!strstarts(deps[i], "ccan/"))
- continue;
- newdeps = get_one_deps(ctx, deps[i], &newnum);
- /* Should be short, so brute-force out dups. */
- for (j = 0; j < newnum; j++) {
- if (have_dep(deps, num, newdeps[j]))
- continue;
- deps = talloc_realloc(NULL, deps, char *, num + 2);
- deps[num++] = newdeps[j];
- deps[num] = NULL;
- }
- }
- return deps;
- }
|