This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Implement -MF <output-filename>


Unfortunately this complicates things w.r.t. -MD and -MMD.  The "cpp"
and "gcc" drivers would take these latter options without an argument,
and pass them to cpp0 with an argument.

This meant cpp0 was providing multiple ways to express the output file
name (not to mention the vaguely documented environment variable
OUTPUT_DEPENDENCIES and the undocumented SUNPRO_DEPENDENCIES).

So, I scrapped -MD and -MMD from cpp0 (worthwhile simplification, in
fact), and re-did the driver specs to cause -MD and -MMD send "-M -MF"
or "-MM -MF" instead.  This seems cleaner and more logical.  It also
eliminates much of the confusion that existed with -MG and -MD / -MMD.

The command line -MF overrides environment variable designations,
since this seems to be standard practice.

Zack, do you think I'm going the right way with this?  I'll wait for
your confirmation before committing.

The patch also renames a few function names to be shorter and more
consistent with the rest of CPP and GCC, and updates the CPP run-time
help.

Neil.

	* cppinit.c (initialize, initialize_builtins,
	initialize_dependency_output, initialize_standard_includes):
	Rename with init instead of initialize.
	(check_options): New function, called when cpp_handle_options
	has finished all options, before it returns.
	(cpp_start_read): Move some checks to check_options.  Set
	dependency information if appropriate.
	(init_dependency_output): Now called from check_options.
	(output_deps): New function, broken out from cpp_finish.
	(OPT_MD, OPT_MMD): Remove.
	(OPT_MF): New.
	(cpp_handle_option): Update.
	(cpp_handle_options): Call check_options when finally finished.
	(print_help): Update.

Index: cppinit.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/cppinit.c,v
retrieving revision 1.131
diff -u -p -r1.131 cppinit.c
--- cppinit.c	2001/01/06 00:15:29	1.131
+++ cppinit.c	2001/01/06 13:48:43
@@ -94,8 +94,8 @@ struct cpp_pending
 static void print_help                  PARAMS ((void));
 static void path_include		PARAMS ((cpp_reader *,
 						 char *, int));
