public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc r14-4683] PR modula2/111756: Re-building all-gcc after source changes fails to link
@ 2023-10-17 13:12 Gaius Mulley
  0 siblings, 0 replies; only message in thread
From: Gaius Mulley @ 2023-10-17 13:12 UTC (permalink / raw)
  To: gcc-cvs

https://gcc.gnu.org/g:ef6696af08a888b53e0e21b17c0a1f87ffdfc3c6

commit r14-4683-gef6696af08a888b53e0e21b17c0a1f87ffdfc3c6
Author: Gaius Mulley <gaiusmod2@gmail.com>
Date:   Tue Oct 17 14:11:24 2023 +0100

    PR modula2/111756: Re-building all-gcc after source changes fails to link
    
    When having modula-2 enabled in a development tree and there are any
    changes that trigger rebuilds in m2/ doing a 'make all-gcc' in the
    build directory might fail due to lack of dependency tracking.  This
    patch introduces build dependencies into gcc/m2/Make-lang.in using -M*
    options.  The patch also introduces all -M* options to cc1gm2 and gm2.
    
    gcc/m2/ChangeLog:
    
            PR modula2/111756
            * Make-lang.in (CM2DEP): New define conditionally set if
            ($(CXXDEPMODE),depmode=gcc3).
            (GM2_1): Use $(CM2DEP).
            (m2/gm2-gcc/%.o): Ensure $(@D)/$(DEPDIR) is created.
            Add $(CM2DEP) to the $(COMPILER) command and use $(POSTCOMPILE).
            (m2/gm2-gcc/m2configure.o): Ditto.
            (m2/gm2-lang.o): Ditto.
            (m2/m2pp.o): Ditto.
            (m2/gm2-gcc/rtegraph.o): Ditto.
            (m2/mc-boot/$(SRC_PREFIX)%.o): Ditto.
            (m2/mc-boot-ch/$(SRC_PREFIX)%.o): Ditto.
            (m2/mc-boot-ch/$(SRC_PREFIX)%.o): Ditto.
            (m2/mc-boot/main.o): Ditto.
            (mcflex.o): Ditto.
            (m2/gm2-libs-boot/M2RTS.o): Ditto.
            (m2/gm2-libs-boot/%.o): Ditto.
            (m2/gm2-libs-boot/%.o): Ditto.
            (m2/gm2-libs-boot/RTcodummy.o): Ditto.
            (m2/gm2-libs-boot/RTintdummy.o): Ditto.
            (m2/gm2-libs-boot/wrapc.o): Ditto.
            (m2/gm2-libs-boot/UnixArgs.o): Ditto.
            (m2/gm2-libs-boot/choosetemp.o): Ditto.
            (m2/gm2-libs-boot/errno.o): Ditto.
            (m2/gm2-libs-boot/dtoa.o): Ditto.
            (m2/gm2-libs-boot/ldtoa.o): Ditto.
            (m2/gm2-libs-boot/termios.o): Ditto.
            (m2/gm2-libs-boot/SysExceptions.o): Ditto.
            (m2/gm2-libs-boot/SysStorage.o): Ditto.
            (m2/gm2-compiler-boot/M2GCCDeclare.o): Ditto.
            (m2/gm2-compiler-boot/M2Error.o): Ditto.
            (m2/gm2-compiler-boot/%.o): Ditto.
            (m2/gm2-compiler-boot/%.o): Ditto.
            (m2/gm2-compiler-boot/m2flex.o): Ditto.
            (m2/gm2-compiler/%.o): Ditto.
            (m2/gm2-compiler/m2flex.o): Ditto.
            (m2/gm2-libs-iso/%.o): Ditto.
            (m2/gm2-libs/%.o): Ditto.
            (m2/gm2-libs/%.o): Ditto.
            (m2/gm2-libs/choosetemp.o): Ditto.
            (m2/boot-bin/mklink$(exeext)): Ditto.
            (m2/pge-boot/%.o): Ditto.
            (m2/pge-boot/%.o): Ditto.
            (m2/gm2-compiler/%.o): Ensure $(@D)/$(DEPDIR) is created and use
            $(POSTCOMPILE).
            (m2/gm2-compiler/%.o): Ditto.
            (m2/gm2-libs-iso/%.o): Ditto.
            (m2/gm2-libs/%.o): Ditto.
            * README: Purge out of date info.
            * gm2-compiler/M2Comp.mod (MakeSaveTempsFileNameExt): Import.
            (OnExitDelete): Import.
            (GetModuleDefImportStatementList): Import.
            (GetModuleModImportStatementList): Import.
            (GetImportModule): Import.
            (IsImportStatement): Import.
            (IsImport): Import.
            (GetImportStatementList): Import.
            (File): Import.
            (Close): Import.
            (EOF): Import.
            (IsNoError): Import.
            (WriteLine): Import.
            (WriteChar): Import.
            (FlushOutErr): Import.
            (WriteS): Import.
            (OpenToRead): Import.
            (OpenToWrite): Import.
            (ReadS): Import.
            (WriteS): Import.
            (GetM): Import.
            (GetMM): Import.
            (GetDepTarget): Import.
            (GetMF): Import.
            (GetMP): Import.
            (GetObj): Import.
            (GetMD): Import.
            (GetMMD): Import.
            (GenerateDefDependency): New procedure.
            (GenerateDependenciesFromImport): New procedure.
            (GenerateDependenciesFromList): New procedure.
            (GenerateDependencies): New procedure.
            (Compile): Re-write.
            (compile): Re-format.
            (CreateFileStem): New procedure function.
            (DoPass0): Re-write.
            (IsLibrary): New procedure function.
            (IsUnique): New procedure function.
            (Append): New procedure.
            (MergeDep): New procedure.
            (GetRuleTarget): New procedure function.
            (ReadDepContents): New procedure function.
            (WriteDep): New procedure.
            (WritePhonyDep): New procedure.
            (WriteDepContents): New procedure.
            (CreateDepFilename): New procedure function.
            (Pass0CheckDef): New procedure function.
            (Pass0CheckMod): New procedure function.
            (DoPass0): Re-write.
            (DepContent): New variable.
            (DepOutput): New variable.
            (BaseName): New procedure function.
            * gm2-compiler/M2GCCDeclare.mod (PrintTerse): Handle IsImport.
            Replace IsGnuAsmVolatile with IsGnuAsm.
            * gm2-compiler/M2Options.def (EXPORT QUALIFIED): Remove list.
            (SetM): New procedure.
            (GetM): New procedure function.
            (SetMM): New procedure.
            (GetMM): New procedure function.
            (SetMF): New procedure.
            (GetMF): New procedure function.
            (SetPPOnly): New procedure.
            (GetB): New procedure function.
            (SetMD): New procedure.
            (GetMD): New procedure function.
            (SetMMD): New procedure.
            (GetMMD): New procedure function.
            (SetMQ): New procedure.
            (SetMT): New procedure.
            (GetMT): New procedure function.
            (GetDepTarget): New procedure function.
            (SetMP): New procedure.
            (GetMP): New procedure function.
            (SetObj): New procedure.
            (SetSaveTempsDir): New procedure.
            * gm2-compiler/M2Options.mod (SetM): New procedure.
            (GetM): New procedure function.
            (SetMM): New procedure.
            (GetMM): New procedure function.
            (SetMF): New procedure.
            (GetMF): New procedure function.
            (SetPPOnly): New procedure.
            (GetB): New procedure function.
            (SetMD): New procedure.
            (GetMD): New procedure function.
            (SetMMD): New procedure.
            (GetMMD): New procedure function.
            (SetMQ): New procedure.
            (SetMT): New procedure.
            (GetMT): New procedure function.
            (GetDepTarget): New procedure function.
            (SetMP): New procedure.
            (GetMP): New procedure function.
            (SetObj): New procedure.
            (SetSaveTempsDir): New procedure.
            * gm2-compiler/M2Preprocess.def (PreprocessModule): New parameters
            topSource and outputDep.  Re-write.
            (MakeSaveTempsFileNameExt): New procedure function.
            (OnExitDelete): New procedure function.
            * gm2-compiler/M2Preprocess.mod (GetM): Import.
            (GetMM): Import.
            (OnExitDelete): Add debugging message.
            (RemoveFile): Add debugging message.
            (BaseName): Remove.
            (BuildCommandLineExecute): New procedure function.
            * gm2-compiler/M2Search.def (SetDefExtension): Remove unnecessary
            spacing.
            * gm2-compiler/SymbolTable.mod (GetSymName): Handle ImportSym and
            ImportStatementSym.
            * gm2-gcc/m2options.h (M2Options_SetMD): New function.
            (M2Options_GetMD): New function.
            (M2Options_SetMMD): New function.
            (M2Options_GetMMD): New function.
            (M2Options_SetM): New function.
            (M2Options_GetM): New function.
            (M2Options_SetMM): New function.
            (M2Options_GetMM): New function.
            (M2Options_GetMQ): New function.
            (M2Options_SetMF): New function.
            (M2Options_GetMF): New function.
            (M2Options_SetMT): New function.
            (M2Options_SetMP): New function.
            (M2Options_GetMP): New function.
            (M2Options_GetDepTarget): New function.
            * gm2-lang.cc (gm2_langhook_init): Correct comment case.
            (gm2_langhook_init_options): Add case OPT_M and
            OPT_MM.
            (gm2_langhook_post_options): Add case OPT_MF, OPT_MT,
            OPT_MD and OPT_MMD.
            * lang-specs.h (M2CPP): Pass though MF option.
            (MDMMD): New define.  Add MDMMD to "@modula-2".
    
    Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>

Diff:
---
 gcc/m2/Make-lang.in                  | 201 +++++---
 gcc/m2/README                        |  21 -
 gcc/m2/gm2-compiler/M2Comp.mod       | 876 ++++++++++++++++++++++++++++-------
 gcc/m2/gm2-compiler/M2GCCDeclare.mod |  11 +-
 gcc/m2/gm2-compiler/M2Options.def    | 171 ++++---
 gcc/m2/gm2-compiler/M2Options.mod    | 227 +++++++--
 gcc/m2/gm2-compiler/M2Preprocess.def |  25 +-
 gcc/m2/gm2-compiler/M2Preprocess.mod | 254 +++++-----
 gcc/m2/gm2-compiler/M2Search.def     |   2 -
 gcc/m2/gm2-compiler/SymbolTable.mod  |   4 +-
 gcc/m2/gm2-gcc/m2options.h           |  19 +-
 gcc/m2/gm2-lang.cc                   |  66 ++-
 gcc/m2/lang-specs.h                  |  10 +-
 13 files changed, 1382 insertions(+), 505 deletions(-)

diff --git a/gcc/m2/Make-lang.in b/gcc/m2/Make-lang.in
index 61ad1646701f..d826d4cc423b 100644
--- a/gcc/m2/Make-lang.in
+++ b/gcc/m2/Make-lang.in
@@ -27,7 +27,14 @@ GM2_CROSS_NAME = `echo gm2|sed '$(program_transform_cross_name)'`
 
 M2_MAINTAINER = no
 
-GM2_1 = ./gm2 -B./m2/stage1 -g -fm2-g
+# CM2DEP must match the COMPILE and POSTCOMPILE defines in gcc/Make-lang.in
+ifeq ($(CXXDEPMODE),depmode=gcc3)
+CM2DEP=-MT $@ -MMD -MP -MF $(@D)/$(DEPDIR)/$(*F).TPo
+else
+CM2DEP=
+endif
+
+GM2_1 = ./gm2 -B./m2/stage1 -g -fm2-g $(CM2DEP)
 
 GM2_FOR_TARGET = $(STAGE_CC_WRAPPER) ./gm2 -B./ -B$(build_tooldir)/bin/ -L$(objdir)/../ld $(TFLAGS)
 
