summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorH. Peter Anvin <hpa@zytor.com>2008-05-29 21:38:00 -0700
committerH. Peter Anvin <hpa@zytor.com>2008-05-29 21:38:00 -0700
commit9e1f528c3634af3ce3650c1784f20eeae62abe42 (patch)
tree5f3cf4ae0240b09c62548174f6584ca2b123c840
parent46fe1eed76bbb4ede2ddc0265d6b5e6cc2389abf (diff)
downloadnasm-9e1f528c3634af3ce3650c1784f20eeae62abe42.tar.gz
Add the -MP option to emit phony targets
Add the -MP option to emit phony targets. Since this means each header file has to be visited more than once, change the implementation to use an internal list of all the dependencies, and centralize the emission of the dependency files.
-rw-r--r--CHANGES2
-rw-r--r--doc/nasmdoc.src9
-rw-r--r--nasm.c105
-rw-r--r--nasm.h10
-rw-r--r--preproc.c79
5 files changed, 137 insertions, 68 deletions
diff --git a/CHANGES b/CHANGES
index e60fbc7f..f4f480b3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -13,7 +13,7 @@
* SAFESEH support for Win32, IMAGEREL for Win64 (SEH).
* %? and %?? to refer to the name of a macro itself. In particular,
"%idefine keyword $%?" can be used to make a keyword "disappear".
-* New options for dependency generation: -MD, -MF, -MT, -MQ.
+* New options for dependency generation: -MD, -MF, -MP, -MT, -MQ.
2.02
----
diff --git a/doc/nasmdoc.src b/doc/nasmdoc.src
index cff4096d..6b191991 100644
--- a/doc/nasmdoc.src
+++ b/doc/nasmdoc.src
@@ -19,6 +19,7 @@
\IR{-MD} \c{-MD} option
\IR{-MF} \c{-MF} option
\IR{-MG} \c{-MG} option
+\IR{-MP} \c{-MP} option
\IR{-MQ} \c{-MQ} option
\IR{-MT} \c{-MT} option
\IR{-On} \c{-On} option
@@ -609,6 +610,14 @@ is not foolproof, as not all characters with special meaning are
quotable in Make.
+\S{opt-MP} The \i\c{-MP} Option: Emit phony targets
+
+When used with any of the dependency generation options, the \c{-MP}
+option causes NASM to emit a phony target without dependencies for
+each header file. This prevents Make from complaining if a header
+file has been removed.
+
+
\S{opt-F} The \i\c{-F} Option: Selecting a \i{Debug Information Format}
This option is used to select the format of the debug information emitted
diff --git a/nasm.c b/nasm.c
index 766248e1..1eb5e4f7 100644
--- a/nasm.c
+++ b/nasm.c
@@ -38,7 +38,7 @@ struct forwrefinfo { /* info held on forward refs. */
static int get_bits(char *value);
static uint32_t get_cpu(char *cpu_str);
static void parse_cmdline(int, char **);
-static void assemble_file(char *, FILE *);
+static void assemble_file(char *, StrList **);
static void register_output_formats(void);
static void report_error_gnu(int severity, const char *fmt, ...);
static void report_error_vc(int severity, const char *fmt, ...);
@@ -91,6 +91,7 @@ enum op_type {
};
static enum op_type operating_mode;
/* Dependency flags */
+static bool depend_emit_phony = false;
static bool depend_missing_ok = false;
static const char *depend_target = NULL;
static const char *depend_file = NULL;
@@ -136,7 +137,7 @@ static const char *suppressed_what[ERR_WARN_MAX+1] = {
* not preprocess their source file.
*/
-static void no_pp_reset(char *, int, efunc, evalfunc, ListGen *, FILE *);
+static void no_pp_reset(char *, int, efunc, evalfunc, ListGen *, StrList **);
static char *no_pp_getline(void);
static void no_pp_cleanup(int);
static Preproc no_pp = {
@@ -242,9 +243,50 @@ static void define_macros_late(void)
pp_pre_define(temp);
}
+static void emit_dependencies(StrList *list)
+{
+ FILE *deps;
+ int linepos, len;
+ StrList *l, *nl;
+
+ if (depend_file && strcmp(depend_file, "-")) {
+ deps = fopen(depend_file, "w");
+ if (!deps) {
+ report_error(ERR_NONFATAL|ERR_NOFILE|ERR_USAGE,
+ "unable to write dependency file `%s'", depend_file);
+ return;
+ }
+ } else {
+ deps = stdout;
+ }
+
+ linepos = fprintf(deps, "%s:", depend_target);
+ for (l = list; l; l = l->next) {
+ len = strlen(l->str);
+ if (linepos + len > 62) {
+ fprintf(deps, " \\\n ");
+ linepos = 1;
+ }
+ fprintf(deps, " %s", l->str);
+ linepos += len+1;
+ }
+ fprintf(deps, "\n\n");
+
+ for (l = list; l; l = nl) {
+ if (depend_emit_phony)
+ fprintf(deps, "%s:\n\n", l->str);
+
+ nl = l->next;
+ nasm_free(l);
+ }
+
+ if (deps != stdout)
+ fclose(deps);
+}
+
int main(int argc, char **argv)
{
- FILE *depends;
+ StrList *depend_list = NULL, **depend_ptr;
time(&official_compile_time);
@@ -289,16 +331,8 @@ int main(int argc, char **argv)
/* define some macros dependent of command-line */
define_macros_late();
- depends = NULL;
- if (depend_file) {
- depends = fopen(depend_file, "w");
- if (!depends) {
- report_error(ERR_FATAL | ERR_NOFILE,
- "unable to open dependencies file `%s'",
- depend_file);
- }
- }
-
+ depend_ptr = (depend_file || (operating_mode == op_depend))
+ ? &depend_list : NULL;
if (!depend_target)
depend_target = outname;
@@ -307,18 +341,14 @@ int main(int argc, char **argv)
{
char *line;
- if (!depends)
- depends = stdout;
-
if (depend_missing_ok)
pp_include_path(NULL); /* "assume generated" */
preproc->reset(inname, 0, report_error, evaluate, &nasmlist,
- depends);
+ depend_ptr);
if (outname[0] == '\0')
ofmt->filename(inname, outname, report_error);
ofile = NULL;
- fprintf(depends, "%s: %s", depend_target, inname);
while ((line = preproc->getline()))
nasm_free(line);
preproc->cleanup(0);
@@ -345,9 +375,7 @@ int main(int argc, char **argv)
/* pass = 1; */
preproc->reset(inname, 2, report_error, evaluate, &nasmlist,
- depends);
- if (depends)
- fprintf(depends, "%s: %s", depend_target, inname);
+ depend_ptr);
while ((line = preproc->getline())) {
/*
@@ -404,7 +432,7 @@ int main(int argc, char **argv)
ofmt->init(ofile, report_error, define_label, evaluate);
- assemble_file(inname, depends);
+ assemble_file(inname, depend_ptr);
if (!terminate_after_phase) {
ofmt->cleanup(using_debug_info);
@@ -424,11 +452,8 @@ int main(int argc, char **argv)
break;
}
- if (depends) {
- putc('\n', depends);
- if (depends != stdout)
- fclose(depends);
- }
+ if (depend_list)
+ emit_dependencies(depend_list);
if (want_usage)
usage();
@@ -825,13 +850,15 @@ static bool process_arg(char *p, char *q)
case 'M':
switch (p[2]) {
case 0:
- case 'M':
operating_mode = op_depend;
break;
case 'G':
operating_mode = op_depend;
depend_missing_ok = true;
break;
+ case 'P':
+ depend_emit_phony = true;
+ break;
case 'D':
depend_file = q;
advance = true;
@@ -1085,8 +1112,10 @@ static void parse_cmdline(int argc, char **argv)
if (!*inname)
report_error(ERR_NONFATAL | ERR_NOFILE | ERR_USAGE,
"no input file specified");
- else if (!strcmp(inname, errname) || !strcmp(inname, outname) ||
- !strcmp(inname, listname))
+ else if (!strcmp(inname, errname) ||
+ !strcmp(inname, outname) ||
+ !strcmp(inname, listname) ||
+ (depend_file && !strcmp(inname, depend_file)))
report_error(ERR_FATAL | ERR_NOFILE | ERR_USAGE,
"file `%s' is both input and output file",
inname);
@@ -1113,7 +1142,7 @@ static const char *directives[] = {
};
static enum directives getkw(char **directive, char **value);
-static void assemble_file(char *fname, FILE *depends)
+static void assemble_file(char *fname, StrList **depend_ptr)
{
char *directive, *value, *p, *q, *special, *line, debugid[80];
insn output_ins;
@@ -1158,9 +1187,7 @@ static void assemble_file(char *fname, FILE *depends)
offsets = raa_init();
}
preproc->reset(fname, pass1, report_error, evaluate, &nasmlist,
- pass1 == 2 ? depends : NULL);
- if (pass1 == 2 && depends)
- fprintf(depends, "%s: %s", depend_target, inname);
+ pass1 == 2 ? depend_ptr : NULL);
globallineno = 0;
if (passn == 1)
@@ -1950,7 +1977,7 @@ static ListGen *no_pp_list;
static int32_t no_pp_lineinc;
static void no_pp_reset(char *file, int pass, efunc error, evalfunc eval,
- ListGen * listgen, FILE *depends)
+ ListGen * listgen, StrList **deplist)
{
src_set_fname(nasm_strdup(file));
src_set_linnum(0);
@@ -1963,7 +1990,13 @@ static void no_pp_reset(char *file, int pass, efunc error, evalfunc eval,
no_pp_list = listgen;
(void)pass; /* placate compilers */
(void)eval; /* placate compilers */
- (void)depends; /* placate compilers */
+
+ if (deplist) {
+ StrList *sl = nasm_malloc(strlen(file)+1+sizeof sl->next);
+ sl->next = NULL;
+ strcpy(sl->str, file);
+ *deplist = sl;
+ }
}
static char *no_pp_getline(void)
diff --git a/nasm.h b/nasm.h
index 4c7b3386..384fb659 100644
--- a/nasm.h
+++ b/nasm.h
@@ -291,6 +291,14 @@ typedef expr *(*evalfunc) (scanner sc, void *scprivate,
#define EXPR_SEGBASE (EXPR_REG_END+4)
/*
+ * Linked list of strings...
+ */
+typedef struct string_list {
+ struct string_list *next;
+ char str[1];
+} StrList;
+
+/*
* preprocessors ought to look like this:
*/
typedef struct preproc_ops {
@@ -299,7 +307,7 @@ typedef struct preproc_ops {
* of the pass, an error reporting function, an evaluator
* function, and a listing generator to talk to.
*/
- void (*reset) (char *, int, efunc, evalfunc, ListGen *, FILE *);
+ void (*reset) (char *, int, efunc, evalfunc, ListGen *, StrList **);
/*
* Called to fetch a line of preprocessed source. The line
diff --git a/preproc.c b/preproc.c
index 7a305b39..c42cdfd8 100644
--- a/preproc.c
+++ b/preproc.c
@@ -327,7 +327,7 @@ static efunc _error; /* Pointer to client-provided error reporting fu
static evalfunc evaluate;
static int pass; /* HACK: pass 0 = generate dependencies only */
-static FILE *deplist; /* Write dependencies to this FILE */
+static StrList **dephead, **deptail; /* Dependency list */
static uint64_t unique; /* unique identifier numbers */
@@ -1257,51 +1257,63 @@ static Context *get_ctx(char *name, bool all_contexts)
}
/*
+ * Check to see if a file is already in a string list
+ */
+static bool in_list(const StrList *list, const char *str)
+{
+ while (list) {
+ if (!strcmp(list->str, str))
+ return true;
+ list = list->next;
+ }
+ return false;
+}
+
+/*
* Open an include file. This routine must always return a valid
* file pointer if it returns - it's responsible for throwing an
* ERR_FATAL and bombing out completely if not. It should also try
* the include path one by one until it finds the file or reaches
* the end of the path.
*/
-static FILE *inc_fopen(char *file)
+static FILE *inc_fopen(const char *file)
{
FILE *fp;
- char *prefix = "", *combine;
+ char *prefix = "";
IncPath *ip = ipath;
- static int namelen = 0;
int len = strlen(file);
+ size_t prefix_len = 0;
+ StrList *sl;
while (1) {
- combine = nasm_malloc(strlen(prefix) + len + 1);
- strcpy(combine, prefix);
- strcat(combine, file);
- fp = fopen(combine, "r");
- if (fp && deplist) {
- namelen += strlen(combine) + 1;
- if (namelen > 62) {
- fprintf(deplist, " \\\n ");
- namelen = 2;
- }
- fprintf(deplist, " %s", combine);
- }
- nasm_free(combine);
+ sl = nasm_malloc(prefix_len+len+1+sizeof sl->next);
+ memcpy(sl->str, prefix, prefix_len);
+ memcpy(sl->str+prefix_len, file, len+1);
+ fp = fopen(sl->str, "r");
+ if (fp && dephead && !in_list(*dephead, sl->str)) {
+ sl->next = NULL;
+ *deptail = sl;
+ deptail = &sl->next;
+ } else {
+ nasm_free(sl);
+ }
if (fp)
return fp;
if (!ip)
break;
prefix = ip->path;
ip = ip->next;
-
- if (!prefix) {
- /* -MG given and file not found */
- if (deplist) {
- namelen += strlen(file) + 1;
- if (namelen > 62) {
- fprintf(deplist, " \\\n ");
- namelen = 2;
- }
- fprintf(deplist, " %s", file);
- }
+ if (prefix) {
+ prefix_len = strlen(prefix);
+ } else {
+ /* -MG given and file not found */
+ if (dephead && !in_list(*dephead, file)) {
+ sl = nasm_malloc(len+1+sizeof sl->next);
+ sl->next = NULL;
+ strcpy(sl->str, file);
+ *deptail = sl;
+ deptail = &sl->next;
+ }
return NULL;
}
}
@@ -3734,7 +3746,7 @@ static void error(int severity, const char *fmt, ...)
static void
pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
- ListGen * listgen, FILE * adeplist)
+ ListGen * listgen, StrList **deplist)
{
_error = errfunc;
cstk = NULL;
@@ -3763,7 +3775,14 @@ pp_reset(char *file, int apass, efunc errfunc, evalfunc eval,
list = listgen;
evaluate = eval;
pass = apass;
- deplist = adeplist;
+ dephead = deptail = deplist;
+ if (deplist) {
+ StrList *sl = nasm_malloc(strlen(file)+1+sizeof sl->next);
+ sl->next = NULL;
+ strcpy(sl->str, file);
+ *deptail = sl;
+ deptail = &sl->next;
+ }
}
static char *pp_getline(void)