diff -rup4 a/link.c b/link.c
--- a/link.c	2009-12-03 22:26:24.000000000 +0100
+++ b/link.c	2010-01-08 12:07:51.227667900 +0100
@@ -86,13 +86,9 @@ int runLINK()
 	if (i)
 	    cmdbuf.writeByte('+');
 	p = (char *)global.params.objfiles->data[i];
 	char *ext = FileName::ext(p);
-	if (ext)
-	    // Write name sans extension
-	    writeFilename(&cmdbuf, p, ext - p - 1);
-	else
-	    writeFilename(&cmdbuf, p);
+	writeFilename(&cmdbuf, p);
     }
     cmdbuf.writeByte(',');
     if (global.params.exefile)
 	writeFilename(&cmdbuf, global.params.exefile);
diff -rup4 a/mars.c b/mars.c
--- a/mars.c	2009-12-03 22:26:24.000000000 +0100
+++ b/mars.c	2010-01-08 10:53:01.833429500 +0100
@@ -241,8 +241,9 @@ Usage:\n\
   -o-            do not write object file\n\
   -odobjdir      write object & library files to directory objdir\n\
   -offilename	 name output file to filename\n\
   -op            do not strip paths from source file\n\
+  -oq            use fully qualified module name for object filenames\n\
   -profile	 profile runtime performance of generated code\n\
   -quiet         suppress unnecessary messages\n\
   -release	 compile release version\n\
   -run srcfile args...   run resulting program, passing args\n\
@@ -443,8 +444,14 @@ int main(int argc, char *argv[])
 			    goto Lerror;
 			global.params.preservePaths = 1;
 			break;
 
+                    case 'q':
+                        if (p[3])
+                            goto Lerror;
+                        global.params.packagePaths = 1;
+                        break;
+
 		    case 0:
 			error("-o no longer supported, use -of or -od");
 			break;
 
@@ -856,9 +863,8 @@ int main(int argc, char *argv[])
 
     // Create Modules
     Array modules;
     modules.reserve(files.dim);
-    int firstmodule = 1;
     for (i = 0; i < files.dim; i++)
     {
 	char *ext;
 	char *name;
@@ -967,13 +973,8 @@ int main(int argc, char *argv[])
 
 	Identifier *id = new Identifier(name, 0);
 	m = new Module((char *) files.data[i], id, global.params.doDocComments, global.params.doHdrGeneration);
 	modules.push(m);
-
-	if (firstmodule)
-	{   global.params.objfiles->push(m->objfile->name->str);
-	    firstmodule = 0;
-	}
     }
 
 #if WINDOWS_SEH
   __try
@@ -1000,25 +1001,27 @@ int main(int argc, char *argv[])
 #endif
 
     // Parse files
     int anydocfiles = 0;
+    int firstmodule = 1;
     for (i = 0; i < modules.dim; i++)
     {
 	m = (Module *)modules.data[i];
 	if (global.params.verbose)
 	    printf("parse     %s\n", m->toChars());
 	if (!Module::rootModule)
 	    Module::rootModule = m;
 	m->importedFrom = m;
-	if (!global.params.oneobj || i == 0 || m->isDocFile)
-	    m->deleteObjFile();
 #if ASYNCREAD
 	if (aw->read(i))
 	{
 	    error("cannot read file %s", m->srcfile->name->toChars());
 	}
 #endif
 	m->parse();
+        m->prepareObjfile();
+        if (!global.params.oneobj || i == 0 || m->isDocFile)
+            m->deleteObjFile();
 	if (m->isDocFile)
 	{
 	    anydocfiles = 1;
 	    m->gendocfile();
@@ -1038,9 +1041,14 @@ int main(int argc, char *argv[])
 	    }
 
 	    if (global.params.objfiles->dim == 0)
 		global.params.link = 0;
-	}
+        }
+
+        if (firstmodule)
+        {   global.params.objfiles->push(m->objfile->name->str);
+            firstmodule = 0;
+        }
     }
 #if ASYNCREAD
     AsyncRead::dispose(aw);
 #endif
diff -rup4 a/mars.h b/mars.h
--- a/mars.h	2009-12-03 22:26:24.000000000 +0100
+++ b/mars.h	2010-01-08 10:53:01.833429500 +0100
@@ -145,8 +145,9 @@ struct Param
     char useUnitTests;	// generate unittest code
     char useInline;	// inline expand functions
     char release;	// build release version
     char preservePaths;	// !=0 means don't strip path from source file