@@ -582,35 +589,40 @@ GCC_HEADER_DEPENDENCIES_FOR_M2 = $(BUILD-BOOT-H) $(TIMEVAR_H) m2/gm2config.h $(C
         $(generated_files) insn-attr-common.h
 
 m2/gm2-gcc/%.o: $(srcdir)/m2/gm2-gcc/%.cc $(GCC_HEADER_DEPENDENCIES_FOR_M2)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(COMPILER) -c -g $(ALL_COMPILERFLAGS) \
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(COMPILER) $(CM2DEP) -c -g $(ALL_COMPILERFLAGS) \
              $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+	$(POSTCOMPILE)
 
 m2/gm2-gcc/m2configure.o: $(srcdir)/m2/gm2-gcc/m2configure.cc \
                $(SYSTEM_H) $(GCC_H) $(CONFIG_H) \
                m2/gm2config.h $(TARGET_H) $(PLUGIN_HEADERS) \
                $(generated_files) $(C_TREE_H) insn-attr-common.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(COMPILER) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(COMPILER) $(CM2DEP) $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
          $(DRIVER_DEFINES) \
 		-DLIBSUBDIR=\"$(libsubdir)\" \
                 -DPREFIX=\"$(prefix)\" \
                 -c $(srcdir)/m2/gm2-gcc/m2configure.cc $(OUTPUT_OPTION)
+	$(POSTCOMPILE)
 
 m2/gm2-lang.o: $(srcdir)/m2/gm2-lang.cc gt-m2-gm2-lang.h $(GCC_HEADER_DEPENDENCIES_FOR_M2)
-	$(COMPILER) -c -g $(GM2GCC) $(ALL_COMPILERFLAGS) \
+	$(COMPILER) $(CM2DEP) -c -g $(GM2GCC) $(ALL_COMPILERFLAGS) \
 	    -DLIBSUBDIR=\"$(libsubdir)\" \
             $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+	$(POSTCOMPILE)
 
 m2/m2pp.o : $(srcdir)/m2/m2pp.cc $(GCC_HEADER_DEPENDENCIES_FOR_M2)
-	$(COMPILER) -c -g -DGM2 $(ALL_COMPILERFLAGS) \
+	$(COMPILER) $(CM2DEP) -c -g -DGM2 $(ALL_COMPILERFLAGS) \
             $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+	$(POSTCOMPILE)
 
 m2/gm2-gcc/rtegraph.o: $(srcdir)/m2/gm2-gcc/rtegraph.cc $(GCC_HEADER_DEPENDENCIES_FOR_M2) \
                        gt-m2-rtegraph.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(COMPILER) -c -g $(GM2GCC) $(ALL_COMPILERFLAGS) \
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(COMPILER) $(CM2DEP) -c -g $(GM2GCC) $(ALL_COMPILERFLAGS) \
             $(ALL_CPPFLAGS) $(INCLUDES) $< $(OUTPUT_OPTION)
+	$(POSTCOMPILE)
 
 m2/gm2-gcc/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-gcc/%.def $(MCDEPS)
 	-test -d $(@D) || $(mkinstalldirs) $(@D)
@@ -1388,126 +1400,150 @@ m2/boot-bin/mc$(exeext): $(BUILD-MC-BOOT-O) $(BUILD-MC-INTERFACE-O) \
          mcflex.o m2/gm2-libs-boot/RTcodummy.o -lm
 
 m2/mc-boot/$(SRC_PREFIX)%.o: m2/mc-boot/$(SRC_PREFIX)%.cc m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -g -c -I. -I$(srcdir)/m2/mc-boot-ch -I$(srcdir)/m2/mc-boot -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) $(CXXFLAGS) $(GM2_PICFLAGS) -g -c -I. -I$(srcdir)/m2/mc-boot-ch -I$(srcdir)/m2/mc-boot -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/mc-boot-ch/$(SRC_PREFIX)%.o: m2/mc-boot-ch/$(SRC_PREFIX)%.c m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) $(CXXFLAGS) $(GM2_PICFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@
+	$(POSTCOMPILE)
 
 m2/mc-boot-ch/$(SRC_PREFIX)%.o: m2/mc-boot-ch/$(SRC_PREFIX)%.cc m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) $(CXXFLAGS) $(GM2_PICFLAGS) -DHAVE_CONFIG_H -g -c -I. -Im2/gm2-libs -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) -Im2/gm2-libs $< -o $@
+	$(POSTCOMPILE)
 
 m2/mc-boot/main.o: $(M2LINK) $(srcdir)/m2/init/mcinit
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	unset CC ; $(M2LINK) -s --langc++ --exit --name m2/mc-boot/main.cc $(srcdir)/m2/init/mcinit
-	$(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) -g -c -I. -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) m2/mc-boot/main.cc -o $@
+	$(CXX) $(CM2DEP) $(CXXFLAGS) $(GM2_PICFLAGS) -g -c -I. -I$(srcdir)/../include -I$(srcdir) $(INCLUDES) m2/mc-boot/main.cc -o $@
+	$(POSTCOMPILE)
 
 mcflex.o: mcflex.c m2/gm2-libs/gm2-libs-host.h
-	$(CC) $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2/mc -g -c $< -o $@   # remember that mcReserved.h is copied into m2/mc
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CC) $(CM2DEP) $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2/mc -g -c $< -o $@   # remember that mcReserved.h is copied into m2/mc
+	$(POSTCOMPILE)
 
 mcflex.c: $(srcdir)/m2/mc/mc.flex
 	flex -t $< > $@
 
 m2/gm2-libs-boot/M2RTS.o: $(srcdir)/m2/gm2-libs/M2RTS.mod $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(MC) --suppress-noreturn -o=m2/gm2-libs-boot/M2RTS.c $(srcdir)/m2/gm2-libs/M2RTS.mod
-	$(COMPILER) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/M2RTS.c -o $@
+	$(COMPILER) $(CM2DEP) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/M2RTS.c -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/%.o: $(srcdir)/m2/gm2-libs-boot/%.mod $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(MC) -o=m2/gm2-libs-boot/$*.c $(srcdir)/m2/gm2-libs-boot/$*.mod
-	$(COMPILER) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) $(MCINCLUDES) m2/gm2-libs-boot/$*.c -o $@
+	$(COMPILER) $(CM2DEP) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) $(MCINCLUDES) m2/gm2-libs-boot/$*.c -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/%.o: $(srcdir)/m2/gm2-libs/%.mod $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(MC) -o=m2/gm2-libs-boot/$*.c $(srcdir)/m2/gm2-libs/$*.mod
-	$(COMPILER) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/$*.c -o $@
+	$(COMPILER) $(CM2DEP) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) m2/gm2-libs-boot/$*.c -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-libs/%.def $(MCDEPS)
 	-test -d $(@D) || $(mkinstalldirs) $(@D)
 	$(MC) -o=$@ $(srcdir)/m2/gm2-libs/$*.def
 
 m2/gm2-libs-boot/RTcodummy.o: $(srcdir)/m2/gm2-libs-ch/RTcodummy.c m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/RTintdummy.o: $(srcdir)/m2/gm2-libs-ch/RTintdummy.c m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/wrapc.o: $(srcdir)/m2/gm2-libs-ch/wrapc.c m2/gm2-libs-boot/$(SRC_PREFIX)wrapc.h m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c -DHAVE_CONFIG_H $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libs $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c -DHAVE_CONFIG_H $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libs $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/UnixArgs.o: $(srcdir)/m2/gm2-libs-ch/UnixArgs.cc m2/gm2-libs-boot/$(SRC_PREFIX)UnixArgs.h m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c -DIN_GCC $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/choosetemp.o: m2/gm2-libs-ch/choosetemp.c m2/gm2-libiberty/Gchoosetemp.h m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libiberty -I$(srcdir)/m2/gm2-libiberty/ $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libiberty -I$(srcdir)/m2/gm2-libiberty/ $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/errno.o: $(srcdir)/m2/gm2-libs-ch/errno.c m2/gm2-libs-boot/$(SRC_PREFIX)errno.h m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/dtoa.o: $(srcdir)/m2/gm2-libs-ch/dtoa.cc m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/ldtoa.o: $(srcdir)/m2/gm2-libs-ch/ldtoa.cc m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/termios.o: $(srcdir)/m2/gm2-libs-ch/termios.c $(BUILD-LIBS-BOOT-H) m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/SysExceptions.o: $(srcdir)/m2/gm2-libs-ch/SysExceptions.c \
                                   m2/gm2-libs-boot/$(SRC_PREFIX)SysExceptions.h m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/SysStorage.o: $(srcdir)/m2/gm2-libs/SysStorage.mod $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(MC) -o=m2/gm2-libs-boot/SysStorage.c $(srcdir)/m2/gm2-libs/SysStorage.mod
-	$(COMPILER) -DIN_GCC -c $(CFLAGS) $(GM2_PICFLAGS) \
+	$(COMPILER) $(CM2DEP) -DIN_GCC -c $(CFLAGS) $(GM2_PICFLAGS) \
           -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(MCINCLUDES) $(INCLUDES) \
           m2/gm2-libs-boot/SysStorage.c -o m2/gm2-libs-boot/SysStorage.o
+	$(POSTCOMPILE)
 
 m2/gm2-compiler-boot/M2GCCDeclare.o: $(srcdir)/m2/gm2-compiler/M2GCCDeclare.mod $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(MC) --extended-opaque -o=m2/gm2-compiler-boot/M2GCCDeclare.c $<
-	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
+	$(COMPILER) $(CM2DEP) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
             -I. -I$(srcdir)/../include -I$(srcdir) \
             -I. -Im2/gm2-libs-boot -Im2/gm2-compiler-boot \
             -I$(srcdir)/m2/gm2-libiberty $(MCINCLUDES) $(INCLUDES) m2/gm2-compiler-boot/M2GCCDeclare.c -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-compiler-boot/M2Error.o: $(srcdir)/m2/gm2-compiler/M2Error.mod $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(MC) --extended-opaque -o=m2/gm2-compiler-boot/M2Error.c $<
-	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
+	$(COMPILER) $(CM2DEP) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
             -I. -I$(srcdir)/../include -I$(srcdir) \
             -I. -Im2/gm2-libs-boot -Im2/gm2-compiler-boot \
             -I$(srcdir)/m2/gm2-libiberty $(MCINCLUDES) $(INCLUDES) m2/gm2-compiler-boot/M2Error.c -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-compiler-boot/%.o: $(srcdir)/m2/gm2-compiler/%.mod $(BUILD-BOOT-H) $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(MC) -o=m2/gm2-compiler-boot/$*.c $(srcdir)/m2/gm2-compiler/$*.mod
-	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
+	$(COMPILER) $(CM2DEP) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
             -I. -I$(srcdir)/../include -I$(srcdir) \
             -I. -Im2/gm2-libs-boot -Im2/gm2-compiler-boot -Im2/gm2-libiberty \
             -I$(srcdir)/m2/gm2-libiberty $(MCINCLUDES) $(INCLUDES) m2/gm2-compiler-boot/$*.c -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-compiler-boot/%.o: m2/gm2-compiler-boot/%.mod $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(MC) -o=m2/gm2-compiler-boot/$*.c m2/gm2-compiler-boot/$*.mod
-	$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
+	$(COMPILER) $(CM2DEP) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(GM2GCC) \
             -I. -I$(srcdir)/../include -I$(srcdir) \
             -I. -Im2/gm2-libs-boot -Im2/gm2-compiler-boot \
             -I$(srcdir)/m2/gm2-libiberty $(MCINCLUDES) $(INCLUDES) m2/gm2-compiler-boot/$*.c -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-compiler-boot/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-compiler/%.def $(MCDEPS)
 	-test -d $(@D) || $(mkinstalldirs) $(@D)
@@ -1516,10 +1552,11 @@ m2/gm2-compiler-boot/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-compiler/%.def $(MCDEPS)
 m2/gm2-compiler-boot/m2flex.o: m2/gm2-compiler/m2flex.c $(BUILD-BOOT-H) $(TIMEVAR_H) \
         $(BUILD-LIBS-BOOT-H)  m2/gm2-compiler-boot/$(SRC_PREFIX)NameKey.h \
         $(CONFIG_H) m2/gm2config.h $(TARGET_H) $(PLUGIN_HEADERS)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(COMPILER) -c -g $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(COMPILER) $(CM2DEP) -c -g $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
           $(GM2GCC) $(INCLUDES) -I$(srcdir)/m2 \
           -Im2 -Im2/gm2-compiler-boot -Im2/gm2-libs-boot $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-compiler/m2flex.c: $(srcdir)/m2/m2.flex $(TIMEVAR_H) insn-attr-common.h
 	-test -d $(@D) || $(mkinstalldirs) $(@D)
@@ -1532,25 +1569,30 @@ m2/gm2-libiberty/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-libiberty/%.def $(MCDEPS)
 # The rules to build objects in gm2-compiler and gm2-libs directories.
 
 m2/gm2-compiler/%.o: $(srcdir)/m2/gm2-compiler/%.mod
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(GM2_1) $(GM2_FLAGS) -c -I$(srcdir)/m2/gm2-compiler -I$(srcdir)/m2/gm2-libs -I$(srcdir)/m2/gm2-gcc -I$(srcdir)/m2/gm2-libiberty $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-compiler/m2flex.o: m2/gm2-compiler/m2flex.c m2/gm2-libs/gm2-libs-host.h $(TIMEVAR_H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(COMPILER) -c -g $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(COMPILER) $(CM2DEP) -c -g $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(INCLUDES) \
           $(GM2GCC) -Im2/gm2-compiler-boot -Im2/gm2-libs-boot $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-compiler/%.o: m2/gm2-compiler/%.mod
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(GM2_1) $(GM2_FLAGS) -c -I$(srcdir)/m2/gm2-compiler -I$(srcdir)/m2/gm2-libs -I$(srcdir)/m2/gm2-gcc -I$(srcdir)/m2/gm2-libiberty $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-iso/%.o: $(srcdir)/m2/gm2-libs-iso/%.c m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -DBUILD_GM2_LIBS_TARGET -DBUILD_GM2_LIBS -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -DBUILD_GM2_LIBS_TARGET -DBUILD_GM2_LIBS -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-iso/%.o: $(srcdir)/m2/gm2-libs-iso/%.mod
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(GM2_1) $(GM2_ISO_FLAGS) -c -B./ -Im2/gm2-libs-iso:$(srcdir)/m2/gm2-libs-iso -I$(srcdir)/m2/gm2-libs $< -o $@
+	$(POSTCOMPILE)
 
 
 # We build the cc1gm2$(exeext) from the boot stage and then proceed to build it
@@ -1643,20 +1685,24 @@ m2/gm2-libs/libgm2.a: build-compiler gm2$(exeext) $(BUILD-LIBS)
 	$(RANLIB) $@
 
 m2/gm2-libs/%.o: $(srcdir)/m2/gm2-libs/%.mod $(MCDEPS) $(BUILD-BOOT-H)
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
 	$(GM2_1) -c $(GM2_FLAGS) -Im2/gm2-libs -I$(srcdir)/m2/gm2-libs -I$(srcdir)/m2/gm2-libs-iso $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs/%.o: $(srcdir)/m2/gm2-libs-ch/%.c m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -DBUILD_GM2_LIBS -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -DBUILD_GM2_LIBS -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs/%.o: $(srcdir)/m2/gm2-libs-ch/%.cc m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs/choosetemp.o: m2/gm2-libs-ch/choosetemp.c m2/gm2-libiberty/Gchoosetemp.h m2/gm2-libs/gm2-libs-host.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libiberty -I$(srcdir)/m2/gm2-libiberty/ $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) -c $(CFLAGS) $(GM2_PICFLAGS) -Im2/gm2-libs -I$(srcdir)/m2 -Im2 -I. -Im2/gm2-libs-boot -Im2/gm2-libiberty -I$(srcdir)/m2/gm2-libiberty/ $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-libs-boot/libgm2.a: m2/boot-bin/mc$(exeext) $(BUILD-LIBS-BOOT)
 	-test -d $(@D) || $(mkinstalldirs) $(@D)
