diff --git a/ini/freebsd/bin32/dmd.conf b/ini/freebsd/bin32/dmd.conf index 7f35963b9175..1d41f0cf9a91 100644 --- a/ini/freebsd/bin32/dmd.conf +++ b/ini/freebsd/bin32/dmd.conf @@ -1,5 +1,5 @@ [Environment32] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic -rx=object -rx=std.* -rx=core.* -rx=etc.* [Environment64] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -rx=object -rx=std.* -rx=core.* -rx=etc.* diff --git a/ini/freebsd/bin64/dmd.conf b/ini/freebsd/bin64/dmd.conf index 7f35963b9175..1d41f0cf9a91 100644 --- a/ini/freebsd/bin64/dmd.conf +++ b/ini/freebsd/bin64/dmd.conf @@ -1,5 +1,5 @@ [Environment32] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic -rx=object -rx=std.* -rx=core.* -rx=etc.* [Environment64] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -rx=object -rx=std.* -rx=core.* -rx=etc.* diff --git a/ini/linux/bin32/dmd.conf b/ini/linux/bin32/dmd.conf index 7f35963b9175..1d41f0cf9a91 100644 --- a/ini/linux/bin32/dmd.conf +++ b/ini/linux/bin32/dmd.conf @@ -1,5 +1,5 @@ [Environment32] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic -rx=object -rx=std.* -rx=core.* -rx=etc.* [Environment64] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -rx=object -rx=std.* -rx=core.* -rx=etc.* diff --git a/ini/linux/bin64/dmd.conf b/ini/linux/bin64/dmd.conf index 7f35963b9175..1d41f0cf9a91 100644 --- a/ini/linux/bin64/dmd.conf +++ b/ini/linux/bin64/dmd.conf @@ -1,5 +1,5 @@ [Environment32] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib32 -L--export-dynamic -rx=object -rx=std.* -rx=core.* -rx=etc.* [Environment64] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib64 -L--export-dynamic -rx=object -rx=std.* -rx=core.* -rx=etc.* diff --git a/ini/osx/bin/dmd.conf b/ini/osx/bin/dmd.conf index 9e80a65c0e31..19c3e2cc4744 100644 --- a/ini/osx/bin/dmd.conf +++ b/ini/osx/bin/dmd.conf @@ -1,4 +1,4 @@ [Environment] -DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib +DFLAGS=-I%@P%/../../src/phobos -I%@P%/../../src/druntime/import -L-L%@P%/../lib -rx=object -rx=std.* -rx=core.* -rx=etc.* diff --git a/ini/osx/bin/dmdx.conf b/ini/osx/bin/dmdx.conf index c0fcaf2a0f4c..7ff485519d83 100644 --- a/ini/osx/bin/dmdx.conf +++ b/ini/osx/bin/dmdx.conf @@ -1,4 +1,4 @@ [Environment] -DFLAGS=-I~/dmd2/src/phobos -I~/dmd2/src/druntime/import +DFLAGS=-I~/dmd2/src/phobos -I~/dmd2/src/druntime/import -rx=object -rx=std.* -rx=core.* -rx=etc.* diff --git a/ini/windows/bin/sc.ini b/ini/windows/bin/sc.ini index ecb9142f934d..894851a69976 100644 --- a/ini/windows/bin/sc.ini +++ b/ini/windows/bin/sc.ini @@ -4,7 +4,7 @@ version=7.51 Build 020 ; environment for both 32/64 bit [Environment] -DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src\druntime\import" +DFLAGS="-I%@P%\..\..\src\phobos" "-I%@P%\..\..\src\druntime\import" -rx=object -rx=std.* -rx=core.* -rx=etc.* ; optlink only reads from the Environment section so we need this redundancy ; from the Environment32 section (bugzilla 11302) diff --git a/src/mars.c b/src/mars.c index dc74ee1448f3..9a5f0b073aaf 100644 --- a/src/mars.c +++ b/src/mars.c @@ -442,6 +442,8 @@ Usage:\n\ -profile profile runtime performance of generated code\n\ -property enforce property syntax\n\ -quiet suppress unnecessary messages\n\ + -rb recursively build all dependencies (if not filtered by -rx)\n\ + -rx do not build a dependency (e.g. -rx=foo.bar -rx=foo.*)\n\ -release compile release version\n\ -run srcfile args... run resulting program, passing args\n\ -shared generate shared library (DLL)\n\ @@ -643,6 +645,8 @@ int tryMain(size_t argc, const char *argv[]) } #endif + global.params.excludeList = new Strings(); + for (size_t i = 1; i < argc; i++) { const char *p = argv[i]; @@ -722,6 +726,10 @@ int tryMain(size_t argc, const char *argv[]) global.params.is64bit = true; else if (strcmp(p + 1, "profile") == 0) global.params.trace = 1; + else if (strcmp(p + 1, "rb") == 0) + global.params.buildRecurse = 1; + else if (memcmp(p + 1, "rx=", 3) == 0) + global.params.excludeList->push(p + 4); else if (strcmp(p + 1, "v") == 0) global.params.verbose = 1; else if (strcmp(p + 1, "vtls") == 0) @@ -1270,8 +1278,7 @@ Language changes listed by -transition=id:\n\ } // Create Modules - Modules modules; - modules.reserve(files.dim); + Module::buildModules.reserve(files.dim); bool firstmodule = true; for (size_t i = 0; i < files.dim; i++) { @@ -1381,7 +1388,7 @@ Language changes listed by -transition=id:\n\ Identifier *id = Lexer::idPool(name); Module *m = new Module(files[i], id, global.params.doDocComments, global.params.doHdrGeneration); - modules.push(m); + Module::buildModules.push(m); if (firstmodule) { global.params.objfiles->push(m->objfile->name->str); @@ -1397,8 +1404,8 @@ Language changes listed by -transition=id:\n\ { for (size_t i = 0; 1; i++) { - assert(i != modules.dim); - Module *m = modules[i]; + assert(i != Module::buildModules.dim); + Module *m = Module::buildModules[i]; if (strcmp(m->srcfile->name->str, global.main_d) == 0) { static const char buf[] = "int main(){return 0;}"; @@ -1412,28 +1419,29 @@ Language changes listed by -transition=id:\n\ #define ASYNCREAD 1 #if ASYNCREAD // Multi threaded - AsyncRead *aw = AsyncRead::create(modules.dim); - for (size_t i = 0; i < modules.dim; i++) + AsyncRead *aw = AsyncRead::create(Module::buildModules.dim); + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; aw->addFile(m->srcfile); } aw->start(); #else // Single threaded - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + m = Module::buildModules[i]; m->read(Loc()); } #endif // Parse files bool anydocfiles = false; - size_t filecount = modules.dim; + size_t filecount = Module::buildModules.dim; for (size_t filei = 0, modi = 0; filei < filecount; filei++, modi++) { - Module *m = modules[modi]; + Module *m = Module::buildModules[modi]; + if (global.params.verbose) fprintf(global.stdmsg, "parse %s\n", m->toChars()); if (!Module::rootModule) @@ -1454,8 +1462,8 @@ Language changes listed by -transition=id:\n\ anydocfiles = true; m->gendocfile(); - // Remove m from list of modules - modules.remove(modi); + // Remove m from list of Module::buildModules + Module::buildModules.remove(modi); modi--; // Remove m's object file from list of object files @@ -1476,7 +1484,7 @@ Language changes listed by -transition=id:\n\ AsyncRead::dispose(aw); #endif - if (anydocfiles && modules.dim && + if (anydocfiles && Module::buildModules.dim && (global.params.oneobj || global.params.objname)) { error(Loc(), "conflicting Ddoc and obj generation options"); @@ -1491,9 +1499,9 @@ Language changes listed by -transition=id:\n\ * line switches and what else is imported, they are generated * before any semantic analysis. */ - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; if (global.params.verbose) fprintf(global.stdmsg, "import %s\n", m->toChars()); m->genhdrfile(); @@ -1503,9 +1511,9 @@ Language changes listed by -transition=id:\n\ fatal(); // load all unconditional imports for better symbol resolving - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; if (global.params.verbose) fprintf(global.stdmsg, "importall %s\n", m->toChars()); m->importAll(NULL); @@ -1516,9 +1524,9 @@ Language changes listed by -transition=id:\n\ backend_init(); // Do semantic analysis - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; if (global.params.verbose) fprintf(global.stdmsg, "semantic %s\n", m->toChars()); m->semantic(); @@ -1530,9 +1538,9 @@ Language changes listed by -transition=id:\n\ Module::runDeferredSemantic(); // Do pass 2 semantic analysis - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; if (global.params.verbose) fprintf(global.stdmsg, "semantic2 %s\n", m->toChars()); m->semantic2(); @@ -1541,9 +1549,9 @@ Language changes listed by -transition=id:\n\ fatal(); // Do pass 3 semantic analysis - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; if (global.params.verbose) fprintf(global.stdmsg, "semantic3 %s\n", m->toChars()); m->semantic3(); @@ -1593,9 +1601,9 @@ Language changes listed by -transition=id:\n\ // Scan for functions to inline if (global.params.useInline) { - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; if (global.params.verbose) fprintf(global.stdmsg, "inline scan %s\n", m->toChars()); inlineScan(m); @@ -1627,7 +1635,7 @@ Language changes listed by -transition=id:\n\ if (global.params.doXGeneration) { OutBuffer buf; - json_generate(&buf, &modules); + json_generate(&buf, &Module::buildModules); // Write buf to file const char *name = global.params.xfilename; @@ -1672,11 +1680,12 @@ Language changes listed by -transition=id:\n\ if (global.params.oneobj) { - if (modules.dim) - obj_start(modules[0]->srcfile->toChars()); - for (size_t i = 0; i < modules.dim; i++) + if (Module::buildModules.dim) + obj_start(Module::buildModules[0]->srcfile->toChars()); + + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; if (global.params.verbose) fprintf(global.stdmsg, "code %s\n", m->toChars()); m->genobjfile(0); @@ -1685,16 +1694,16 @@ Language changes listed by -transition=id:\n\ if (!global.errors && global.params.doDocComments) m->gendocfile(); } - if (!global.errors && modules.dim) + if (!global.errors && Module::buildModules.dim) { - obj_end(library, modules[0]->objfile); + obj_end(library, Module::buildModules[0]->objfile); } } else { - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - Module *m = modules[i]; + Module *m = Module::buildModules[i]; if (global.params.verbose) fprintf(global.stdmsg, "code %s\n", m->toChars()); if (global.params.obj) @@ -1745,9 +1754,10 @@ Language changes listed by -transition=id:\n\ /* Delete .obj files and .exe file */ - for (size_t i = 0; i < modules.dim; i++) + for (size_t i = 0; i < Module::buildModules.dim; i++) { - modules[i]->deleteObjFile(); + Module *m = Module::buildModules[i]; + m->deleteObjFile(); if (global.params.oneobj) break; } diff --git a/src/mars.h b/src/mars.h index a1fb84fd2995..a1c742ba7fc8 100644 --- a/src/mars.h +++ b/src/mars.h @@ -85,6 +85,8 @@ typedef Array Strings; // Put command line switches in here struct Param { + bool buildRecurse; // build modules recursively + Strings *excludeList; // exclude filters for modules not to be built when building recursively char obj; // write object file char link; // perform link char dll; // generate shared dynamic library diff --git a/src/module.c b/src/module.c index 24e1c90cedbe..9edd75e4a571 100644 --- a/src/module.c +++ b/src/module.c @@ -32,6 +32,7 @@ AggregateDeclaration *Module::moduleinfo; Module *Module::rootModule; DsymbolTable *Module::modules; Modules Module::amodules; +Modules Module::buildModules; Dsymbols Module::deferred; // deferred Dsymbol's needing semantic() run on them Dsymbols Module::deferred3; @@ -191,6 +192,48 @@ const char *Module::kind() return "module"; } +bool isModuleFiltered(Identifiers *packages, Identifier *ident) +{ + char *fullName = ident->toChars(); + if (packages && packages->dim) + { + OutBuffer buf; + for (size_t i = 0; i < packages->dim; i++) + { + Identifier *pid = (*packages)[i]; + buf.writestring(pid->toChars()); + buf.writeByte('.'); + } + + buf.writestring(fullName); + buf.writeByte(0); + fullName = (char *)buf.extractData(); + } + + bool filtered = false; + for (size_t i = 0; i < global.params.excludeList->dim; i++) + { + const char *filter = (*global.params.excludeList)[i]; + + size_t len = strlen(filter); + if (filter[len - 1] == '*') // wildcard + { + if (memcmp(fullName, filter, len - 1) == 0) + { + //printf("-- found: %s filter: %s\n", fullName, filter); + return true; + } + } + else if (strcmp(fullName, filter) == 0) + { + //printf("-- found: %s filter: %s\n", fullName, filter); + return true; + } + } + + return false; +} + Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident) { Module *m; char *filename; @@ -252,6 +295,18 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident) d_gcc_magic_module(m); #endif + // don't build interface file + bool isInterfaceFile = FileName::exists(FileName::forceExt(filename, global.hdr_ext)); + + if (global.params.buildRecurse && !isInterfaceFile) + { + if (!isModuleFiltered(packages, ident)) + { + buildModules.push(m); + m->importedFrom = m; // m->isRoot() == true + } + } + return m; } diff --git a/src/module.h b/src/module.h index 0703acf34b11..0c07ad2acd76 100644 --- a/src/module.h +++ b/src/module.h @@ -63,6 +63,7 @@ class Module : public Package static Module *rootModule; static DsymbolTable *modules; // symbol table of all modules static Modules amodules; // array of all modules + static Modules buildModules; // array of modules to build static Dsymbols deferred; // deferred Dsymbol's needing semantic() run on them static Dsymbols deferred3; // deferred Dsymbol's needing semantic3() run on them static unsigned dprogress; // progress resolving the deferred list diff --git a/test/compilable/extra-files/test9896b.d b/test/compilable/extra-files/test9896b.d new file mode 100644 index 000000000000..20091a78d12d --- /dev/null +++ b/test/compilable/extra-files/test9896b.d @@ -0,0 +1,6 @@ +module test9896b; + +int square(int x) +{ + return x * x; +} diff --git a/test/compilable/imports/test9896a.d b/test/compilable/imports/test9896a.d new file mode 100644 index 000000000000..a0f30979b69b --- /dev/null +++ b/test/compilable/imports/test9896a.d @@ -0,0 +1,6 @@ +module imports.test9896a; + +int square(int x) +{ + return x * x; +} diff --git a/test/compilable/imports/test9896b.di b/test/compilable/imports/test9896b.di new file mode 100644 index 000000000000..2e2a5f49b601 --- /dev/null +++ b/test/compilable/imports/test9896b.di @@ -0,0 +1,3 @@ +module test9896b; + +int square(int x); diff --git a/test/compilable/test9896.d b/test/compilable/test9896.d new file mode 100644 index 000000000000..9d0a6aaf6c07 --- /dev/null +++ b/test/compilable/test9896.d @@ -0,0 +1,11 @@ +// PERMUTE_ARGS: -inline +// REQUIRED_ARGS: -rb +module test9896; + +import imports.test9896a; + +void main() +{ + static assert(square(2) == 4); + assert(square(2) == 4); +} diff --git a/test/compilable/test9896.sh b/test/compilable/test9896.sh new file mode 100755 index 000000000000..16eee7186e52 --- /dev/null +++ b/test/compilable/test9896.sh @@ -0,0 +1,9 @@ +#!/usr/bin/env bash + +dir=${RESULTS_DIR}${DSEP}compilable +src_file=compilable${DSEP}test9896.d +imp_file=compilable${DSEP}imports${DSEP}test9896a.d +object_file=${dir}${DSEP}test9896a${OBJ} + +$DMD -m${MODEL} -c ${imp_file} -of${object_file} +$DMD -Icompilable -rb -rx=object -rx=std.* -rx=core.* -rx=etc.* -rx=imports.* -m${MODEL} ${src_file} ${object_file} diff --git a/test/compilable/test9896a.d b/test/compilable/test9896a.d new file mode 100644 index 000000000000..6a95caa2448b --- /dev/null +++ b/test/compilable/test9896a.d @@ -0,0 +1,12 @@ +// PERMUTE_ARGS: -inline +// REQUIRED_ARGS: -rb -Iimports +// EXTRA_SOURCES: extra-files/test9896b.d +module test9896a; + +/** Ensure .di files are not compiled. */ +import test9896b; + +void main() +{ + assert(square(2) == 4); +}