-static void initialize			PARAMS ((void));
-static void initialize_builtins		PARAMS ((cpp_reader *));
+static void init			PARAMS ((void));
+static void init_builtins		PARAMS ((cpp_reader *));
 static void append_include_chain	PARAMS ((cpp_reader *,
 						 char *, int, int));
 struct file_name_list * remove_dup_dir	PARAMS ((cpp_reader *,
@@ -107,11 +107,13 @@ static void do_includes			PARAMS ((cpp_r
 						 struct pending_option *,
 						 int));
 static void set_lang			PARAMS ((cpp_reader *, enum c_lang));
-static void initialize_dependency_output PARAMS ((cpp_reader *));
-static void initialize_standard_includes PARAMS ((cpp_reader *));
+static void init_dependency_output	PARAMS ((cpp_reader *));
+static void init_standard_includes	PARAMS ((cpp_reader *));
+static void output_deps			PARAMS ((cpp_reader *));
 static void new_pending_directive	PARAMS ((struct cpp_pending *,
 						 const char *,
 						 cl_directive_handler));
+static void check_options		PARAMS ((cpp_reader *));
 #ifdef HOST_EBCDIC
 static int opt_comp			PARAMS ((const void *, const void *));
 #endif
@@ -460,7 +462,7 @@ set_lang (pfile, lang)
 static int initialized = 0;
 
 static void
-initialize ()
+init ()
 {
 #ifdef HOST_EBCDIC
   /* For non-ASCII hosts, the cl_options array needs to be sorted at
@@ -485,7 +487,7 @@ cpp_create_reader (lang)
 
   /* Initialise this instance of the library if it hasn't been already.  */
   if (! initialized)
-    initialize ();
+    init ();
 
   CPP_OPTION (pfile, warn_import) = 1;
   CPP_OPTION (pfile, discard_comments) = 1;
@@ -667,7 +669,7 @@ static const struct builtin builtin_arra
 /* Subroutine of cpp_start_read; reads the builtins table above and
    enters the macros into the hash table.  */
 static void
-initialize_builtins (pfile)
+init_builtins (pfile)
      cpp_reader *pfile;
 {
   const struct builtin *b;
@@ -729,60 +731,9 @@ initialize_builtins (pfile)
 #undef CPLUS
 #undef builtin_array_end
 
-/* Another subroutine of cpp_start_read.  This one sets up to do
-   dependency-file output. */
-static void
-initialize_dependency_output (pfile)
-     cpp_reader *pfile;
-{
-  char *spec, *s, *output_file;
-
-  /* Either of two environment variables can specify output of deps.
-     Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
-     where OUTPUT_FILE is the file to write deps info to
-     and DEPS_TARGET is the target to mention in the deps.  */
-
-  if (CPP_OPTION (pfile, print_deps) == 0)
-    {
-      spec = getenv ("DEPENDENCIES_OUTPUT");
-      if (spec)
-	CPP_OPTION (pfile, print_deps) = 1;
-      else
-	{
-	  spec = getenv ("SUNPRO_DEPENDENCIES");
-	  if (spec)
-	    CPP_OPTION (pfile, print_deps) = 2;
-	  else
-	    return;
-	}
-
-      /* Find the space before the DEPS_TARGET, if there is one.  */
-      s = strchr (spec, ' ');
-      if (s)
-	{
-	  /* Let the caller perform MAKE quoting.  */
-	  deps_add_target (pfile->deps, s + 1, 0);
-	  output_file = (char *) xmalloc (s - spec + 1);
-	  memcpy (output_file, spec, s - spec);
-	  output_file[s - spec] = 0;
-	}
-      else
-	output_file = spec;
-
-      CPP_OPTION (pfile, deps_file) = output_file;
-      CPP_OPTION (pfile, print_deps_append) = 1;
-    }
-
-  /* Set the default target (if there is none already).  */
-  deps_add_default_target (pfile->deps, CPP_OPTION (pfile, in_fname));
-
-  if (CPP_OPTION (pfile, in_fname))
-    deps_add_dep (pfile->deps, CPP_OPTION (pfile, in_fname));
-}
-
 /* And another subroutine.  This one sets up the standard include path.  */
 static void
-initialize_standard_includes (pfile)
+init_standard_includes (pfile)
      cpp_reader *pfile;
 {
   char *path;
@@ -902,28 +853,30 @@ cpp_start_read (pfile, fname)
 {
   struct pending_option *p, *q;
 
-  /* -MG doesn't select the form of output and must be specified with one of
-     -M or -MM.  -MG doesn't make sense with -MD or -MMD since they don't
-     inhibit compilation.  */
-  if (CPP_OPTION (pfile, print_deps_missing_files)
-      && (CPP_OPTION (pfile, print_deps) == 0
-	  || !CPP_OPTION (pfile, no_output)))
+  /* Open the main input file.  This must be done early, so we have a
+     buffer to stand on.  */
+  if (CPP_OPTION (pfile, in_fname) == NULL
+      || *CPP_OPTION (pfile, in_fname) == 0)
     {
-      cpp_fatal (pfile, "-MG must be specified with one of -M or -MM");
-      return 0;
+      CPP_OPTION (pfile, in_fname) = fname;
+      if (CPP_OPTION (pfile, in_fname) == NULL)
+	CPP_OPTION (pfile, in_fname) = "";
     }
+  if (CPP_OPTION (pfile, out_fname) == NULL)
+    CPP_OPTION (pfile, out_fname) = "";
 
-  /* -Wtraditional is not useful in C++ mode.  */
-  if (CPP_OPTION (pfile, cplusplus))
-    CPP_OPTION (pfile, warn_traditional) = 0;
+  if (CPP_OPTION (pfile, print_deps))
+    {
+      /* Set the default target (if there is none already).  */
+      deps_add_default_target (pfile->deps, CPP_OPTION (pfile, in_fname));
 
-  /* Set this if it hasn't been set already. */
-  if (CPP_OPTION (pfile, user_label_prefix) == NULL)
-    CPP_OPTION (pfile, user_label_prefix) = USER_LABEL_PREFIX;
+      if (CPP_OPTION (pfile, in_fname))
+	deps_add_dep (pfile->deps, CPP_OPTION (pfile, in_fname));
+    }
 
   /* Set up the include search path now.  */
   if (! CPP_OPTION (pfile, no_standard_includes))
-    initialize_standard_includes (pfile);
+    init_standard_includes (pfile);
 
   merge_include_chains (pfile);
 
@@ -941,25 +894,11 @@ cpp_start_read (pfile, fname)
       fprintf (stderr, _("End of search list.\n"));
     }
 
-  /* Open the main input file.  This must be done early, so we have a
-     buffer to stand on.  */
-  if (CPP_OPTION (pfile, in_fname) == NULL
-      || *CPP_OPTION (pfile, in_fname) == 0)
-    {
-      CPP_OPTION (pfile, in_fname) = fname;
-      if (CPP_OPTION (pfile, in_fname) == NULL)
-	CPP_OPTION (pfile, in_fname) = "";
-    }
-  if (CPP_OPTION (pfile, out_fname) == NULL)
-    CPP_OPTION (pfile, out_fname) = "";
-
   if (!_cpp_read_file (pfile, fname))
     return 0;
 
-  initialize_dependency_output (pfile);
-
   /* Install __LINE__, etc.  */
-  initialize_builtins (pfile);
+  init_builtins (pfile);
 
   /* Do -U's, -D's and -A's in the order they were seen.  */
   p = CPP_OPTION (pfile, pending)->directive_head;
@@ -986,6 +925,40 @@ cpp_start_read (pfile, fname)
   return 1;
 }
 
+/* Outputs the dependency file.  */
+static void
+output_deps (pfile)
+     cpp_reader *pfile;
+{
+  /* Stream on which to print the dependency information.  */
+  FILE *deps_stream = 0;
+  const char *deps_mode = CPP_OPTION (pfile, print_deps_append) ? "a" : "w";
+
+  if (CPP_OPTION (pfile, deps_file) == 0)
+    deps_stream = stdout;
+  else
+    {
+      deps_stream = fopen (CPP_OPTION (pfile, deps_file), deps_mode);
+      if (deps_stream == 0)
+	{
+	  cpp_notice_from_errno (pfile, CPP_OPTION (pfile, deps_file));
+	  return;
+	}
+    }
+
+  deps_write (pfile->deps, deps_stream, 72);
+
+  if (CPP_OPTION (pfile, deps_phony_targets))
+    deps_phony_targets (pfile->deps, deps_stream);
+
+  /* Don't close stdout.  */
+  if (CPP_OPTION (pfile, deps_file))
+    {
+      if (ferror (deps_stream) || fclose (deps_stream))
+	cpp_fatal (pfile, "I/O error on dependency output");
+    }
+}
+
 /* This is called at the end of preprocessing.  It pops the
    last buffer and writes dependency output.  It should also
    clear macro definitions, such that you could call cpp_start_read
@@ -1003,34 +976,8 @@ cpp_finish (pfile)
 
   /* Don't write the deps file if preprocessing has failed.  */
   if (CPP_OPTION (pfile, print_deps) && pfile->errors == 0)
-    {
-      /* Stream on which to print the dependency information.  */
-      FILE *deps_stream = 0;
-      const char *deps_mode
-	= CPP_OPTION (pfile, print_deps_append) ? "a" : "w";
-      if (CPP_OPTION (pfile, deps_file) == 0)
-	deps_stream = stdout;
-      else
-	{
-	  deps_stream = fopen (CPP_OPTION (pfile, deps_file), deps_mode);
-	  if (deps_stream == 0)
-	    cpp_notice_from_errno (pfile, CPP_OPTION (pfile, deps_file));
-	}
-      if (deps_stream)
-	{
-	  deps_write (pfile->deps, deps_stream, 72);
-
-	  if (CPP_OPTION (pfile, deps_phony_targets))
-	    deps_phony_targets (pfile->deps, deps_stream);
+    output_deps (pfile);
 
-	  if (CPP_OPTION (pfile, deps_file))
-	    {
-	      if (ferror (deps_stream) || fclose (deps_stream) != 0)
-		cpp_fatal (pfile, "I/O error on output");
-	    }
-	}
-    }
-
   /* Report on headers that could use multiple include guards.  */
   if (CPP_OPTION (pfile, print_include_names))
     _cpp_report_missing_guards (pfile);
@@ -1078,10 +1025,9 @@ new_pending_directive (pend, text, handl
   DEF_OPT("H",                        0,      OPT_H)                          \
   DEF_OPT("I",                        no_dir, OPT_I)                          \
   DEF_OPT("M",                        0,      OPT_M)                          \
-  DEF_OPT("MD",                       no_fil, OPT_MD)                         \
+  DEF_OPT("MF",                       no_fil, OPT_MF)                         \
   DEF_OPT("MG",                       0,      OPT_MG)                         \
   DEF_OPT("MM",                       0,      OPT_MM)                         \
-  DEF_OPT("MMD",                      no_fil, OPT_MMD)                        \
   DEF_OPT("MP",                       0,      OPT_MP)                         \
   DEF_OPT("MQ",                       no_tgt, OPT_MQ)                         \
   DEF_OPT("MT",                       no_tgt, OPT_MT)                         \
@@ -1476,43 +1422,22 @@ cpp_handle_option (pfile, argc, argv)
 		}
 	  }
 	  break;
-	  /* The style of the choices here is a bit mixed.
-	     The chosen scheme is a hybrid of keeping all options in one string
-	     and specifying each option in a separate argument:
-	     -M|-MM|-MD file|-MMD file [-MG].  An alternative is:
-	     -M|-MM|-MD file|-MMD file|-MG|-MMG; or more concisely:
-	     -M[M][G][D file].  This is awkward to handle in specs, and is not
-	     as extensible.  */
-	  /* ??? -MG must be specified in addition to one of -M or -MM.
-	     This can be relaxed in the future without breaking anything.
-	     The converse isn't true.  */
 
-	  /* -MG isn't valid with -MD or -MMD.  This is checked for later.  */
 	case OPT_MG:
 	  CPP_OPTION (pfile, print_deps_missing_files) = 1;
 	  break;
 	case OPT_M:
-	case OPT_MD:
+	  CPP_OPTION (pfile, print_deps) = 2;
+	  break;
 	case OPT_MM:
-	case OPT_MMD:
-	  if (opt_code == OPT_M || opt_code == OPT_MD)
-	    CPP_OPTION (pfile, print_deps) = 2;
- 	  else
-	    CPP_OPTION (pfile, print_deps) = 1;
-
-	  /* For -MD and -MMD, write deps on file named by next arg.  */
-	  /* For -M and -MM, write deps on standard output and
-	     suppress the usual output.  */
-	  if (opt_code == OPT_MD || opt_code == OPT_MMD)
-	      CPP_OPTION (pfile, deps_file) = arg;
- 	  else
-	      CPP_OPTION (pfile, no_output) = 1;
+	  CPP_OPTION (pfile, print_deps) = 1;
 	  break;
-
+	case OPT_MF:
+	  CPP_OPTION (pfile, deps_file) = arg;
+	  break;
 	case OPT_MP:
 	  CPP_OPTION (pfile, deps_phony_targets) = 1;
 	  break;
-
 	case OPT_MQ:
 	case OPT_MT:
 	  /* Add a target.  -MQ quotes for Make.  */
@@ -1698,6 +1623,85 @@ opt_comp (const void *p1, const void *p2
 }
 #endif
 
+/* Set up dependency-file output. */
+static void
+init_dependency_output (pfile)
+     cpp_reader *pfile;
+{
+  char *spec, *s, *output_file;
+
+  /* Either of two environment variables can specify output of deps.
+     Its value is either "OUTPUT_FILE" or "OUTPUT_FILE DEPS_TARGET",
+     where OUTPUT_FILE is the file to write deps info to
+     and DEPS_TARGET is the target to mention in the deps.  */
+
+  if (CPP_OPTION (pfile, print_deps) == 0)
+    {
+      spec = getenv ("DEPENDENCIES_OUTPUT");
+      if (spec)
+	CPP_OPTION (pfile, print_deps) = 1;
+      else
+	{
+	  spec = getenv ("SUNPRO_DEPENDENCIES");
+	  if (spec)
+	    CPP_OPTION (pfile, print_deps) = 2;
+	  else
+	    return;
+	}
+
+      /* Find the space before the DEPS_TARGET, if there is one.  */
+      s = strchr (spec, ' ');
+      if (s)
+	{
+	  /* Let the caller perform MAKE quoting.  */
+	  deps_add_target (pfile->deps, s + 1, 0);
+	  output_file = (char *) xmalloc (s - spec + 1);
+	  memcpy (output_file, spec, s - spec);
+	  output_file[s - spec] = 0;
+	}
+      else
+	output_file = spec;
+
+      /* Command line overrides environment variables.  */
+      if (CPP_OPTION (pfile, deps_file) == 0)
+	CPP_OPTION (pfile, deps_file) = output_file;
+      CPP_OPTION (pfile, print_deps_append) = 1;
+    }
+
+  /* If dependencies go to standard output, we need to suppress
+     output.  The user may be requesting other stuff to stdout, with
+     -dM, -v etc.  We let them shoot themselves in the foot.  */
+  if (CPP_OPTION (pfile, deps_file) == 0)
+    CPP_OPTION (pfile, no_output) = 1;
+}
+
+/* Extra processing when all options are parsed, before the final
+   return from cpp_handle_options.  Consistency checks etc.  */
+static void
+check_options (pfile)
+     cpp_reader *pfile;
+{
+  /* -Wtraditional is not useful in C++ mode.  */
+  if (CPP_OPTION (pfile, cplusplus))
+    CPP_OPTION (pfile, warn_traditional) = 0;
+
+  /* Set this if it hasn't been set already. */
+  if (CPP_OPTION (pfile, user_label_prefix) == NULL)
+    CPP_OPTION (pfile, user_label_prefix) = USER_LABEL_PREFIX;
+
+  /* We need to do this before returning from cpp_handle_options, as
+     cppmain.c relies on the no_output option to set its callbacks
+     before calling cpp_start_read.  */
+  init_dependency_output (pfile);
+
+  /* -MG doesn't select the form of output and must be specified with
+     one of -M or -MM.  -MG doesn't make sense unless preprocessed
+     output (and compilation) is inhibited.  */
+  if (CPP_OPTION (pfile, print_deps_missing_files)
+      && CPP_OPTION (pfile, print_deps) == 0)
+    cpp_fatal (pfile, "-MG must be specified with one of -M or -MM");
+}
+
 /* Handle command-line options in (argc, argv).
    Can be called multiple times, to handle multiple sets of options.
    Returns if an unrecognized option is seen.
@@ -1715,8 +1719,11 @@ cpp_handle_options (pfile, argc, argv)
     {
       strings_processed = cpp_handle_option (pfile, argc - i, argv + i);
       if (strings_processed == 0)
-	break;
+	return i;
     }
+
+  /* Called when all options have been processed.  */
+  check_options (pfile);
   return i;
 }
 
@@ -1786,9 +1793,13 @@ Switches:\n\
   fputs (_("\
   -M                        Generate make dependencies\n\
   -MM                       As -M, but ignore system header files\n\
-  -MD                       As -M, but put output in a .d file\n\
-  -MMD                      As -MD, but ignore system header files\n\
+  -MF <file>                Write dependency output to the given file\n\
   -MG                       Treat missing header file as generated files\n\
+"), stdout);
+  fputs (_("\
+  -MP			    Generate phony targets for all headers\n\
+  -MQ <target>              Add a MAKE-quoted target\n\
+  -MT <target>              Add an unquoted target\n\
   -g3                       Include #define and #undef directives in the output\n\
 "), stdout);
   fputs (_("\
Index: gcc.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/gcc.c,v
retrieving revision 1.193
diff -u -p -r1.193 gcc.c
--- gcc.c	2001/01/06 00:15:29	1.193
+++ gcc.c	2001/01/06 13:49:05
@@ -584,7 +584,7 @@ static const char *cpp_options =
 "%{C:%{!E:%eGNU C does not support -C without using -E}}\
  %{std*} %{nostdinc*}\
  %{C} %{v} %{I*} %{P} %{$} %I\
- %{M} %{MM} %{MD:-MD %b.d} %{MMD:-MMD %b.d} %{MG} %{MP} %{MQ} %{MT}\
+ %{M} %{MM} %{MD:-M -MF %b.d} %{MMD:-MM -MF %b.d} %{MG} %{MP} %{MQ} %{MT}\
  %{!no-gcc:-D__GNUC__=%v1 -D__GNUC_MINOR__=%v2 -D__GNUC_PATCHLEVEL__=%v3}\
  %{!undef:%{!ansi:%{!std=*:%p}%{std=gnu*:%p}} %P} %{trigraphs}\
  %c %{Os:-D__OPTIMIZE_SIZE__} %{O*:%{!O0:-D__OPTIMIZE__}}\


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]