@@ -1675,8 +1721,9 @@ m2/gm2-compiler-boot/gm2.a: m2/boot-bin/mc$(exeext) m2/boot-bin/mklink$(exeext)
 m2/gm2-compiler-boot/gm2.a: m2/boot-bin/mc$(exeext)
 
 m2/boot-bin/mklink$(exeext): $(srcdir)/m2/tools-src/mklink.c
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) $(CFLAGS) $(LDFLAGS) -I$(srcdir)/m2 -Im2/gm2-libs-boot -Im2/gm2-compiler-boot -I$(srcdir)/m2/mc-boot-ch $(INCLUDES) $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) $(CFLAGS) $(LDFLAGS) -I$(srcdir)/m2 -Im2/gm2-libs-boot -Im2/gm2-compiler-boot -I$(srcdir)/m2/mc-boot-ch $(INCLUDES) $< -o $@
+	$(POSTCOMPILE)
 
 m2/gm2-compiler-boot/$(SRC_PREFIX)%.h: $(srcdir)/m2/gm2-compiler-boot/%.def $(MCDEPS)
 	-test -d $(@D) || $(mkinstalldirs) $(@D)
@@ -1755,12 +1802,14 @@ ifeq ($(M2_MAINTAINER),yes)
 include m2/Make-maintainer
 else
 m2/pge-boot/%.o: m2/pge-boot/%.c m2/gm2-libs/gm2-libs-host.h m2/gm2config.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) $(CFLAGS) $(GM2_PICFLAGS) $(INCLUDES) -I$(srcdir)/m2/pge-boot -Im2/gm2-libs -g -c $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) $(CFLAGS) $(GM2_PICFLAGS) $(INCLUDES) -I$(srcdir)/m2/pge-boot -Im2/gm2-libs -g -c $< -o $@
+	$(POSTCOMPILE)
 
 m2/pge-boot/%.o: m2/pge-boot/%.cc m2/gm2-libs/gm2-libs-host.h m2/gm2config.h
-	-test -d $(@D) || $(mkinstalldirs) $(@D)
-	$(CXX) $(CXXFLAGS) $(GM2_PICFLAGS) $(INCLUDES) -I$(srcdir)/m2/pge-boot -Im2/gm2-libs -g -c $< -o $@
+	-test -d $(@D)/$(DEPDIR) || $(mkinstalldirs) $(@D)/$(DEPDIR)
+	$(CXX) $(CM2DEP) $(CXXFLAGS) $(GM2_PICFLAGS) $(INCLUDES) -I$(srcdir)/m2/pge-boot -Im2/gm2-libs -g -c $< -o $@
+	$(POSTCOMPILE)
 
 $(PGE): $(BUILD-PGE-O)
 	+$(LINKER) $(ALL_LINKERFLAGS) $(LDFLAGS) -o $@ $(BUILD-PGE-O) -lm
diff --git a/gcc/m2/README b/gcc/m2/README
index 9de9e4fbf548..9cb87724d318 100644
--- a/gcc/m2/README
+++ b/gcc/m2/README
@@ -1,25 +1,4 @@
 
-Building GNU Modula-2
-=====================
-
-Please see the GCC documentation (gcc.texi) and section
-(Installing GCC).
-
-Regression testing GM2
-======================
-
-   cd host-build ; make check-m2
-
-runs all regression tests.
-
-Stress testing GM2
-==================
-
-   cd host-build/gcc ; make gm2.paranoid
-
-builds gm2 using itself and then compiles each module with both
-versions of gm2 comparing the emitted assembler code.
-
 Contributing to GNU Modula-2
 ============================
 
diff --git a/gcc/m2/gm2-compiler/M2Comp.mod b/gcc/m2/gm2-compiler/M2Comp.mod
index e33363e9f834..0ce8510ca76d 100644
--- a/gcc/m2/gm2-compiler/M2Comp.mod
+++ b/gcc/m2/gm2-compiler/M2Comp.mod
@@ -22,26 +22,29 @@ along with GNU Modula-2; see the file COPYING3.  If not see
 IMPLEMENTATION MODULE M2Comp ;
 
 
-FROM M2Options IMPORT PPonly, Statistics, Quiet, WholeProgram,
-                      ExtendedOpaque, GenModuleList ;
-
-FROM M2Pass IMPORT SetPassToPass0, SetPassToPass1, SetPassToPass2, SetPassToPassC, SetPassToPass3,
-                   SetPassToNoPass, SetPassToPassHidden ;
+FROM M2Pass IMPORT SetPassToPass0, SetPassToPass1, SetPassToPass2, SetPassToPassC,
+                   SetPassToPass3, SetPassToNoPass, SetPassToPassHidden ;
 
 FROM M2Reserved IMPORT toktype ;
 FROM M2Search IMPORT FindSourceDefFile, FindSourceModFile ;
 FROM M2Code IMPORT Code ;
-FROM M2LexBuf IMPORT OpenSource, CloseSource, ResetForNewPass, currenttoken, GetToken, ReInitialize, currentstring, GetTokenNo ;
+
+FROM M2LexBuf IMPORT OpenSource, CloseSource, ResetForNewPass, currenttoken, GetToken,
+                     ReInitialize, currentstring, GetTokenNo ;
+
 FROM M2FileName IMPORT CalculateFileName ;
-FROM M2Preprocess IMPORT PreprocessModule ;
+FROM M2Preprocess IMPORT PreprocessModule, MakeSaveTempsFileNameExt, OnExitDelete ;
 FROM libc IMPORT exit ;
 
 FROM M2Error IMPORT ErrorStringAt, ErrorStringAt2, ErrorStringsAt2,
                     WriteFormat0, FlushErrors, FlushWarnings, ResetErrorScope ;
 
-FROM M2MetaError IMPORT MetaErrorString0, MetaErrorString1, MetaError0, MetaError1, MetaString0 ;
+FROM M2MetaError IMPORT MetaErrorString0, MetaErrorString1, MetaError0, MetaError1,
+                        MetaString0 ;
+
 FROM FormatStrings IMPORT Sprintf1 ;
 FROM P0SymBuild IMPORT P0Init, P1Init ;
+FROM M2Debug IMPORT Assert ;
 
 IMPORT m2flex ;
 IMPORT P0SyntaxCheck ;
@@ -51,6 +54,7 @@ IMPORT PCBuild ;
 IMPORT P3Build ;
 IMPORT PHBuild ;
 IMPORT PCSymBuild ;
+IMPORT DynamicStrings ;
 
 FROM M2Batch IMPORT GetSource, GetModuleNo, GetDefinitionModuleFile, GetModuleFile,
                     AssociateModule, AssociateDefinition, MakeImplementationSource,
@@ -59,16 +63,32 @@ FROM M2Batch IMPORT GetSource, GetModuleNo, GetDefinitionModuleFile, GetModuleFi
 FROM SymbolTable IMPORT GetSymName, IsDefImp, NulSym,
                         IsHiddenTypeDeclared, GetFirstUsed, GetMainModule, SetMainModule,
                         ResolveConstructorTypes, SanityCheckConstants, IsDefinitionForC,
-                        IsBuiltinInModule, PutModLink, IsDefLink, IsModLink,
-                        PutLibName ;
+                        IsBuiltinInModule, PutModLink, IsDefLink, IsModLink, PutLibName,
+                        GetModuleDefImportStatementList, GetModuleModImportStatementList,
+                        GetImportModule, IsImportStatement, IsImport,
+                        GetImportStatementList ;
+
+FROM M2Search IMPORT FindSourceDefFile ;
 
-FROM FIO IMPORT StdErr, StdOut ;
+FROM FIO IMPORT File, StdErr, StdOut, Close, EOF, IsNoError, WriteLine,
+                WriteChar, FlushOutErr ;
+
+FROM SFIO IMPORT WriteS, OpenToRead, OpenToWrite, ReadS, WriteS ;
 FROM NameKey IMPORT Name, GetKey, KeyToCharStar, makekey ;
-FROM M2Printf IMPORT fprintf1 ;
+FROM M2Printf IMPORT fprintf0, fprintf1 ;
 FROM M2Quiet IMPORT qprintf0, qprintf1, qprintf2 ;
-FROM DynamicStrings IMPORT String, InitString, KillString, InitStringCharStar, Dup, Mark, EqualArray, string ;
-FROM M2Options IMPORT Verbose, GetM2Prefix ;
+
+FROM M2Options IMPORT Verbose, GetM2Prefix, GetM, GetMM, GetDepTarget, GetMF, GetMP,
+                      GetObj, PPonly, Statistics, Quiet, WholeProgram, GetMD, GetMMD,
+                      ExtendedOpaque, GenModuleList ;
+
 FROM PathName IMPORT DumpPathName ;
+FROM Lists IMPORT List, NoOfItemsInList, GetItemFromList ;
+FROM Indexing IMPORT Index, InitIndex, KillIndex, GetIndice, PutIndice, HighIndice ;
+
+FROM DynamicStrings IMPORT String, InitString, KillString, InitStringCharStar,
+                           Dup, Mark, EqualArray, string, Length, ConCat, ConCatChar,
+                           InitStringChar, RIndex, Slice, Equal, RemoveWhitePrefix ;
 
 
 CONST
@@ -76,6 +96,8 @@ CONST
 
 VAR
    ModuleType : (None, Definition, Implementation, Program) ;
