commit - 56b8970e016ef878addb3a2bb6b965bab0618dd4
commit + 1890360633f9e2e2db7d890f1e3a57db32dcc949
blob - 05ebc849f544e93f1441be88fcfd8d5e0b91cc4c
blob + fb7db528948ded17772f6914fa42f8ba2ab912e9
--- make/TODO.md
+++ make/TODO.md
-S opposite of `-k`
-h print a generated help page
-s silent, do not write commands to stdout
--f file read `file` instead of `MyMakefile`
# "normal" `include file`
## Write a tutorial on how to correctly use this make
## Write a specification
## Create a freestanding version, written in Rust, so that other projects can use this make
-# `.include xxx, DIR, Makefile`
blob - fae3ab7b588ebd6ec2fca7724642b14d063bbc34
blob + a293f0d5de67124d87a88694466fe78320acc182
--- make/make.c
+++ make/make.c
sub = new (struct scope);
sub->next = sc->dir->subdirs;
sub->parent = sc;
+ sub->makefile = NULL;
sc->dir->subdirs = sub;
p = strtok (s, ",");
if (p == NULL) {
sub->type = SC_DIR;
sub->dir = NULL;
+ sub->makefile = MAKEFILE;
return 0;
}
if (strcmp (p, "DIR") == 0) {
sub->type = SC_DIR;
sub->dir = NULL;
+ sub->makefile = MAKEFILE;
+
+ p = strtok (NULL, ",");
+ if (p == NULL)
+ return 0;
+
+ sub->makefile = strdup (trim (p));
return 0;
} else if (strcmp (p, "GNU") == 0) {
sub->type = SC_GNU;
sub->gnu = new (struct gnu);
sub->gnu->prog = NULL;
- sub->gnu->file = NULL;
p = strtok (NULL, ",");
if (p == NULL)
p = strtok (NULL, ",");
if (p == NULL)
return 0;
- sub->gnu->file = strdup (trim (p));
+ sub->makefile = strdup (trim (p));
return 0;
} else {
{
char *path;
- asprintf (&path, "%s/" MAKEFILE, path_to_str (dir));
+ asprintf (&path, "%s/%s", path_to_str (dir), sc->makefile);
parse (sc, dir, path);
free (path);
}
struct scope *
-parse_recursive (dir)
+parse_recursive (dir, makefile)
struct path *dir;
+char *makefile;
{
struct path *mfpath, *ppath;
struct scope *sc, *parent;
char *path, *name;
- tmppath.name = MAKEFILE;
+ tmppath.name = makefile;
mfpath = path_cat (dir, &tmppath);
path = path_to_str (mfpath);
if (access (path, F_OK) != 0) {
}
ppath = path_cat (dir, &path_super);
- parent = parse_recursive (ppath);
+ parent = parse_recursive (ppath, makefile);
+ if (parent == NULL)
+ parent = parse_recursive (ppath, MAKEFILE);
free (ppath);
name = path_basename (dir);
}
parse:
+ sc->makefile = makefile;
sc->parent = parent;
path = strdup (path_to_str (mfpath));
parse (sc, dir, path);
return ec;
}
-rungnu (sc, prefix, gnu, rule, q)
+rungnu (sc, prefix, rule, q)
struct scope *sc;
struct path *prefix;
-struct gnu *gnu;
char *rule;
{
size_t len = 0;
char *cmd, *prog;
int ec;
- prog = gnu->prog != NULL ? gnu->prog : "make";
+ /* TODO: use str_*() API */
+ prog = sc->gnu->prog != NULL ? sc->gnu->prog : "make";
len += strlen (prog);
if (q)
len += 3;
- if (gnu->file != NULL)
- len += strlen (gnu->file) + 4;
+ if (sc->makefile != NULL)
+ len += strlen (sc->makefile) + 4;
if (rule != NULL)
len += strlen (rule) + 1;
if (q)
strcat (cmd, " -q");
- if (gnu->file != NULL) {
+ if (sc->makefile != NULL) {
strcat (cmd, " -f ");
- strcat (cmd, gnu->file);
+ strcat (cmd, sc->makefile);
}
if (rule != NULL) {
goto ret;
case SC_GNU:
/* first check if the target is already built */
- if (rungnu (sc, prefix, sc->gnu, name, 1) == 0) {
+ if (rungnu (sc, prefix, name, 1) == 0) {
t.tv_sec = 0;
goto ret;
}
- if (rungnu (sc, prefix, sc->gnu, name, 0) != 0)
+ if (rungnu (sc, prefix, name, 0) != 0)
errx (1, "building foreign directory failed");
t = now ();
char **s;
if (verbose)
- printf ("=== %s/%s\n", path_to_str (prefix), MAKEFILE);
+ printf ("=== %s/%s\n", path_to_str (prefix), sc->makefile);
if (sc->type != SC_DIR || sc->dir == NULL)
errx (1, "print_sc(): must be of type SC_DIR");
for (sub = sc->dir->subdirs; sub != NULL; sub = sub->next) {
switch (sub->type) {
case SC_DIR:
- printf (".include %s, DIR\n", sub->name);
+ printf (".include %s, DIR", sub->name);
+ if (sc->makefile != NULL)
+ printf (", %s", sc->makefile);
+ printf ("\n");
break;
case SC_GNU:
printf (".include %s, GNU", sub->name);
- if (sub->gnu->prog)
+ if (sub->gnu->prog != NULL)
printf (", %s", sub->gnu->prog);
- if (sub->gnu->file)
- printf (", %s", sub->gnu->file);
+ if (sc->makefile != NULL)
+ printf (", %s", sc->makefile);
printf ("\n");
break;
}
usage ()
{
- fprintf (stderr, "usage: %s [-pv] [-C dir] [target...]\n", m_make.value);
+ fprintf (stderr, "usage: %s [-pv] [-C dir] [-f makefile] [target...]\n", m_make.value);
return 1;
}
struct scope *sc;
struct path *path;
struct macro *m;
- char *s, *cd = NULL;
+ char *s, *cd = NULL, *makefile = MAKEFILE;
int i, option, pr = 0, n = 0;
m_dmake.value = m_make.value = argv[0];
str_reset ();
- while ((option = getopt (argc, argv, "pvC:")) != -1) {
+ while ((option = getopt (argc, argv, "pvC:f:")) != -1) {
switch (option) {
case 'p':
str_push_str (" -p");
case 'C':
cd = optarg;
break;
+ case 'f':
+ makefile = optarg;
+ break;
case '?':
return usage ();
default:
m_dmakeflags.value = m_makeflags.value = strdup (trim (str_get ()));
path = parse_path (".");
- sc = parse_recursive (path);
+ sc = parse_recursive (path, makefile);
+ if (sc == NULL)
+ errx (1, "failed to find or parse makefile");
if (pr) {
print_sc (path, sc, verbose);
blob - 9d67b3a7fb336880d2b6daab65c7ce4e9d09bad8
blob + d2758945c7b2ec8dc2490fe94f889cd012978ab9
--- make/make.h
+++ make/make.h
enum scope_type type;
char *name; /* optional */
struct scope *parent; /* optional */
+ char *makefile; /* required */
union {
struct directory *dir; /* optional */
struct gnu *gnu; /* required */
struct gnu {
char *prog; /* optional (default: "make") */
- char *file; /* optional */
};
struct dep {