https://issues.dlang.org/show_bug.cgi?id=4071
--- Comment #14 from Walter Bright <bugzi...@digitalmars.com> --- Rainer's add options -exportall and -sharedlib to dmd Index: backend/cdef.h =================================================================== --- backend/cdef.h (revision 431) +++ backend/cdef.h (working copy) @@ -675,6 +675,7 @@ # define WFsaveds 0x2000 // use push/pop DS for far functions # define WFdsnedgroup 0x4000 // DS != DGROUP # define WFexe 0x8000 // generating code for Windows EXE +# define WFexpall 0x10000 // generate export definition for all symbols char inline8087; /* 0: emulator 1: IEEE 754 inline 8087 code Index: backend/cgobj.c =================================================================== --- backend/cgobj.c (revision 431) +++ backend/cgobj.c (working copy) @@ -2285,16 +2285,20 @@ { char *coment; size_t len; - coment = (char *) alloca(4 + 1 + (IDMAX + IDOHD) + 1); // allow extra byte for mangling + coment = (char *) alloca(4 + 1 + (2*IDMAX + IDOHD) + 1); // allow extra byte for mangling len = obj_mangle(s,&coment[4]); assert(len <= IDMAX + IDOHD); - coment[1] = 0xA0; // comment class - coment[2] = 2; // why??? who knows - if (argsize >= 64) // we only have a 5 bit field - argsize = 0; // hope we don't need callgate - coment[3] = (argsize + 1) >> 1; // # words on stack - coment[4 + len] = 0; // no internal name - objrecord(COMENT,coment,4 + len + 1); // module name record + coment[0] = 0x80; // comment type (no purge bit set) + coment[1] = 0xA0; // comment class + coment[2] = 2; // why??? who knows + if (argsize >= 64) // we only have a 5 bit field + argsize = 0; // hope we don't need callgate + coment[3] = (argsize + 1) >> 1; // # words on stack + if(config.wflags & WFexpall) + len += obj_mangle(s,coment+4+len); // workaround for linker inconsistently removing first char + else + coment[4 + len++] = 0; // no internal name + objrecord(COMENT,coment,4 + len); // module name record } /******************************** Index: backend/out.c =================================================================== --- backend/out.c (revision 431) +++ backend/out.c (working copy) @@ -141,6 +141,8 @@ ty = s->ty(); if (ty & mTYexport && config.wflags & WFexpdef && s->Sclass != SCstatic) obj_export(s,0); // export data definition + else if(config.wflags & WFexpall && type_mangle(s->Stype)) + obj_export(s,0); // export data definition for (dt = dtstart; dt; dt = dt->DTnext) { //printf("dt = x%p, dt = %d\n",dt,dt->dt); @@ -1436,6 +1438,8 @@ !(sfunc->Sclass == SCinline && !(config.flags2 & CFG2comdat)) && sfunc->ty() & mTYexport) obj_export(sfunc,Poffset); // export function definition + else if(config.wflags & WFexpall && type_mangle(sfunc->Stype)) + obj_export(sfunc,Poffset); // export function definition if (config.fulltypes) cv_func(sfunc); // debug info for function Index: glue.c =================================================================== --- glue.c (revision 431) +++ glue.c (working copy) @@ -610,8 +610,11 @@ else if (strcmp(s->Sident, "main") == 0 && linkage == LINKc) { #if TARGET_WINDOS - objextdef("__acrtused_con"); // bring in C startup code - obj_includelib("snn.lib"); // bring in C runtime library + objextdef("__acrtused_con"); // bring in C startup code + if(global.params.sharedlib) + obj_includelib("snn_shared.lib"); // bring in shared part of C runtime library + else + obj_includelib("snn.lib"); // bring in C runtime library #endif s->Sclass = SCglobal; } Index: mars.c =================================================================== --- mars.c (revision 431) +++ mars.c (working copy) @@ -165,7 +165,7 @@ #endif fprintf(stdmsg, "\n"); fflush(stdmsg); -//halt(); +halt(); } global.errors++; } @@ -216,7 +216,7 @@ */ void halt() { -#ifdef DEBUG +#if 0 //def DEBUG *(char*)0=0; #endif } @@ -254,6 +254,7 @@ -debuglib=name set symbolic debug library to name\n\ -defaultlib=name set default library to name\n\ -deps=filename write module dependencies to filename\n%s\ + -exportall export any suitable public symbol\n\ -g add symbolic debug info\n\ -gc add symbolic debug info, pretend to be C\n\ -H generate 'header' file\n\ @@ -279,6 +280,7 @@ -quiet suppress unnecessary messages\n\ -release compile release version\n\ -run srcfile args... run resulting program, passing args\n\ + -sharedlib link against shared runtime library\n\ -unittest compile in unit tests\n\ -v verbose\n\ -version=level compile in version code >= level\n\ @@ -301,6 +303,7 @@ int status = EXIT_SUCCESS; int argcstart = argc; int setdebuglib = 0; + int setdefaultlib = 0; char noboundscheck = 0; const char *inifilename = NULL; @@ -659,6 +662,7 @@ } else if (memcmp(p + 1, "defaultlib=", 11) == 0) { + setdefaultlib = 1; global.params.defaultlibname = p + 1 + 11; } else if (memcmp(p + 1, "debuglib=", 9) == 0) @@ -668,13 +672,21 @@ } else if (memcmp(p + 1, "deps=", 5) == 0) { - global.params.moduleDepsFile = p + 1 + 5; - if (!global.params.moduleDepsFile[0]) - goto Lnoarg; - global.params.moduleDeps = new OutBuffer; - } - else if (memcmp(p + 1, "man", 3) == 0) - { + global.params.moduleDepsFile = p + 1 + 5; + if (!global.params.moduleDepsFile[0]) + goto Lnoarg; + global.params.moduleDeps = new OutBuffer; + } + else if (memcmp(p + 1, "exportall", 9) == 0) + { + global.params.exportall = true; + } + else if (memcmp(p + 1, "sharedlib", 9) == 0) + { + global.params.sharedlib = true; + } + else if (memcmp(p + 1, "man", 3) == 0) + { #if _WIN32 #if DMDV1 browse("http://www.digitalmars.com/d/1.0/dmd-windows.html"); @@ -753,6 +765,8 @@ return EXIT_FAILURE; } + if (!setdefaultlib) + global.params.defaultlibname = global.params.sharedlib ? "phobos_shared" : "phobos"; if (!setdebuglib) global.params.debuglibname = global.params.defaultlibname; @@ -805,9 +819,11 @@ global.params.libname = global.params.objname; global.params.objname = NULL; - // Haven't investigated handling these options with multiobj - if (!global.params.cov && !global.params.trace) - global.params.multiobj = 1; + // Haven't investigated handling these options with multiobj + // multiobj causes class/struct debug info to be attached to init-data, + // but this will not be linked into the executable, so this info is lost + if (!global.params.cov && !global.params.trace && !global.params.symdebug) + global.params.multiobj = 1; } else if (global.params.run) { @@ -851,6 +867,8 @@ if (global.params.useUnitTests) VersionCondition::addPredefinedGlobalIdent("unittest"); #endif + if(global.params.sharedlib) + VersionCondition::addPredefinedGlobalIdent("sharedlib"); // Initialization Type::init(); Index: mars.h =================================================================== --- mars.h (revision 431) +++ mars.h (working copy) @@ -159,6 +159,8 @@ char nofloat; // code should not pull in floating point support char Dversion; // D version number char ignoreUnsupportedPragmas; // rather than error on them + char exportall; // export any suitable symbol + char sharedlib; // link against the shared version of phobos.lib and snn.lib char *argv0; // program name Array *imppath; // array of char*'s of where to look for import modules Index: msc.c =================================================================== --- msc.c (revision 431) +++ msc.c (working copy) @@ -67,6 +67,8 @@ if (len >= 4 && stricmp(params->exefile + len - 3, "exe") == 0) config.wflags |= WFexe; } + if(params->exportall) + config.wflags |= WFexpall; config.flags4 |= CFG4underscore; #endif #if TARGET_LINUX --