+   DepContent : Index ;
+   DepOutput  : String ;
 
 
 (*
@@ -123,37 +145,132 @@ BEGIN
 END NeedToParseImplementation ;
 
 
+(*
+   GenerateDefDependency - generate a single dependency for the definition module
+                           providing that it can be found and is not blocked by -MM.
+*)
+
+PROCEDURE GenerateDefDependency (module: CARDINAL) ;
+VAR
+   stem,
+   fullpath,
+   named   : String ;
+BEGIN
+   stem := InitStringCharStar (KeyToCharStar (GetSymName (module))) ;
+   named := NIL ;
+   IF FindSourceDefFile (stem, fullpath, named)
+   THEN
+      IF EqualArray (named, '') OR (NOT GetMM ())
+      THEN
+         MergeDep (DepContent, fullpath)
+      ELSE
+         fullpath := KillString (fullpath)
+      END
+   END ;
+   stem := KillString (stem) ;
+   named := KillString (named)
+END GenerateDefDependency ;
+
+
+(*
+   GenerateDependenciesFromImport - lookup the module associated with the import
+                                    and call GenerateDefDependency.
+*)
+
+PROCEDURE GenerateDependenciesFromImport (import: CARDINAL) ;
+VAR
+   module  : CARDINAL ;
+BEGIN
+   Assert (IsImport (import)) ;
+   module := GetImportModule (import) ;
+   GenerateDefDependency (module)
+END GenerateDependenciesFromImport ;
+
+
+(*
+   GenerateDependenciesFromList - iterative over the import lists and for
+                                  each module issue a dependency.
+*)
+
+PROCEDURE GenerateDependenciesFromList (dep: List) ;
+VAR
+   importList: List ;
+   import    : CARDINAL ;
+   i, n, j, m: CARDINAL ;
+BEGIN
+   n := NoOfItemsInList (dep) ;
+   i := 1 ;
+   WHILE i <= n DO
+      import := GetItemFromList (dep, i) ;
+      IF IsImportStatement (import)
+      THEN
+         importList := GetImportStatementList (import) ;
+         j := 1 ;
+         m := NoOfItemsInList (importList) ;
+         WHILE j <= m DO
+            import := GetItemFromList (importList, j) ;
+            GenerateDependenciesFromImport (import) ;
+            INC (j)
+         END
+      ELSE
+         GenerateDependenciesFromImport (import)
+      END ;
+      INC (i)
+   END
+END GenerateDependenciesFromList ;
+
+
+(*
+   GenerateDependencies - generate a list of dependencies for the main module where
+                          the source code is found in sourcefile.
+*)
+
+PROCEDURE GenerateDependencies (sourcefile: String) ;
+BEGIN
+   IF IsDefImp (GetMainModule ())
+   THEN
+      GenerateDependenciesFromList (GetModuleDefImportStatementList (GetMainModule ())) ;
+      GenerateDefDependency (GetMainModule ())
+   END ;
+   GenerateDependenciesFromList (GetModuleModImportStatementList (GetMainModule ())) ;
+   WriteDepContents (DepOutput, DepContent)
+END GenerateDependencies ;
+
+
 (*
    Compile - compile file, s, using a 5 pass technique.
 *)
 
 PROCEDURE Compile (s: String) ;
 BEGIN
-   DoPass0(s) ;
+   DoPass0 (s) ;
    FlushWarnings ; FlushErrors ;
-   IF PPonly
-   THEN
-      RETURN
-   END;
    ResetForNewPass ; ResetErrorScope ;
    qprintf0('Pass 1: scopes, enumerated types, imports and exports\n') ;
    DoPass1 ;
    FlushWarnings ; FlushErrors ;
-   qprintf0('Pass 2: constants and types\n') ;
-   ResetForNewPass ; ResetErrorScope ;
-   DoPass2 ;
-   FlushWarnings ; FlushErrors ;
-   qprintf0('Pass C: aggregate constants\n') ;
-   ResetForNewPass ; ResetErrorScope ;
-   DoPassC ;
-   FlushWarnings ; FlushErrors ;
-   qprintf0('Pass 3: quadruple generation\n') ;
-   ResetForNewPass ; ResetErrorScope ;
-   DoPass3 ;
-   FlushWarnings ; FlushErrors ;
-   qprintf0('Pass 4: gcc tree generation\n') ;
-   Code ;
-   FlushWarnings ; FlushErrors
+   IF GetM () OR GetMM ()
+   THEN
+      GenerateDependencies (s)
+   END ;
+   IF NOT PPonly
+   THEN
+      qprintf0('Pass 2: constants and types\n') ;
+      ResetForNewPass ; ResetErrorScope ;
+      DoPass2 ;
+      FlushWarnings ; FlushErrors ;
+      qprintf0('Pass C: aggregate constants\n') ;
+      ResetForNewPass ; ResetErrorScope ;
+      DoPassC ;
+      FlushWarnings ; FlushErrors ;
+      qprintf0('Pass 3: quadruple generation\n') ;
+      ResetForNewPass ; ResetErrorScope ;
+      DoPass3 ;
+      FlushWarnings ; FlushErrors ;
+      qprintf0('Pass 4: gcc tree generation\n') ;
+      Code ;
+      FlushWarnings ; FlushErrors
+   END
 END Compile ;
 
 
@@ -165,9 +282,9 @@ PROCEDURE compile (filename: ADDRESS) ;
 VAR
    f: String ;
 BEGIN
-   f := InitStringCharStar(filename) ;
-   Compile(f) ;
-   f := KillString(f) ;
+   f := InitStringCharStar (filename) ;
+   Compile (f) ;
+   f := KillString (f)
 END compile ;
 
 
@@ -229,7 +346,7 @@ END PeepInto ;
 
 
 (*
-   qprintLibName - print the libname
+   qprintLibName - print the libname.
 *)
 
 PROCEDURE qprintLibName (LibName: String) ;
@@ -242,165 +359,594 @@ END qprintLibName ;
 
 
 (*
-   DoPass0 -
+   CreateFileStem - create a stem using the template LibName_ModuleName.
+*)
+
+PROCEDURE CreateFileStem (SymName, LibName: String) : String ;
+BEGIN
+   IF Length (LibName) > 0
+   THEN
+      RETURN ConCat (Dup (LibName), ConCat (InitStringChar ('_'), SymName))
+   ELSE
+      RETURN SymName
+   END
+END CreateFileStem ;
+
+
+(*
+   Return basename of path.  CutExt determines whether the .extension
+   should be removed.
 *)
 
-PROCEDURE DoPass0 (s: String) ;
+PROCEDURE BaseName (Path: String; CutExt: BOOLEAN) : String ;
 VAR
-   Main,
-   Sym     : CARDINAL ;
-   i       : CARDINAL ;
-   SymName,
-   FileName,
-   LibName,
-   PPSource: String ;
+   ext,
+   basename: INTEGER ;
 BEGIN
-   P0Init ;
-   SetPassToPass0 ;
-   (* Maybe preprocess the main file.  *)
-   PPSource := PreprocessModule(s, TRUE);
-   IF PPonly
+   basename := RIndex (Path, '/', 0) ;
+   IF basename = -1
    THEN
-      RETURN
-   END;
-   PeepInto (PPSource) ;
-   Main := GetMainModule() ;
-   i := 1 ;
-   Sym := GetModuleNo(i) ;
-   qprintf1('Compiling: %s\n', PPSource) ;
-   IF Debugging
+      basename := 0
+   ELSE
+      basename := basename + 1
+   END ;
+   IF CutExt
    THEN
-      DumpPathName ('DoPass0')
+      ext := RIndex (Path, '.', 0) ;
+      IF ext=-1
+      THEN
+         ext := 0
+      END
+   ELSE
+      ext := 0
    END ;
-   IF Verbose
+   RETURN Slice (Path, basename, ext)
+END BaseName ;
+
+
+(*
+   IsLibrary - return TRUE if line contains a library module.
+*)
+
+PROCEDURE IsLibrary (line: String) : BOOLEAN ;
+VAR
+   moduleName,
+   libname, filename: String ;
+   result           : BOOLEAN ;
+BEGIN
+   result := FALSE ;
+   moduleName := BaseName (line, TRUE) ;
+   filename := NIL ;
+   libname := NIL ;
+   IF FindSourceDefFile (moduleName, filename, libname)
    THEN
-      fprintf1 (StdOut, 'Compiling: %s\n', PPSource)
+      moduleName := KillString (moduleName) ;
+      IF Length (libname) > 0
+      THEN
+         moduleName := BaseName (line, FALSE) ;
+         line := BaseName (line, FALSE) ;
+         result := Equal (line, moduleName) ;
+         line := KillString (line) ;
+      END
    END ;
-   qprintf0('Pass 0: lexical analysis, parsing, modules and associated filenames\n') ;
-   WHILE Sym#NulSym DO
-      SymName := InitStringCharStar (KeyToCharStar (GetSymName (Sym))) ;
-      IF IsDefImp (Sym)
+   libname := KillString (libname) ;
+   filename := KillString (filename) ;
+   moduleName := KillString (moduleName) ;
+   RETURN result
+END IsLibrary ;
+
+
+(*
+   IsUnique - return TRUE if line is unique in array content.
+*)
+
+PROCEDURE IsUnique (content: Index; line: String) : BOOLEAN ;
+VAR
+   high, i: CARDINAL ;
+BEGIN
+   high := HighIndice (content) ;
+   i := 1 ;
+   WHILE i <= high DO
+      IF Equal (line, GetIndice (content, i))
       THEN
-         LibName := NIL ;
-         IF FindSourceDefFile (SymName, FileName, LibName)
+         RETURN FALSE
+      END ;
+      INC (i)
+   END ;
+   RETURN TRUE
+END IsUnique ;
+
+
+(*
+   Append - append line to array content.
+*)
+
+PROCEDURE Append (content: Index; line: String) ;
+VAR
+   high: CARDINAL ;
+BEGIN
+   high := HighIndice (content) ;
+   PutIndice (content, high+1, line)
+END Append ;
+
+
+(*
+   MergeDep - if line is unique in array content then append.
+              Check to see (and ignore) if line is a library module and -MM
+              is present.
+*)
+
+PROCEDURE MergeDep (content: Index; line: String) ;
+BEGIN
+   line := RemoveWhitePrefix (line) ;
+   IF (NOT EqualArray (line, "\")) AND (Length (line) > 0)
+   THEN
+      (* Ignore if -MM and is a library module.  *)
+      IF NOT (GetMM () AND IsLibrary (line))
+      THEN
+         IF IsUnique (content, line)
          THEN
-            ModuleType := Definition ;
-            IF OpenSource (AssociateDefinition (PreprocessModule (FileName, FALSE), Sym))
+            Append (content, line)
+         END
+      END
+   END
+END MergeDep ;
+
+
+(*
+   splitLine - split a line into words separated by spaces
+               and call MergeDep on each word.
+*)
+
+PROCEDURE splitLine (content: Index; line: String) ;
+VAR
+   word : String ;
+   space: INTEGER ;
+BEGIN
+   REPEAT
+      line := RemoveWhitePrefix (line) ;
+      space := DynamicStrings.Index (line, ' ', 0) ;
+      IF space > 0
+      THEN
+         word := Slice (line, 0, space) ;
+         word := RemoveWhitePrefix (word) ;
+         IF Length (word) > 0
+         THEN
+            MergeDep (content, word)
+         END ;
+         line := Slice (line, space, 0) ;
+      ELSIF space < 0
+      THEN
+         MergeDep (content, line)
+      END
+   UNTIL space <= 0
+END splitLine ;
+
+
+(*
+   MergeDeps - foreach dependency in ChildDep do
+                  add dependency to ChildDep if not already present.
+               ignore all ChildDep if -MM and libname # "".
+*)
+
+PROCEDURE MergeDeps (content: Index; ChildDep, LibName: String) ;
+VAR
+   line: String ;
+   in  : File ;
+BEGIN
+   IF (content # NIL) AND (NOT (GetMM () AND (Length (LibName) > 0)))
+   THEN
+      in := OpenToRead (ChildDep) ;
+      IF IsNoError (in)
+      THEN
+         line := ReadS (in) ;  (* Skip over first line containing the module object.  *)
+         WHILE NOT EOF (in) DO
+            line := ReadS (in) ;
+            splitLine (content, line)
+         END
+      END ;
+      Close (in)
+   END
+END MergeDeps ;
+
+
+(*
+   GetRuleTarget - return the rule target which is derived from the -MT arg
+                   or -o arg or filename.mod.
+*)
+
+PROCEDURE GetRuleTarget (filename: String) : String ;
+BEGIN
+   IF GetDepTarget () # NIL
+   THEN
+      RETURN InitStringCharStar (GetDepTarget ())
+   ELSIF GetMF () # NIL
+   THEN
+      RETURN InitStringCharStar (GetMF ())
+   ELSE
+      RETURN ConCat (BaseName (filename, TRUE), InitString ('.o'))
+   END
+END GetRuleTarget ;
+
+
+(*
+   ReadDepContents - reads the contents of file dep into a dynamic array
+                     and return the array.  The file will be split into words
+                     and each word stored as an entry in the array.
+*)
+
+PROCEDURE ReadDepContents (filename, dep: String) : Index ;
+VAR
+   content: Index ;
+   line   : String ;
+   in     : File ;
+BEGIN
+   content := NIL ;
+   IF GetM () OR GetMM ()
+   THEN
+      in := OpenToRead (dep) ;
+      (* The file might not be created (if -MD or -MMD is used as these options
+         operate without preprocessing) in which case we create an dynamic
+         array with the source filename and target.  *)
+      content := InitIndex (1) ;
+      IF GetMD () OR GetMMD () OR (NOT IsNoError (in))
+      THEN
+         (* No preprocessing done therefore create first two lines using
+            target and source.  *)
+         PutIndice (content, 1, ConCatChar (GetRuleTarget (filename), ':')) ;
+         PutIndice (content, 2, Dup (filename))
+      ELSE
+         (* Preprocessing (using cc1) has created one for us, so we read it.  *)
+         WHILE NOT EOF (in) DO
+            line := ReadS (in) ;
+            splitLine (content, line)
+         END
+      END ;
+      Close (in)
+   END ;
+   RETURN content
+END ReadDepContents ;
+
+
+(*
+   WriteDep - write the dependencies and target to file out.
+*)
+
+PROCEDURE WriteDep (dep: String; contents: Index; out: File) ;
+VAR
+   i, h: CARDINAL ;
+   line: String ;
+BEGIN
+   i := 1 ;
+   h := HighIndice (contents) ;
+   WHILE i <= h DO
+      line := GetIndice (contents, i) ;
+      line := RemoveWhitePrefix (line) ;
+      IF Length (line) > 0
+      THEN
+         IF i = 1
+         THEN
+            (* First line is always the target.  *)
+            IF GetDepTarget () # NIL
             THEN
-               IF NOT P0SyntaxCheck.CompilationUnit ()
-               THEN
-                  WriteFormat0 ('compilation failed') ;
-                  CloseSource ;
-                  RETURN
-               END ;
-               qprintf2 ('   Module %-20s : %s', SymName, FileName) ;
-               qprintLibName (LibName) ;
-               PutLibName (Sym, makekey (string (LibName))) ;
-               IF IsDefinitionForC (Sym)
-               THEN
-                  qprintf0 (' (for C)')
-               END ;
-               IF IsDefLink (Sym)
-               THEN
-                  qprintf0 (' (linking)')
-               END ;
-               qprintf0 ('\n') ;
-               CloseSource
-            ELSE
-               (* Unrecoverable error.  *)
-               MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found'),
-                                           FileName), Sym)
+               line := ConCatChar (InitStringCharStar (GetDepTarget ()), ':')
             END
+         ELSIF i > 1
+         THEN
+            WriteChar (out, ' ')
+         END ;
+         line := WriteS (out, line) ;
+         IF i < h
+         THEN
+            WriteChar (out, ' ') ;
+            WriteChar (out, '\')
+         END ;
+         WriteLine (out)
+      END ;
+      INC (i)
+   END
+END WriteDep ;
+
+
+(*
+   WritePhonyDep - write the dependencies and target to file out.
+*)
+
+PROCEDURE WritePhonyDep (dep: String; contents: Index; out: File) ;
+VAR
+   i, h: CARDINAL ;
+   line: String ;
+BEGIN
+   (* The first line is always the target and the second line is always
+      the top level source file.  *)
+   i := 3 ;
+   h := HighIndice (contents) ;
+   WHILE i <= h DO
+      line := GetIndice (contents, i) ;
+      line := RemoveWhitePrefix (line) ;
+      IF Length (line) > 0
+      THEN
+         line := WriteS (out, line) ;
+         WriteChar (out, ':') ;
+         WriteLine (out)
+      END ;
+      INC (i)
+   END
+END WritePhonyDep ;
+
+
+(*
+   WriteDepContents - write the dynamic array to filename dep (or StdOut) if
+                      the GetMF file is NIL.
+*)
+
+PROCEDURE WriteDepContents (dep: String; contents: Index) ;
+VAR
+   out: File ;
+BEGIN
+   IF (contents # NIL) AND (GetM () OR GetMM ())
+   THEN
+      IF GetMF () = NIL
+      THEN
+         out := StdOut ;
+         dep := OnExitDelete (dep)
+      ELSE
+         out := OpenToWrite (dep)
+      END ;
+      IF IsNoError (out)
+      THEN
+         WriteDep (dep, contents, out) ;
+         IF GetMP ()
+         THEN
+            WritePhonyDep (dep, contents, out)
+         END
+      END ;
+      IF GetMF () = NIL
+      THEN
+         FlushOutErr
+      ELSE
+         Close (out) ;
+      END ;
+      contents := KillIndex (contents)
+   END
+END WriteDepContents ;
+
+
+(*
+   CreateDepFilename - return a dependency filename associated with filename or use GetMF.
+*)
+
+PROCEDURE CreateDepFilename (filename: String) : String ;
+VAR
+   depfile: String ;
+BEGIN
+   IF GetMF () = NIL
+   THEN
+      depfile := MakeSaveTempsFileNameExt (filename, InitString ('.d')) ;
+      RETURN OnExitDelete (depfile)
+   ELSE
+      RETURN InitStringCharStar (GetMF ())
+   END
+END CreateDepFilename ;
+
+
+(*
+   Pass0CheckDef -
+*)
+
+PROCEDURE Pass0CheckDef (sym: CARDINAL) : BOOLEAN ;
+VAR
+   ChildDep,
+   SymName,
+   FileName,
+   LibName : String ;
+BEGIN
+   LibName := NIL ;
+   FileName := NIL ;
+   SymName := InitStringCharStar (KeyToCharStar (GetSymName (sym))) ;
+   IF IsDefImp (sym)
+   THEN
+      IF FindSourceDefFile (SymName, FileName, LibName)
+      THEN
+         ModuleType := Definition ;
+         ChildDep := MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), InitString ('.def.d')) ;
+         IF OpenSource (AssociateDefinition (PreprocessModule (FileName, FALSE, TRUE,
+                                                               ChildDep), sym))
+         THEN
+            IF NOT P0SyntaxCheck.CompilationUnit ()
+            THEN
+               WriteFormat0 ('compilation failed') ;
+               CloseSource ;
+               SymName := KillString (SymName) ;
+               FileName := KillString (FileName) ;
+               LibName := KillString (LibName) ;
+               RETURN FALSE
+            END ;
+            qprintf2 ('   Module %-20s : %s', SymName, FileName) ;
+            qprintLibName (LibName) ;
+            PutLibName (sym, makekey (string (LibName))) ;
+            IF IsDefinitionForC (sym)
+            THEN
+               qprintf0 (' (for C)')
+            END ;
+            IF IsDefLink (sym)
+            THEN
+               qprintf0 (' (linking)')
+            END ;
+            qprintf0 ('\n') ;
+            CloseSource ;
+            MergeDeps (DepContent, ChildDep, LibName)
          ELSE
             (* Unrecoverable error.  *)
-            MetaError1 ('the file containing the definition module {%1EMAa} cannot be found', Sym)
-         END ;
-         ModuleType := Implementation
+            MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found'),
+                                        FileName), sym)
+         END
       ELSE