+    char packagePaths;  // !=0 means use the fully qualified module name as object file output filename
     char warnings;	// enable warnings
     char pic;		// generate position-independent-code for shared libs
     char cov;		// generate code coverage data
     char nofloat;	// code should not pull in floating point support
diff -rup4 a/module.c b/module.c
--- a/module.c	2009-12-03 22:26:24.000000000 +0100
+++ b/module.c	2010-01-08 10:53:01.833429500 +0100
@@ -63,13 +63,12 @@ Module::Module(char *filename, Identifie
 {
     FileName *srcfilename;
     FileName *cfilename;
     FileName *hfilename;
-    FileName *objfilename;
-    FileName *symfilename;
 
 //    printf("Module::Module(filename = '%s', ident = '%s')\n", filename, ident->toChars());
     this->arg = filename;
+    orig_filename = filename;
     md = NULL;
     errors = 0;
     numlines = 0;
     members = NULL;
@@ -128,39 +127,54 @@ Module::Module(char *filename, Identifie
 	    fatal();
 	}
     }
 
+    if (doDocComment)
+    {
+        setDocfile();
+    }
+
+    if (doHdrGen)
+    {
+        setHdrfile();
+    }
+
+    srcfile = new File(srcfilename);
+}
+
+void Module::prepareObjfile()
+{
+    char *filename = orig_filename;
+    FileName *objfilename;
+    FileName *symfilename;
     char *argobj;
     if (global.params.objname)
-	argobj = global.params.objname;
+        argobj = global.params.objname;
     else if (global.params.preservePaths)
-	argobj = filename;
-    else
-	argobj = FileName::name(filename);
+        argobj = filename;
+    else if (global.params.packagePaths) {
+        argobj = (char*)toPrettyChars();
+        //FileName::forceExt will think the last part of the package path is an extension
+        //argobj = argobj ~ '.' ~ global.obj_ext;
+        char* tmp = (char*)calloc(1, strlen(argobj) + strlen(global.obj_ext) + 2);
+        memcpy(tmp, argobj, strlen(argobj));
+        tmp[strlen(argobj)] = '.';
+        memcpy(tmp + strlen(argobj) + 1, global.obj_ext, strlen(global.obj_ext));
+        argobj = tmp;
+    } else
+        argobj = FileName::name(filename);
     if (!FileName::absolute(argobj))
     {
-	argobj = FileName::combine(global.params.objdir, argobj);
+        argobj = FileName::combine(global.params.objdir, argobj);
     }
 
     if (global.params.objname)
-	objfilename = new FileName(argobj, 0);
+        objfilename = new FileName(argobj, 0);
     else
-	objfilename = FileName::forceExt(argobj, global.obj_ext);
+        objfilename = FileName::forceExt(argobj, global.obj_ext);
 
     symfilename = FileName::forceExt(filename, global.sym_ext);
 
-    srcfile = new File(srcfilename);
-
-    if (doDocComment)
-    {
-	setDocfile();
-    }
-
-    if (doHdrGen)
-    {
-	setHdrfile();
-    }
-
     objfile = new File(objfilename);
     symfile = new File(symfilename);
 }
 
@@ -221,9 +235,9 @@ void Module::setHdrfile()
 }
 
 void Module::deleteObjFile()
 {
-    if (global.params.obj)
+    if (global.params.obj && objfile)
 	objfile->remove();
     if (docfile)
 	docfile->remove();
 }
@@ -605,8 +619,11 @@ void Module::parse()
 	/* Check to see if module name is a valid identifier
 	 */
 	if (!Lexer::isValidIdentifier(this->ident->toChars()))
 	    error("has non-identifier characters in filename, use module declaration instead");
+
+        if (global.params.packagePaths)
+            error("has no module declaration; this is not allowed when using option -oq");
     }
 
     // Update global list of modules
     if (!dst->insert(this))
diff -rup4 a/module.h b/module.h
--- a/module.h	2009-12-03 22:26:24.000000000 +0100
+++ b/module.h	2010-01-08 10:53:01.849059000 +0100
@@ -57,8 +57,9 @@ struct Module : Package
     static ClassDeclaration *moduleinfo;
 
 
     const char *arg;	// original argument name
+    char *orig_filename; //original filename (passed to Module ctor)
     ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
     File *srcfile;	// input source file
     File *objfile;	// output .obj file
     File *hdrfile;	// 'header' file
@@ -110,8 +111,10 @@ struct Module : Package
 
     Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen);
     ~Module();
 
+    void prepareObjfile();
+
     static Module *load(Loc loc, Array *packages, Identifier *ident);
 
     void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
     void toJsonBuffer(OutBuffer *buf);