-         ModuleType := Program
+         (* Unrecoverable error.  *)
+         MetaError1 ('the file containing the definition module {%1EMAa} cannot be found', sym)
       END ;
-      IF (Main=Sym) OR NeedToParseImplementation (Sym)
+      ModuleType := Implementation
+   ELSE
+      ModuleType := Program
+   END ;
+   SymName := KillString (SymName) ;
+   FileName := KillString (FileName) ;
+   LibName := KillString (LibName) ;
+   RETURN TRUE
+END Pass0CheckDef ;
+
+
+(*
+   Pass0CheckMod -
+*)
+
+PROCEDURE Pass0CheckMod (sym: CARDINAL; PPSource: String) : BOOLEAN ;
+VAR
+   Main    : CARDINAL ;
+   ChildDep,
+   SymName,
+   FileName,
+   LibName : String ;
+BEGIN
+   SymName := InitStringCharStar (KeyToCharStar (GetSymName (sym))) ;
+   FileName := NIL ;
+   LibName := NIL ;
+   Main := GetMainModule () ;
+   IF (Main = sym) OR NeedToParseImplementation (sym)
+   THEN
+      (* Only need to read implementation module if hidden types are
+         declared or it is the main module.  *)
+      IF Main = sym
       THEN
-         (* Only need to read implementation module if hidden types are declared or it is the main module *)
-         LibName := NIL ;
-         IF Main=Sym
+         FileName := Dup (PPSource) ;
+         LibName := InitStringCharStar (GetM2Prefix ()) ;
+         PutLibName (sym, makekey (string (LibName)))
+      ELSE
+         IF FindSourceModFile (SymName, FileName, LibName)
          THEN
-            FileName := Dup (PPSource) ;
-            LibName := InitStringCharStar (GetM2Prefix ()) ;
-            PutLibName (Sym, makekey (string (LibName)))
+            ChildDep := MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), InitString ('.mod.d')) ;
+            FileName := PreprocessModule (FileName, FALSE, TRUE, ChildDep) ;
+            PutLibName (sym, makekey (string (LibName))) ;
+            MergeDeps (DepContent, ChildDep, LibName)
          ELSE
-            IF FindSourceModFile (SymName, FileName, LibName)
+            qprintf1 ('   Module %-20s : implementation source file not found\n', SymName)
+         END
+      END ;
+
+      IF FileName # NIL
+      THEN
+         IF OpenSource (AssociateModule (Dup (FileName), sym))
+         THEN
+            IF NOT P0SyntaxCheck.CompilationUnit ()
             THEN
-               FileName := PreprocessModule (FileName, FALSE) ;
-               PutLibName (Sym, makekey (string (LibName)))
-            ELSE
-               qprintf1 ('   Module %-20s : implementation source file not found\n', SymName)
+               WriteFormat0 ('compilation failed') ;
+               CloseSource ;
+               SymName := KillString (SymName) ;
+               FileName := KillString (FileName) ;
+               LibName := KillString (LibName) ;
+               RETURN FALSE
+            END ;
+            qprintf2 ('   Module %-20s : %s', SymName, FileName) ;
+            qprintLibName (LibName) ;
+            IF IsModLink (sym)
+            THEN
+               qprintf0 (' (linking)')
+            END ;
+            qprintf0 ('\n') ;
+            CloseSource
+         ELSE
+            (* It is quite legitimate to implement a module in C (and pretend it was a M2
+               implementation) providing that it is not the main program module and the
+               definition module does not declare a hidden type when -fextended-opaque
+               is used.  *)
+            IF (NOT WholeProgram) OR (sym = Main) OR IsHiddenTypeDeclared (sym)
+            THEN
+               (* Unrecoverable error.  *)
+               MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found'),
+                                           FileName), sym) ;
             END
-         END ;
-
-         IF FileName#NIL
+         END
+      END
+   ELSIF GenModuleList
+   THEN
+      IF NOT IsDefinitionForC (sym)
+      THEN
+         (* The implementation module is only useful if -fgen-module-list= is
+            used (to gather all dependencies) although we do not insist upon finding the
+            implementation module.  *)
+         LibName := NIL ;
+         IF FindSourceModFile (SymName, FileName, LibName)
          THEN
-            IF OpenSource (AssociateModule (Dup (FileName), Sym))
+            PutLibName (sym, makekey (string (LibName))) ;
+            qprintf2 ('   Module %-20s : %s' , SymName, FileName) ;
+            qprintLibName (LibName) ;
+            qprintf0 (' (linking)\n') ;
+            ChildDep := MakeSaveTempsFileNameExt (CreateFileStem (SymName, LibName), InitString ('.mod.d')) ;
+            IF OpenSource (AssociateModule (PreprocessModule (FileName, FALSE, TRUE, ChildDep), sym))
             THEN
+               PutModLink (sym, TRUE) ;   (* This source is only used to determine link time info.  *)
                IF NOT P0SyntaxCheck.CompilationUnit ()
                THEN
                   WriteFormat0 ('compilation failed') ;
                   CloseSource ;
-                  RETURN
-               END ;
-               qprintf2 ('   Module %-20s : %s', SymName, FileName) ;
-               qprintLibName (LibName) ;
-               IF IsModLink (Sym)
-               THEN
-                  qprintf0 (' (linking)')
+                  SymName := KillString (SymName) ;
+                  FileName := KillString (FileName) ;
+                  LibName := KillString (LibName) ;
+                  RETURN FALSE
                END ;
-               qprintf0 ('\n') ;
-               CloseSource
-            ELSE
-               (* It is quite legitimate to implement a module in C (and pretend it was a M2
-                  implementation) providing that it is not the main program module and the
-                  definition module does not declare a hidden type when -fextended-opaque
-                  is used.  *)
-               IF (NOT WholeProgram) OR (Sym=Main) OR IsHiddenTypeDeclared (Sym)
-               THEN
-                  (* Unrecoverable error.  *)
-                  MetaErrorString1 (Sprintf1 (InitString ('file {%%1EUAF%s} containing module {%%1a} cannot be found'),
-                                              FileName), Sym) ;
-               END
+               CloseSource ;
+               MergeDeps (DepContent, ChildDep, LibName)
             END
          END
-      ELSIF GenModuleList
+      END
+   END ;
+   SymName := KillString (SymName) ;
+   FileName := KillString (FileName) ;
+   LibName := KillString (LibName) ;
+   RETURN TRUE
+END Pass0CheckMod ;
+
+
+(*
+   DoPass0 -
+*)
+
+PROCEDURE DoPass0 (filename: String) ;
+VAR
+   sym       : CARDINAL ;
+   i         : CARDINAL ;
+   PPSource  : String ;
+BEGIN
+   P0Init ;
+   SetPassToPass0 ;
+   (* Maybe preprocess the main file.  *)
+   DepOutput := CreateDepFilename (filename) ;
+   PPSource := PreprocessModule (filename, TRUE, FALSE, DepOutput) ;
+   DepContent := ReadDepContents (filename, DepOutput) ;
+   PeepInto (PPSource) ;
+   i := 1 ;
+   sym := GetModuleNo (i) ;
+   qprintf1 ('Compiling: %s\n', PPSource) ;
+   IF Debugging
+   THEN
+      DumpPathName ('DoPass0')
+   END ;
+   IF Verbose
+   THEN
+      fprintf1 (StdOut, 'Compiling: %s\n', PPSource)
+   END ;
+   qprintf0 ('Pass 0: lexical analysis, parsing, modules and associated filenames\n') ;
+   WHILE sym # NulSym DO
+      IF NOT Pass0CheckDef (sym)
       THEN
-         IF NOT IsDefinitionForC (Sym)
-         THEN
-            (* The implementation is only useful if -fgen-module-list= is
-               used and we do not insist upon it.  *)
-            LibName := NIL ;
-            IF FindSourceModFile (SymName, FileName, LibName)
-            THEN
-               PutLibName (Sym, makekey (string (LibName))) ;
-               qprintf2 ('   Module %-20s : %s' , SymName, FileName) ;
-               qprintLibName (LibName) ;
-               qprintf0 (' (linking)\n') ;
-               IF OpenSource (AssociateModule (PreprocessModule (FileName, FALSE), Sym))
-               THEN
-                  PutModLink (Sym, TRUE) ;   (* This source is only used to determine link time info.  *)
-                  IF NOT P0SyntaxCheck.CompilationUnit ()
-                  THEN
-                     WriteFormat0 ('compilation failed') ;
-                     CloseSource ;
-                     RETURN
-                  END ;
-                  CloseSource
-               END
-            END
-         END
+         RETURN
+      END ;
+      IF NOT Pass0CheckMod (sym, PPSource)
+      THEN
+         RETURN
       END ;
-      SymName := KillString (SymName) ;
-      FileName := KillString (FileName) ;
-      LibName := KillString (LibName) ;
       INC (i) ;
-      Sym := GetModuleNo (i)
+      sym := GetModuleNo (i)
    END ;
    SetPassToNoPass
 END DoPass0 ;
@@ -706,5 +1252,7 @@ END DoPass3 ;
 
 
 BEGIN
-   ModuleType := None
+   ModuleType := None ;
+   DepContent := NIL ;
+   DepOutput := NIL
 END M2Comp.
diff --git a/gcc/m2/gm2-compiler/M2GCCDeclare.mod b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
index a16e59d76705..2e5f60fffbe5 100644
--- a/gcc/m2/gm2-compiler/M2GCCDeclare.mod
+++ b/gcc/m2/gm2-compiler/M2GCCDeclare.mod
@@ -97,6 +97,7 @@ FROM SymbolTable IMPORT NulSym,
                         IsGnuAsm, IsGnuAsmVolatile, IsObject, IsTuple,
                         IsError, IsHiddenType, IsVarHeap,
                         IsComponent, IsPublic, IsExtern, IsCtor,
+                        IsImport, IsImportStatement,
       	       	     	GetMainModule, GetBaseModule, GetModule, GetLocalSym,
                         PutModuleFinallyFunction,
                         GetProcedureScope, GetProcedureQuads,
@@ -4268,9 +4269,15 @@ BEGIN
    ELSIF IsAModula2Type(sym)
    THEN
       printf2('sym %d IsAModula2Type (%a)', sym, n)
-   ELSIF IsGnuAsmVolatile(sym)
+   ELSIF IsGnuAsm(sym)
+   THEN
+      printf2('sym %d IsGnuAsm (%a)', sym, n)
+   ELSIF IsImport (sym)
+   THEN
+      printf1('sym %d IsImport', sym)
+   ELSIF IsImportStatement (sym)
    THEN
-      printf2('sym %d IsGnuAsmVolatile (%a)', sym, n)
+      printf1('sym %d IsImportStatement', sym)
    END ;
 
    IF IsHiddenType(sym)
diff --git a/gcc/m2/gm2-compiler/M2Options.def b/gcc/m2/gm2-compiler/M2Options.def
index b70cd8f63ad1..65ab8e8c8b97 100644
--- a/gcc/m2/gm2-compiler/M2Options.def
+++ b/gcc/m2/gm2-compiler/M2Options.def
@@ -34,72 +34,6 @@ FROM SYSTEM IMPORT ADDRESS ;
 FROM DynamicStrings IMPORT String ;
 FROM m2linemap IMPORT location_t ;
 
-EXPORT QUALIFIED SetReturnCheck, SetNilCheck, SetCaseCheck,
-                 SetCheckAll, SetVerboseUnbounded, SetQuiet, SetCpp, GetCpp,
-                 (* SetMakeall, SetMakeall0, SetIncludePath, *) SetAutoInit,
-                 SetUnboundedByReference,
-                 SetSearchPath, SetISO, SetPIM, SetPIM2, SetPIM3, SetPIM4,
-                 SetPositiveModFloor, SetCompilerDebugging, SetExceptions,
-                 SetStyle, SetPedantic, SetPedanticParamNames, SetPedanticCast,
-                 SetExtendedOpaque, SetXCode, SetQuadDebugging, SetSources,
-                 SetDumpSystemExports,
-                 SetSwig, SetOptimizing, SetForcedLocation,
-                 SetCC1Quiet, SetWholeProgram, SetDebugTraceQuad, SetDebugTraceAPI,
-                 SetVerbose, SetM2g, GetM2g,
-		 GetISO, GetPIM, GetPIM2, GetPIM3, GetPIM4,
-		 GetPositiveModFloor,
-		 SetFloatValueCheck, GetFloatValueCheck,
-		 SetWholeValueCheck, GetWholeValueCheck,
-                 SetLowerCaseKeywords,
-                 SetIndex, SetRange, SetWholeDiv, SetStrictTypeChecking,
-                 Setc, Getc, SetPPOnly, GetPPOnly,
-                 SetUselist, GetUselist, GetUselistFilename,
-                 SetShared,
-
-                 Iso, Pim, Pim2, Pim3, Pim4,
-                 PPonly, cflag,
-                 PositiveModFloorDiv,
-                 Pedantic, Verbose, Statistics,
-                 UnboundedByReference, VerboseUnbounded,
-                 Profiling, Coding, Optimizing,
-                 OptimizeBasicBlock, OptimizeUncalledProcedures,
-                 OptimizeCommonSubExpressions,
-                 StyleChecking, WholeProgram,
-                 NilChecking,
-                 WholeDivChecking, WholeValueChecking,
-                 IndexChecking, RangeChecking,
-                 ReturnChecking, CaseElseChecking,
-                 AutoInit,
-                 VariantValueChecking, CaseEnumChecking,
-                 UnusedVariableChecking, UnusedParameterChecking,
-                 UninitVariableChecking, SetUninitVariableChecking,
-                 UninitVariableConditionalChecking,
-                 SetUnusedVariableChecking, SetUnusedParameterChecking,
-                 Quiet, LineDirectives, StrictTypeChecking,
-                 CPreProcessor, Xcode, ExtendedOpaque,
-                 LowerCaseKeywords,
-                 PedanticParamNames, PedanticCast,
-      	       	 DisplayQuadruples, DebugTraceQuad, DebugTraceAPI,
-                 CompilerDebugging, GenerateDebugging, GenerateLineDebug,
-                 DumpSystemExports, GenerateSwig, Exceptions,
-                 OverrideLocation, FinaliseOptions,
-                 DebugBuiltins, setdefextension, setmodextension,
-                 SetStatistics, SetWall,
-                 SetSaveTemps, SetSaveTempsDir, SaveTemps, GetSaveTempsDir,
-                 SetDumpDir, GetDumpDir, GenModuleList,
-                 CppArg, CppCommandLine, CppRemember,
-		 SetDebugFunctionLineNumbers, DebugFunctionLineNumbers,
-		 SetGenerateStatementNote, GenerateStatementNote,
-                 ScaffoldDynamic, ScaffoldStatic,
-                 SetScaffoldDynamic, SetScaffoldStatic,
-                 SetScaffoldMain, ScaffoldMain,
-                 SetRuntimeModuleOverride, GetRuntimeModuleOverride,
-                 SetGenModuleList, GetGenModuleFilename, SharedFlag,
-                 SetB, GetB, SetMD, GetMD, SetMMD, GetMMD, SetObj, GetObj,
-                 GetMQ, SetMQ, SetM2Prefix, GetM2Prefix,
-                 SetM2PathName, GetM2PathName, SetCaseEnumChecking,
-                 SetDebugBuiltins ;
-
 
 VAR
    PPonly,                       (* -E/M/MM present? - preprocessing only    *)
@@ -190,6 +124,48 @@ VAR
    Profiling               : BOOLEAN ;
 
 
+(*
+   SetM - set the MFlag.
+*)
+
+PROCEDURE SetM (value: BOOLEAN) ;
+
+
+(*
+   GetM - set the MFlag.
+*)
+
+PROCEDURE GetM () : BOOLEAN ;
+
+
+(*
+   SetMM - set the MMFlag.
+*)
+
+PROCEDURE SetMM (value: BOOLEAN) ;
+
+
+(*
+   GetMM - set the MMFlag.
+*)
+
+PROCEDURE GetMM () : BOOLEAN ;
+
+
+(*
+   SetMF - assigns MFarg to the filename from arg.
+*)
+
+PROCEDURE SetMF (arg: ADDRESS) ;
+
+
+(*
+   GetMF - returns MFarg or NIL if never set.
+*)
+
+PROCEDURE GetMF () : ADDRESS ;
+
+
 (*
    SetM2Prefix - assign arg to M2Prefix.
 *)
@@ -231,6 +207,7 @@ PROCEDURE SetPPOnly (value: BOOLEAN) ;
 
 PROCEDURE GetPPOnly () : BOOLEAN ;
 
+
 (*
    Setc - set the cflag (compile only flag -c) to value.
 *)
@@ -251,53 +228,91 @@ PROCEDURE Getc () : BOOLEAN ;
 
 PROCEDURE SetB (arg: ADDRESS) ;
 
+
 (*
    GetB - returns argument to the -B option as a string or NIL if it were never set.
 *)
 
 PROCEDURE GetB () : ADDRESS ;
 
+
 (*
-   SetMD - assigns MD file to arg.
+   SetMD - set the MDFlag to value.
 *)
 
-PROCEDURE SetMD (arg: ADDRESS) ;
+PROCEDURE SetMD (value: BOOLEAN) ;
+
 
 (*
-   GetMD - returns the filename set for MD or NIL if it was never set.
+   GetMD - return the MDFlag.
 *)
 
-PROCEDURE GetMD () : ADDRESS ;
+PROCEDURE GetMD () : BOOLEAN ;
 
 
 (*
-   SetMMD - assigns MMD file to arg.
+   SetMMD - set the MMDFlag to value.
 *)
 
-PROCEDURE SetMMD (arg: ADDRESS) ;
+PROCEDURE SetMMD (value: BOOLEAN) ;
+
 
 (*
-   GetMMD - returns the filename set for MMD or NIL if it was never set.
+   GetMMD - return the MMDFlag.
 *)
 
-PROCEDURE GetMMD () : ADDRESS ;
+PROCEDURE GetMMD () : BOOLEAN ;
+
 
 (*
-   SetMQ - assigns MQ file to arg.
+   SetMQ - adds a quoted target arg to the DepTarget sentence.
 *)
 
 PROCEDURE SetMQ (arg: ADDRESS) ;
 
+
 (*
-   GetMQ - returns the filename set for MQ or NIL if it was never set.
+   GetMQ - returns a C string containing all the -MQ arg values.
 *)
 
 PROCEDURE GetMQ () : ADDRESS ;
 
+
 (*
-   SetScaffoldDynamic - set the -fscaffold-dynamic flag.
+   SetMT - adds a target arg to the DepTarget sentence.
+*)
+
+PROCEDURE SetMT (arg: ADDRESS) ;
+
+
+(*
+   GetMT - returns a C string containing all the -MT arg values.
+*)
+
+PROCEDURE GetMT () : ADDRESS ;
+
+
+(*
+   GetDepTarget - returns the DepTarget as a C string.
+*)
+
+PROCEDURE GetDepTarget () : ADDRESS ;
+
+
+(*
+   SetMP - set the MPflag to value.
+*)
+
+PROCEDURE SetMP (value: BOOLEAN) ;
+
+
+(*
+   GetMP - get the MPflag.
 *)
 
+PROCEDURE GetMP () : BOOLEAN ;
+
+
 (*
    SetObj - assigns given object file to arg.
 *)
@@ -310,6 +325,7 @@ PROCEDURE SetObj (arg: ADDRESS) ;
 
 PROCEDURE GetObj () : ADDRESS ;
 
+
 (*
    SetScaffoldDynamic - set the -fscaffold-dynamic flag.
 *)
@@ -893,6 +909,7 @@ PROCEDURE SetSaveTempsDir (arg: ADDRESS) ;
 
 PROCEDURE GetSaveTempsDir () : String ;
 
+
 (*
    SetDumpDir - Specify dump dir.
 *)
diff --git a/gcc/m2/gm2-compiler/M2Options.mod b/gcc/m2/gm2-compiler/M2Options.mod
index 9d72a10b73eb..ece2d9105976 100644
--- a/gcc/m2/gm2-compiler/M2Options.mod
+++ b/gcc/m2/gm2-compiler/M2Options.mod
@@ -36,7 +36,7 @@ FROM m2configure IMPORT FullPathCPP ;
 
 FROM DynamicStrings IMPORT String, Length, InitString, Mark, Slice, EqualArray,
                            InitStringCharStar, ConCatChar, ConCat, KillString,
-                           Dup, string,
+                           Dup, string, char,
                            PushAllocation, PopAllocationExemption,
                            InitStringDB, InitStringCharStarDB,
                            InitStringCharDB, MultDB, DupDB, SliceDB ;
@@ -58,9 +58,10 @@ VAR
    M2Prefix,
    M2PathName,
    Barg,
-   MDarg,
-   MMDarg,
-   MQarg,
+   MFarg,
+   MTFlag,
+   MQFlag,
+   DepTarget,
    CmdLineObj,
    SaveTempsDir,
    DumpDir,
@@ -68,6 +69,11 @@ VAR
    UselistFilename,
    RuntimeModuleOverride,
    CppArgs              : String ;
+   MFlag,
+   MMFlag,
+   MPFlag,
+   MDFlag,
+   MMDFlag,
    UselistFlag,
    CC1Quiet,
    SeenSources          : BOOLEAN ;
@@ -185,72 +191,227 @@ END GetB ;
 
 
 (*
-   SetMD - assigns MDarg to the filename from arg.
-   This overrides any previous MMD.
+   SetM - set the MFlag.
 *)
 
-PROCEDURE SetMD (arg: ADDRESS) ;
+PROCEDURE SetM (value: BOOLEAN) ;
 BEGIN
-   MMDarg := KillString (MMDarg) ;
-   MDarg := KillString (MDarg) ;
-   MDarg := InitStringCharStar (arg)
+   MFlag := value
+END SetM ;
+
+
+(*
+   GetM - set the MFlag.
+*)
+
+PROCEDURE GetM () : BOOLEAN ;
+BEGIN
+   RETURN MFlag
+END GetM ;
+
+
+(*
+   SetMM - set the MMFlag.
+*)
+
+PROCEDURE SetMM (value: BOOLEAN) ;
+BEGIN
+   MMFlag := value
+END SetMM ;
+
+
+(*
+   GetMM - set the MMFlag.
+*)
+
+PROCEDURE GetMM () : BOOLEAN ;
+BEGIN
+   RETURN MMFlag
+END GetMM ;
+
+
+(*
+   SetMD - set the MDFlag to value.
+*)
+
+PROCEDURE SetMD (value: BOOLEAN) ;
+BEGIN
+   MDFlag := value
 END SetMD ;
 
 
 (*
-   GetMD - returns MDarg filename as a c-string or NIL if it was never set.
+   GetMD - return the MDFlag.
 *)
 
-PROCEDURE GetMD () : ADDRESS ;
+PROCEDURE GetMD () : BOOLEAN ;
 BEGIN
-   RETURN string (MDarg)
+   RETURN MDFlag
 END GetMD ;
 
 
 (*
-   SetMMD - assigns MMDarg to the filename from arg.
-   This overrides any previous MD.
+   SetMMD - set the MMDFlag to value.
 *)
 
-PROCEDURE SetMMD (arg: ADDRESS) ;
+PROCEDURE SetMMD (value: BOOLEAN) ;
 BEGIN
-   MDarg := KillString (MDarg) ;
-   MMDarg := KillString (MMDarg) ;
-   MMDarg := InitStringCharStar (arg)
+   MMDFlag := value
 END SetMMD ;
 
 
 (*
-   GetMMD - returns MMDarg filename as a c-string or NIL if it was never set.
+   GetMMD - return the MMDFlag.
 *)
 
-PROCEDURE GetMMD () : ADDRESS ;
+PROCEDURE GetMMD () : BOOLEAN ;
 BEGIN
-   RETURN string (MMDarg)
+   RETURN MMDFlag
 END GetMMD ;
 
 
 (*
-   SetMQ - assigns MQarg to the filename from arg.
+   SetMF - assigns MFarg to the filename from arg.
+*)
+
+PROCEDURE SetMF (arg: ADDRESS) ;
+BEGIN
+   MFarg := KillString (MFarg) ;
+   MFarg := InitStringCharStar (arg)
+END SetMF ;
+
+
+(*
+   GetMF - returns MFarg or NIL if never set.
+*)
+
+PROCEDURE GetMF () : ADDRESS ;
+BEGIN
+   RETURN string (MFarg)
+END GetMF ;
+
+
+(*
+   SetMP - set the MPflag to value.
+*)
+
+PROCEDURE SetMP (value: BOOLEAN) ;
+BEGIN
+   MPFlag := value
+END SetMP ;
+
+
+(*
+   GetMP - get the MPflag.
+*)
+
+PROCEDURE GetMP () : BOOLEAN ;
+BEGIN
+   RETURN MPFlag
+END GetMP ;
+
+
+(*
+   AddWord - concats a word to sentence inserting a space if necessary.
+             sentence is returned.  sentence will be created if it is NIL.
+*)
+
+PROCEDURE AddWord (sentence, word: String) : String ;
+BEGIN
+   IF word # NIL
+   THEN
+      IF sentence = NIL
+      THEN
+         sentence := Dup (word)
+      ELSE
+         sentence := ConCatChar (sentence, ' ') ;
+         sentence := ConCat (sentence, word)
+      END
+   END ;
+   RETURN sentence
+END AddWord ;
+
+
+(*
+   QuoteTarget - quote the '$' character.
+*)
+
+PROCEDURE QuoteTarget (target: String) : String ;
+VAR
+   quoted: String ;
+   i, n  : CARDINAL ;
+BEGIN
+   quoted := InitString ('') ;
+   i := 0 ;
+   n := Length (target) ;
+   WHILE i < n DO
+      CASE char (target, i) OF
+
+      '$':  quoted := ConCat (quoted, Mark (InitString ('$$')))
+
+      ELSE
+         quoted := ConCatChar (quoted, char (target, i))
+      END ;
+      INC (i)
+   END ;
+   RETURN quoted
+END QuoteTarget ;
+
+
+(*
+   SetMQ - adds a quoted target arg to the DepTarget sentence.
 *)
 
 PROCEDURE SetMQ (arg: ADDRESS) ;
 BEGIN
-   MQarg := KillString (MQarg) ;
-   MQarg := InitStringCharStar (arg)
+   DepTarget := AddWord (DepTarget, QuoteTarget (InitStringCharStar (arg))) ;
+   MQFlag := AddWord (MQFlag, Mark (InitString ('-MQ'))) ;
+   MQFlag := AddWord (MQFlag, Mark (InitStringCharStar (arg)))
 END SetMQ ;
 
 
 (*
-   GetMMD - returns MQarg filename as a c-string or NIL if it was never set.
+   GetMQ - returns a C string containing all the -MQ arg values.
 *)
 
 PROCEDURE GetMQ () : ADDRESS ;
 BEGIN
-   RETURN string (MQarg)
+   RETURN string (MQFlag)
 END GetMQ ;
 
 
+(*
+   SetMT - adds a target arg to the DepTarget sentence.
+*)
+
+PROCEDURE SetMT (arg: ADDRESS) ;
+BEGIN
+   DepTarget := AddWord (DepTarget, InitStringCharStar (arg)) ;
+   MTFlag := AddWord (MTFlag, Mark (InitString ('-MT'))) ;
+   MTFlag := AddWord (MTFlag, Mark (InitStringCharStar (arg)))
+END SetMT ;
+
+
+(*
+   GetMT - returns a C string containing all the -MT arg values.
+*)
+
+PROCEDURE GetMT () : ADDRESS ;
+BEGIN
+   RETURN string (MTFlag)
+END GetMT ;
+
+
+(*
+   GetDepTarget - returns the DepTarget as a C string.
+*)
+
+PROCEDURE GetDepTarget () : ADDRESS ;
+BEGIN
+   RETURN string (DepTarget)
+END GetDepTarget ;
+
+
 (*
    SetObj - assigns CmdLineObj to the filename from arg.
 *)
@@ -1498,14 +1659,20 @@ BEGIN
    GenModuleListFilename             := NIL ;
    SharedFlag                        := FALSE ;
    Barg                              := NIL ;
-   MDarg                             := NIL ;
-   MMDarg                            := NIL ;
-   MQarg                             := NIL ;
+   MDFlag                            := FALSE ;
+   MMDFlag                           := FALSE ;
+   DepTarget                         := NIL ;
+   MPFlag                            := FALSE ;
    SaveTempsDir                      := NIL ;
    DumpDir                           := NIL ;
    UninitVariableChecking            := FALSE ;
    UninitVariableConditionalChecking := FALSE ;
    CaseEnumChecking                  := FALSE ;
+   MFlag                             := FALSE ;
+   MMFlag                            := FALSE ;
+   MFarg                             := NIL ;
+   MTFlag                            := NIL ;
+   MQFlag                            := NIL ;
    M2Prefix                          := InitString ('') ;
    M2PathName                        := InitString ('')
 END M2Options.
diff --git a/gcc/m2/gm2-compiler/M2Preprocess.def b/gcc/m2/gm2-compiler/M2Preprocess.def
index 025858003172..0683018de207 100644
--- a/gcc/m2/gm2-compiler/M2Preprocess.def
+++ b/gcc/m2/gm2-compiler/M2Preprocess.def
@@ -32,7 +32,6 @@ DEFINITION MODULE M2Preprocess ;
 *)
 
 FROM DynamicStrings IMPORT String ;
-EXPORT QUALIFIED PreprocessModule ;
 
 
 (*
@@ -43,9 +42,31 @@ EXPORT QUALIFIED PreprocessModule ;
                       If preprocessing occurs then a temporary file is created
                       and its name is returned.
                       All temporary files will be deleted when the compiler exits.
+                      outputdep is the filename which will contain the dependency
+                      info if -M, -MM is provided.  outputdep can be NIL in which case
+                      it is ignored.
 *)
 
-PROCEDURE PreprocessModule (filename: String; isMain: BOOLEAN) : String ;
+PROCEDURE PreprocessModule (filename: String;
+                            topSource, deleteDep: BOOLEAN;
+                            outputDep: String) : String ;
+
+
+(*
+   MakeSaveTempsFileNameExt - creates and return the temporary filename.ext.
+                              in the current working directory unless
+                              SaveTempsDir = obj, when we put it in the dumpdir
+                              if that is specified (or fallback to '.' if not).
+*)
+
+PROCEDURE MakeSaveTempsFileNameExt (filename, ext: String) : String ;
+
+
+(*
+   OnExitDelete - when the application finishes delete filename.
+*)
+
+PROCEDURE OnExitDelete (filename: String) : String ;
 
 
 END M2Preprocess.
diff --git a/gcc/m2/gm2-compiler/M2Preprocess.mod b/gcc/m2/gm2-compiler/M2Preprocess.mod
index d53228b46752..189101e0d7e8 100644
--- a/gcc/m2/gm2-compiler/M2Preprocess.mod
+++ b/gcc/m2/gm2-compiler/M2Preprocess.mod
@@ -33,22 +33,35 @@ FROM libc IMPORT system, exit, unlink, printf, atexit ;
 FROM Lists IMPORT List, InitList, KillList, IncludeItemIntoList, ForeachItemInListDo ;
 FROM FIO IMPORT StdErr, StdOut ;
 FROM M2Printf IMPORT fprintf1 ;
-FROM M2Options IMPORT Verbose, PPonly, GetObj, GetMD, GetMMD, GetMQ,
-                      CppCommandLine, SaveTemps, GetSaveTempsDir, GetDumpDir ;
+
+FROM M2Options IMPORT Verbose, PPonly, GetObj, GetMD, GetMMD, GetCpp, GetMQ,
+                      CppCommandLine, SaveTemps, GetSaveTempsDir, GetDumpDir,
+                      GetM, GetMM ;
+
 FROM NameKey IMPORT Name, MakeKey, KeyToCharStar, makekey ;
 
 
+CONST
+   Debugging = FALSE ;
+
 VAR
    ListOfFiles: List ;
 
 
 (*
-   OnExitDelete -
+   OnExitDelete - when the application finishes delete filename.
 *)
 
 PROCEDURE OnExitDelete (filename: String) : String ;
 BEGIN
-   IncludeItemIntoList (ListOfFiles, makekey (filename)) ;
+   IF filename # NIL
+   THEN
+      IF Debugging
+      THEN
+         printf ("scheduling removal: %s\n", string (filename))
+      END ;
+      IncludeItemIntoList (ListOfFiles, makekey (string (filename)))
+   END ;
    RETURN filename
 END OnExitDelete ;
 
@@ -62,6 +75,10 @@ VAR
    n: Name ;
 BEGIN
    n := w ;
+   IF Debugging
+   THEN
+      printf ("removing: %s\n", KeyToCharStar (n))
+   END ;
    IF unlink (KeyToCharStar (n)) # 0
    THEN
    END
@@ -98,153 +115,174 @@ END GetFileName ;
 
 
 (*
-   Return basename.
+   MakeSaveTempsFileName - return a temporary file like
+   "./filename.{def,mod}.m2i" in the current working directory unless
+   SaveTempsDir = obj, when we put it in the dumpdir if that is specified
+   (or fallback to '.' if not).
+   We have to keep the original extension because that disambiguates .def
+   and .mod files (otherwise, we'd need two 'preprocessed' extensions).
 *)
 
-(*
-PROCEDURE BaseName (Path: String) : String ;
-VAR
-   ext,
-   basename: INTEGER ;
+PROCEDURE MakeSaveTempsFileName (filename: String) : String ;
 BEGIN
-   basename := RIndex(Path, '/', 0) ;
-   IF basename=-1
-   THEN
-      basename := 0
-   ELSE
-      basename := basename + 1
-   END ;
-   ext := RIndex(Path, '.', 0) ;
-   IF ext=-1
-   THEN
-      ext := 0
-   END ;
-   RETURN Dup (Slice(Path, basename, ext))
-END BaseName ;
-*)
+   RETURN MakeSaveTempsFileNameExt (filename, InitString ('.m2i'))
+END MakeSaveTempsFileName ;
+
 
 (*
-   MakeSaveTempsFileName - return a temporary file like 
-   "./filename.{def,mod}.m2i" in the CWD unless SaveTempsDir = obj,
-   when we put it in the dumpdir if that is specified (or fallback to '.'
-   if not).
-   We have to keep the original extension because that disambiguates .def
-   and .mod files (otherwise, we'd need two 'preprocessed' extensions).
+   MakeSaveTempsFileNameExt - creates and return the temporary filename.ext.
+                              in the current working directory unless
+                              SaveTempsDir = obj, when we put it in the dumpdir
+                              if that is specified (or fallback to '.' if not).
 *)
 
-PROCEDURE MakeSaveTempsFileName (filename: String) : String ;
+PROCEDURE MakeSaveTempsFileNameExt (filename, ext: String) : String ;
 VAR
    NewName,
    DumpDir,
    NewDir : String ;
 BEGIN
-   NewName := ConCat (GetFileName (filename), InitString ('.m2i')) ;
-   NewDir := GetSaveTempsDir () ;
-   DumpDir := GetDumpDir () ;
-(*   IF Verbose
+   NewName := ConCat (Dup (GetFileName (filename)), ext) ;
+   NewDir := Dup (GetSaveTempsDir ()) ;
+   DumpDir := Dup (GetDumpDir ()) ;
+   IF Debugging
    THEN
       fprintf1 (StdOut, "newname: %s", NewName) ;
       fprintf1 (StdOut, " NewDir: %s", NewDir) ;
       fprintf1 (StdOut, " DumpDir: %s\n", DumpDir)
    END ;
-*)
    IF (NewDir#NIL) AND EqualArray (NewDir, 'obj') AND (DumpDir#NIL)
    THEN
-      RETURN Dup (ConCat (DumpDir, NewName))
+      RETURN ConCat (DumpDir, NewName)
    ELSE
-      RETURN Dup (ConCat (InitString ('./'), NewName))
+      RETURN ConCat (InitString ('./'), NewName)
    END ;
-END MakeSaveTempsFileName ;
+END MakeSaveTempsFileNameExt ;
 
 
 (*
-   PreprocessModule - preprocess a file, filename, returning the new filename
-                      of the preprocessed file.
-                      Preprocessing will only occur if requested by the user.
-                      If no preprocessing was requested then filename is returned.
-                      If preprocessing occurs then a temporary file is created
-                      and its name is returned.
-                      All temporary files will be deleted when the compiler exits.
+   BuildCommandLineExecute - build the cpp command line and execute the command and return
+                             the tempfile containing the preprocessed source.
 *)
 
-PROCEDURE PreprocessModule (filename: String; isMain: BOOLEAN) : String ;
+PROCEDURE BuildCommandLineExecute (filename: String;
+                                   topSource, deleteDep: BOOLEAN;
+                                   command, outputdep: String) : String ;
 VAR
    tempfile,
-   command,
    commandLine: String ;
 BEGIN
-   command := CppCommandLine () ;
-   IF (command = NIL) OR EqualArray (command, '')
+   commandLine := Dup (command) ;
+   tempfile := NIL ;
+   (* We support MD and MMD for the main file only, at present.  *)
+   IF topSource OR PPonly
    THEN
-      RETURN Dup (filename)
-   ELSE
-      commandLine := Dup (command) ;
-      tempfile := NIL ;
-      (* We support MD and MMD for the main file only, at present.  *)
-      IF isMain OR PPonly
+      IF GetMD ()
       THEN
-         IF GetMD () # NIL
-         THEN
-            tempfile := ConCat( Mark (InitString(' -MD ')),
-                                InitStringCharStar (GetMD ()))
-         ELSIF GetMMD () # NIL
-         THEN
-            tempfile := ConCat( Mark (InitString(' -MMD ')),
-                                InitStringCharStar (GetMMD ()))
-         END ;
-         IF tempfile#NIL
-         THEN
-            commandLine := ConCat (Dup (commandLine), Dup (tempfile)) ;
-            (* We can only add MQ if we already have an MD/MMD.  *)
-            IF GetMQ () # NIL
-            THEN
-               tempfile := ConCat( Mark (InitString(' -MQ ')),
-                                 InitStringCharStar (GetMQ ())) ;
-               commandLine := ConCat (Dup (commandLine), Dup (tempfile))
-            END ;
-         END ;
+         tempfile := ConCat (InitString(' -MD '), outputdep)
+      ELSIF GetMMD ()
+      THEN
+         tempfile := ConCat (InitString(' -MMD '), outputdep)
       END ;
-      (* The output file depends on whether we are in stand-alone PP mode, and
-         if an output file is specified.  *)
-      tempfile := NIL ;
-      IF PPonly
+      IF tempfile#NIL
       THEN
-         IF GetObj () # NIL
+         commandLine := ConCat (Dup (commandLine), Dup (tempfile)) ;
+         (* We can only add MQ if we already have an MD/MMD.  *)
+         IF GetMQ () # NIL
          THEN
-           tempfile := InitStringCharStar (GetObj ())
-         END ;
-      ELSIF SaveTemps
+            tempfile := InitStringCharStar (GetMQ ()) ;
+            commandLine := ConCat (Dup (commandLine), Dup (tempfile))
+         END
+      END
+   END ;
+   (* The output file depends on whether we are in stand-alone PP mode, and
+      if an output file is specified.  *)
+   tempfile := NIL ;
+   IF PPonly
+   THEN
+      IF GetObj () # NIL
       THEN
-         tempfile := MakeSaveTempsFileName (filename)
-      ELSE
-         tempfile := InitStringCharStar (make_temp_file (KeyToCharStar (MakeKey('.m2i'))))
-      END ;
-      commandLine := ConCat (ConCatChar (Dup (commandLine), ' '), filename) ;
-      IF tempfile # NIL
+         tempfile := InitStringCharStar (GetObj ())
+      END
+   ELSIF SaveTemps
+   THEN
+      tempfile := MakeSaveTempsFileName (filename)
+   ELSE
+      tempfile := InitStringCharStar (make_temp_file (KeyToCharStar (MakeKey('.m2i'))))
+   END ;
+   commandLine := ConCat (ConCatChar (Dup (commandLine), ' '), filename) ;
+   IF tempfile # NIL
+   THEN
+      commandLine := ConCat (ConCat (Dup (commandLine),
+                                     Mark (InitString(' -o '))), tempfile) ;
+   END ;
+   IF (outputdep # NIL) AND (Length (outputdep) > 0) AND (GetM () OR GetMM ())
+   THEN
+      commandLine := ConCat (commandLine, ConCat (Mark (InitString (' -MF ')),
+                                                  outputdep)) ;
+      IF deleteDep AND (NOT SaveTemps)
       THEN
-         commandLine := ConCat (ConCat (Dup (commandLine),
-                                        Mark (InitString(' -o '))), tempfile) ;
-      END ;
-(*  use pexecute in the future
-      res := pexecute(string(Slice(commandLine, 0, Index(commandLine, ' ', 0))), etc etc );
+         outputdep := OnExitDelete (outputdep)
+      END
+   END ;
+   (* use pexecute in the future
+      res := pexecute(string(Slice(commandLine, 0, Index(commandLine, ' ', 0))), etc etc );  *)
+   (* for now we'll use system *)
+   IF Verbose
+   THEN
+      fprintf1 (StdOut, "preprocess: %s\n", commandLine)
+   END ;
+   IF system (string (commandLine)) # 0
+   THEN
+      fprintf1 (StdErr, 'C preprocessor failed when preprocessing %s\n', filename) ;
+      exit (1)
+   END ;
+   commandLine := KillString (commandLine) ;
+   IF SaveTemps
+   THEN
+      RETURN tempfile
+   ELSE
+      RETURN OnExitDelete (tempfile)
+   END
+END BuildCommandLineExecute ;
+
+
+(*
+   PreprocessModule - preprocess a file, filename, returning the new filename
+                      of the preprocessed file.
+                      Preprocessing will only occur if requested by the user.
+                      If no preprocessing was requested then filename is returned.
+                      If preprocessing occurs then a temporary file is created
+                      and its name is returned.
+                      All temporary files will be deleted when the compiler exits.
+                      outputdep is the filename which will contain the dependency
+                      info if -M, -MM is provided.  outputdep can be NIL in which case
+                      it is ignored.
 *)
-      (* for now we'll use system *)
-      IF Verbose
-      THEN
-         fprintf1 (StdOut, "preprocess: %s\n", commandLine)
-      END ;
-      IF system (string (commandLine)) # 0
+
+PROCEDURE PreprocessModule (filename: String;
+                            topSource, deleteDep: BOOLEAN;
+                            outputDep: String) : String ;
+VAR
+   command: String ;
+BEGIN
+   IF GetCpp ()
+   THEN
+      command := CppCommandLine () ;
+      IF (command = NIL) OR EqualArray (command, '')
       THEN
-         fprintf1 (StdErr, 'C preprocessor failed when preprocessing %s\n', filename) ;
-         exit (1)
+         RETURN Dup (filename)
       END ;
-      commandLine := KillString (commandLine) ;
-      IF SaveTemps
+      command := BuildCommandLineExecute (filename, topSource, deleteDep,
+                                          command, outputDep) ;
+      IF command = NIL
       THEN
-         RETURN tempfile
+         RETURN filename
       ELSE
-         RETURN OnExitDelete (tempfile)
+         RETURN command
       END
+   ELSE
+      RETURN Dup (filename)
    END
 END PreprocessModule ;
 
diff --git a/gcc/m2/gm2-compiler/M2Search.def b/gcc/m2/gm2-compiler/M2Search.def
index e77c75477ee6..6e16d690a41e 100644
--- a/gcc/m2/gm2-compiler/M2Search.def
+++ b/gcc/m2/gm2-compiler/M2Search.def
@@ -89,6 +89,4 @@ PROCEDURE SetDefExtension (ext: String) ;
 PROCEDURE SetModExtension (ext: String) ;
 
 
-
-
 END M2Search.
diff --git a/gcc/m2/gm2-compiler/SymbolTable.mod b/gcc/m2/gm2-compiler/SymbolTable.mod
index 2414517dd3d7..c2ed90f2a0cb 100644
--- a/gcc/m2/gm2-compiler/SymbolTable.mod
+++ b/gcc/m2/gm2-compiler/SymbolTable.mod
@@ -7688,7 +7688,9 @@ BEGIN
          PartialUnboundedSym : n := GetSymName(PartialUnbounded.Type) |
          TupleSym            : n := NulName |
          GnuAsmSym           : n := NulName |
-         InterfaceSym        : n := NulName
+         InterfaceSym        : n := NulName |
+         ImportSym           : n := NulName |
+         ImportStatementSym  : n := NulName
 
          ELSE
             InternalError ('unexpected symbol type')
diff --git a/gcc/m2/gm2-gcc/m2options.h b/gcc/m2/gm2-gcc/m2options.h
index 2ed2c9adf2ce..290b69ce4eaf 100644
--- a/gcc/m2/gm2-gcc/m2options.h
+++ b/gcc/m2/gm2-gcc/m2options.h
@@ -124,12 +124,21 @@ EXTERN void M2Options_SetGenModuleList (bool value, const char *filename);
 EXTERN void M2Options_SetShared (bool value);
 EXTERN void M2Options_SetB (const char *arg);
 EXTERN char *M2Options_GetB (void);
-EXTERN void M2Options_SetMD (const char *arg);
-EXTERN char *M2Options_GetMD (void);
-EXTERN void M2Options_SetMMD (const char *arg);
-EXTERN char *M2Options_GetMMD (void);
+EXTERN void M2Options_SetM (bool value);
+EXTERN bool M2Options_GetM (void);
+EXTERN void M2Options_SetMM (bool value);
+EXTERN bool M2Options_GetMM (void);
+EXTERN void M2Options_SetMD (bool value);
+EXTERN bool M2Options_GetMD (void);
+EXTERN void M2Options_SetMMD (bool value);
+EXTERN bool M2Options_GetMMD (void);
 EXTERN void M2Options_SetMQ (const char *arg);
-EXTERN char *M2Options_GetMQ (void);
+EXTERN void M2Options_SetMF (const char *arg);
+EXTERN char *M2Options_GetMF (void);
+EXTERN void M2Options_SetMT (const char *arg);
+EXTERN void M2Options_SetMP (bool value);
+EXTERN bool M2Options_GetMP (void);
+EXTERN char *M2Options_GetDepTarget (void);
 EXTERN void M2Options_SetObj (const char *arg);
 EXTERN char *M2Options_GetObj (void);
 EXTERN void M2Options_SetM2Prefix (const char *arg);
diff --git a/gcc/m2/gm2-lang.cc b/gcc/m2/gm2-lang.cc
index 45b5fe2fd458..7cf1185c9d2e 100644
--- a/gcc/m2/gm2-lang.cc
+++ b/gcc/m2/gm2-lang.cc
@@ -131,7 +131,7 @@ gm2_langhook_init (void)
 
   if (M2Options_GetPPOnly ())
     {
-      /* preprocess the file here.  */
+      /* Preprocess the file here.  */
       gm2_langhook_parse_file ();
       return false; /* Finish now, no further compilation.  */
     }
@@ -234,23 +234,54 @@ gm2_langhook_init_options (unsigned int decoded_options_count,
 	      building_cpp_command = true;
 	    }
 	  M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
-			      && !(option->flags & CL_SEPARATE));
+			    && !(option->flags & CL_SEPARATE));
 	  break;
+
 	case OPT_M:
+	  /* Output a rule suitable for make describing the dependencies of the
+	     main source file.  */
+	  if (in_cpp_args)
+	    {
+	      gcc_checking_assert (building_cpp_command);
+	      /* This is a preprocessor command.  */
+	      M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
+				&& !(option->flags & CL_SEPARATE));
+	    }
+	  M2Options_SetPPOnly (value);
+	  M2Options_SetM (value);
+	  break;
+
 	case OPT_MM:
-	  gcc_checking_assert (building_cpp_command);
+	  if (in_cpp_args)
+	    {
+	      gcc_checking_assert (building_cpp_command);
+	      /* This is a preprocessor command.  */
+	      M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
+				&& !(option->flags & CL_SEPARATE));
+	    }
 	  M2Options_SetPPOnly (value);
-	  /* This is a preprocessor command.  */
-	  M2Options_CppArg (opt, arg, (option->flags & CL_JOINED)
-			      && !(option->flags & CL_SEPARATE));
+	  M2Options_SetMM (value);
 	  break;
 
-	/* We can only use MQ when the command line is either PP-only, or
+	case OPT_MF:
+	  if (!in_cpp_args)
+	    M2Options_SetMF (arg);
+	  break;
+
+	case OPT_MP:
+	  M2Options_SetMP (value);
+	  break;
+
+	/* We can only use MQ and MT when the command line is either PP-only, or
 	   when there is a MD/MMD on it.  */
 	case OPT_MQ:
 	  M2Options_SetMQ (arg);
 	  break;
 
+	case OPT_MT:
+	  M2Options_SetMT (arg);
+	  break;
+
 	case OPT_o:
 	  M2Options_SetObj (arg);
 	  break;
@@ -266,14 +297,23 @@ gm2_langhook_init_options (unsigned int decoded_options_count,
 	     For now skip all plugins to avoid fails with the m2 one.  */
 	  break;
 
-	/* Preprocessor arguments with a following filename, we add these
-	   back to the main file preprocess line, but not to dependents
-	   TODO Handle MF.  */
+	/* Preprocessor arguments with a following filename.  */
 	case OPT_MD:
-	  M2Options_SetMD (arg);
+	  M2Options_SetMD (value);
+	  if (value)
+	    {
+	      M2Options_SetM (true);
+	      M2Options_SetMF (arg);
+	    }
 	  break;
+
 	case OPT_MMD:
-	  M2Options_SetMMD (arg);
+	  M2Options_SetMMD (value);
+	  if (value)
+	    {
+	      M2Options_SetMM (true);
+	      M2Options_SetMF (arg);
+	    }
 	  break;
 
 	/* Modula 2 claimed options we pass to the preprocessor.  */
@@ -744,7 +784,7 @@ gm2_langhook_post_options (const char **pfilename)
   if (allow_libraries)
     add_m2_import_paths (flibs);
 
- /* Returning false means that the backend should be used.  */
+  /* Returning false means that the backend should be used.  */
   return M2Options_GetPPOnly ();
 }
 
diff --git a/gcc/m2/lang-specs.h b/gcc/m2/lang-specs.h
index a564779d2e72..542936350bd5 100644
--- a/gcc/m2/lang-specs.h
+++ b/gcc/m2/lang-specs.h
@@ -23,11 +23,15 @@ along with GCC; see the file COPYING3.  If not see
 
 /* A spec for the 'integrated' preprocessor implementation for Modula-2.  */
 #define M2CPP \
-  "%{E|M|MM|fcpp: %{E} -fcpp-begin " \
+  "%{E|M|MM|fcpp: %{E} %{MF} -fcpp-begin " \
   "      %{!E:-E} %(cpp_unique_options) -traditional-cpp -ansi " \
   "      -fcpp-end %{B*} %{save-temps*} ; \
      : %{v} %I %{B*} %{save-temps*} } "
 
+#define MDMMD \
+  " %{MD:-MD %{!o:%b.d}%{o*:%.d%*} %{!MT:-MT %b%O} %{MT} %{MQ} %{MF}} " \
+  " %{MMD:-MMD %{!o:%b.d}%{o*:%.d%*} %{!MT:-MT %b%O} %{MT} %{MQ} %{MF}} "
+
 /* We have three modes:
    1. When the preprocessing step is explict and there is no following
       compilation.  Here we do a similar process to cc1 -E where most of
@@ -43,9 +47,7 @@ along with GCC; see the file COPYING3.  If not see
    "%{E|M|MM:\
       cc1gm2 " M2CPP " %{!fcpp:-fcpp;:%{fcpp}} %{fm2-pathname*} %i } \
     %{!E:%{!M:%{!MM:\
-      cc1gm2 " M2CPP " %(cc1_options) %{fm2-pathname*} %i %{c} \
-      %{!fcpp:%{MD|MMD|MF*: \
-		%eto generate dependencies you must specify '-fcpp' }} \
+      cc1gm2 " M2CPP MDMMD " %(cc1_options) %{fm2-pathname*} %i %{c} \
       %{!fsyntax-only:%(invoke_as)} \
     }}}", 0, 0, 0},
   {".m2i", "@modula-2-cpp-output", 0, 0, 0},

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2023-10-17 13:12 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-10-17 13:12 [gcc r14-4683] PR modula2/111756: Re-building all-gcc after source changes fails to link Gaius Mulley

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).