mirror of
https://github.com/dlang/dmd.git
synced 2025-04-26 13:10:12 +03:00
Fix bugzilla 24748 - DMD can't output object files with fully qualified name, making -od overwirte each other file
This commit is contained in:
parent
da9105bc4e
commit
64df340150
9 changed files with 73 additions and 6 deletions
15
changelog/dmd.oq.dd
Normal file
15
changelog/dmd.oq.dd
Normal file
|
@ -0,0 +1,15 @@
|
|||
Add `-oq` switch to DMD
|
||||
|
||||
The switch gives fully qualified names to object files, preventing name conflicts when using the `-od` switch
|
||||
while compiling multiple modules with the same name, but inside different packages.
|
||||
The switch already existed in LDC, but is now in dmd as well.
|
||||
|
||||
Example:
|
||||
|
||||
$(CONSOLE
|
||||
dmd -c -oq -od=. app.d util/app.d misc/app.d
|
||||
)
|
||||
|
||||
This will output `app.obj`, `util.app.obj`, and `misc.app.obj`, instead of just `app.obj`.
|
||||
|
||||
`-oq` also applies to other outputs, such as DDoc (`-D -Dd=.`) and .di header generation (`-H -Hd=.`).
|
|
@ -690,6 +690,12 @@ dmd -cov -unittest myprog.d
|
|||
off when generating an object, interface, or Ddoc file
|
||||
name. $(SWLINK -op) will leave it on.`,
|
||||
),
|
||||
Option("oq",
|
||||
"Write object files with fully qualified file names",
|
||||
`When compiling pkg/app.d, the resulting object file name will be pkg_app.obj
|
||||
instead of app.o. This helps to prevent name conflicts when compiling multiple
|
||||
packages in the same directory with the $(SWLINK -od) flag.`,
|
||||
),
|
||||
Option("os=<os>",
|
||||
"sets target operating system to <os>",
|
||||
`Set the target operating system as other than the host.
|
||||
|
|
|
@ -349,8 +349,8 @@ extern (C++) final class Module : Package
|
|||
const(char)[] arg; // original argument name
|
||||
ModuleDeclaration* md; // if !=null, the contents of the ModuleDeclaration declaration
|
||||
const FileName srcfile; // input source file
|
||||
const FileName objfile; // output .obj file
|
||||
const FileName hdrfile; // 'header' file
|
||||
FileName objfile; // output .obj file
|
||||
FileName hdrfile; // 'header' file
|
||||
FileName docfile; // output documentation file
|
||||
const(ubyte)[] src; /// Raw content of the file
|
||||
uint errors; // if any errors in file
|
||||
|
@ -579,6 +579,22 @@ extern (C++) final class Module : Package
|
|||
argdoc = arg;
|
||||
else
|
||||
argdoc = FileName.name(arg);
|
||||
|
||||
if (global.params.fullyQualifiedObjectFiles)
|
||||
{
|
||||
const fqn = md ? md.toString() : toString();
|
||||
argdoc = FileName.replaceName(argdoc, fqn);
|
||||
|
||||
// add ext, otherwise forceExt will make nested.module into nested.<ext>
|
||||
const bufferLength = argdoc.length + 1 + ext.length + /* null terminator */ 1;
|
||||
char[] s = new char[bufferLength];
|
||||
s[0 .. argdoc.length] = argdoc[];
|
||||
s[argdoc.length] = '.';
|
||||
s[$-1-ext.length .. $-1] = ext[];
|
||||
s[$-1] = 0;
|
||||
argdoc = s;
|
||||
}
|
||||
|
||||
// If argdoc doesn't have an absolute path, make it relative to dir
|
||||
if (!FileName.absolute(argdoc))
|
||||
{
|
||||
|
|
|
@ -7020,8 +7020,8 @@ public:
|
|||
_d_dynamicArray< const char > arg;
|
||||
ModuleDeclaration* md;
|
||||
const FileName srcfile;
|
||||
const FileName objfile;
|
||||
const FileName hdrfile;
|
||||
FileName objfile;
|
||||
FileName hdrfile;
|
||||
FileName docfile;
|
||||
_d_dynamicArray< const uint8_t > src;
|
||||
uint32_t errors;
|
||||
|
@ -8112,6 +8112,7 @@ struct Param final
|
|||
_d_dynamicArray< const char > resfile;
|
||||
_d_dynamicArray< const char > exefile;
|
||||
_d_dynamicArray< const char > mapfile;
|
||||
bool fullyQualifiedObjectFiles;
|
||||
bool timeTrace;
|
||||
uint32_t timeTraceGranularityUs;
|
||||
const char* timeTraceFile;
|
||||
|
@ -8191,12 +8192,13 @@ struct Param final
|
|||
resfile(),
|
||||
exefile(),
|
||||
mapfile(),
|
||||
fullyQualifiedObjectFiles(),
|
||||
timeTrace(false),
|
||||
timeTraceGranularityUs(500u),
|
||||
timeTraceFile()
|
||||
{
|
||||
}
|
||||
Param(bool obj, bool multiobj = false, bool trace = false, bool tracegc = false, bool vcg_ast = false, DiagnosticReporting useDeprecated = (DiagnosticReporting)1u, bool useUnitTests = false, bool useInline = false, bool release = false, bool preservePaths = false, DiagnosticReporting warnings = (DiagnosticReporting)2u, bool cov = false, uint8_t covPercent = 0u, bool ctfe_cov = false, bool ignoreUnsupportedPragmas = true, bool useModuleInfo = true, bool useTypeInfo = true, bool useExceptions = true, bool useGC = true, bool betterC = false, bool addMain = false, bool allInst = false, bool bitfields = false, CppStdRevision cplusplus = (CppStdRevision)201103u, Help help = Help(), Verbose v = Verbose(), FeatureState useDIP25 = (FeatureState)2u, FeatureState useDIP1000 = (FeatureState)0u, bool ehnogc = false, bool useDIP1021 = false, FeatureState fieldwise = (FeatureState)0u, bool fixAliasThis = false, FeatureState rvalueRefParam = (FeatureState)0u, FeatureState noSharedAccess = (FeatureState)0u, bool previewIn = false, bool inclusiveInContracts = false, bool shortenedMethods = true, bool fixImmutableConv = false, bool fix16997 = true, FeatureState dtorFields = (FeatureState)0u, FeatureState systemVariables = (FeatureState)0u, CHECKENABLE useInvariants = (CHECKENABLE)0u, CHECKENABLE useIn = (CHECKENABLE)0u, CHECKENABLE useOut = (CHECKENABLE)0u, CHECKENABLE useArrayBounds = (CHECKENABLE)0u, CHECKENABLE useAssert = (CHECKENABLE)0u, CHECKENABLE useSwitchError = (CHECKENABLE)0u, CHECKENABLE boundscheck = (CHECKENABLE)0u, CHECKACTION checkAction = (CHECKACTION)0u, CLIIdentifierTable dIdentifierTable = (CLIIdentifierTable)0u, CLIIdentifierTable cIdentifierTable = (CLIIdentifierTable)0u, _d_dynamicArray< const char > argv0 = {}, Array<const char* > modFileAliasStrings = Array<const char* >(), Array<const char* > imppath = Array<const char* >(), Array<const char* > fileImppath = Array<const char* >(), _d_dynamicArray< const char > objdir = {}, _d_dynamicArray< const char > objname = {}, _d_dynamicArray< const char > libname = {}, Output ddoc = Output(), Output dihdr = Output(), Output cxxhdr = Output(), Output json = Output(), JsonFieldFlags jsonFieldFlags = (JsonFieldFlags)0u, Output makeDeps = Output(), Output mixinOut = Output(), Output moduleDeps = Output(), uint32_t debuglevel = 0u, uint32_t versionlevel = 0u, bool run = false, Array<const char* > runargs = Array<const char* >(), Array<const char* > cppswitches = Array<const char* >(), const char* cpp = nullptr, Array<const char* > objfiles = Array<const char* >(), Array<const char* > linkswitches = Array<const char* >(), Array<bool > linkswitchIsForCC = Array<bool >(), Array<const char* > libfiles = Array<const char* >(), Array<const char* > dllfiles = Array<const char* >(), _d_dynamicArray< const char > deffile = {}, _d_dynamicArray< const char > resfile = {}, _d_dynamicArray< const char > exefile = {}, _d_dynamicArray< const char > mapfile = {}, bool timeTrace = false, uint32_t timeTraceGranularityUs = 500u, const char* timeTraceFile = nullptr) :
|
||||
Param(bool obj, bool multiobj = false, bool trace = false, bool tracegc = false, bool vcg_ast = false, DiagnosticReporting useDeprecated = (DiagnosticReporting)1u, bool useUnitTests = false, bool useInline = false, bool release = false, bool preservePaths = false, DiagnosticReporting warnings = (DiagnosticReporting)2u, bool cov = false, uint8_t covPercent = 0u, bool ctfe_cov = false, bool ignoreUnsupportedPragmas = true, bool useModuleInfo = true, bool useTypeInfo = true, bool useExceptions = true, bool useGC = true, bool betterC = false, bool addMain = false, bool allInst = false, bool bitfields = false, CppStdRevision cplusplus = (CppStdRevision)201103u, Help help = Help(), Verbose v = Verbose(), FeatureState useDIP25 = (FeatureState)2u, FeatureState useDIP1000 = (FeatureState)0u, bool ehnogc = false, bool useDIP1021 = false, FeatureState fieldwise = (FeatureState)0u, bool fixAliasThis = false, FeatureState rvalueRefParam = (FeatureState)0u, FeatureState noSharedAccess = (FeatureState)0u, bool previewIn = false, bool inclusiveInContracts = false, bool shortenedMethods = true, bool fixImmutableConv = false, bool fix16997 = true, FeatureState dtorFields = (FeatureState)0u, FeatureState systemVariables = (FeatureState)0u, CHECKENABLE useInvariants = (CHECKENABLE)0u, CHECKENABLE useIn = (CHECKENABLE)0u, CHECKENABLE useOut = (CHECKENABLE)0u, CHECKENABLE useArrayBounds = (CHECKENABLE)0u, CHECKENABLE useAssert = (CHECKENABLE)0u, CHECKENABLE useSwitchError = (CHECKENABLE)0u, CHECKENABLE boundscheck = (CHECKENABLE)0u, CHECKACTION checkAction = (CHECKACTION)0u, CLIIdentifierTable dIdentifierTable = (CLIIdentifierTable)0u, CLIIdentifierTable cIdentifierTable = (CLIIdentifierTable)0u, _d_dynamicArray< const char > argv0 = {}, Array<const char* > modFileAliasStrings = Array<const char* >(), Array<const char* > imppath = Array<const char* >(), Array<const char* > fileImppath = Array<const char* >(), _d_dynamicArray< const char > objdir = {}, _d_dynamicArray< const char > objname = {}, _d_dynamicArray< const char > libname = {}, Output ddoc = Output(), Output dihdr = Output(), Output cxxhdr = Output(), Output json = Output(), JsonFieldFlags jsonFieldFlags = (JsonFieldFlags)0u, Output makeDeps = Output(), Output mixinOut = Output(), Output moduleDeps = Output(), uint32_t debuglevel = 0u, uint32_t versionlevel = 0u, bool run = false, Array<const char* > runargs = Array<const char* >(), Array<const char* > cppswitches = Array<const char* >(), const char* cpp = nullptr, Array<const char* > objfiles = Array<const char* >(), Array<const char* > linkswitches = Array<const char* >(), Array<bool > linkswitchIsForCC = Array<bool >(), Array<const char* > libfiles = Array<const char* >(), Array<const char* > dllfiles = Array<const char* >(), _d_dynamicArray< const char > deffile = {}, _d_dynamicArray< const char > resfile = {}, _d_dynamicArray< const char > exefile = {}, _d_dynamicArray< const char > mapfile = {}, bool fullyQualifiedObjectFiles = false, bool timeTrace = false, uint32_t timeTraceGranularityUs = 500u, const char* timeTraceFile = nullptr) :
|
||||
obj(obj),
|
||||
multiobj(multiobj),
|
||||
trace(trace),
|
||||
|
@ -8278,6 +8280,7 @@ struct Param final
|
|||
resfile(resfile),
|
||||
exefile(exefile),
|
||||
mapfile(mapfile),
|
||||
fullyQualifiedObjectFiles(fullyQualifiedObjectFiles),
|
||||
timeTrace(timeTrace),
|
||||
timeTraceGranularityUs(timeTraceGranularityUs),
|
||||
timeTraceFile(timeTraceFile)
|
||||
|
|
|
@ -248,6 +248,8 @@ extern (C++) struct Param
|
|||
const(char)[] exefile;
|
||||
const(char)[] mapfile;
|
||||
|
||||
bool fullyQualifiedObjectFiles; // prepend module names to object files to prevent name conflicts with -od
|
||||
|
||||
// Time tracing
|
||||
bool timeTrace = false; /// Whether profiling of compile time is enabled
|
||||
uint timeTraceGranularityUs = 500; /// In microseconds, minimum event size to report
|
||||
|
|
|
@ -250,6 +250,10 @@ struct Param
|
|||
DString resfile;
|
||||
DString exefile;
|
||||
DString mapfile;
|
||||
bool fullyQualifiedObjectFiles;
|
||||
bool timeTrace;
|
||||
uint32_t timeTraceGranularityUs;
|
||||
const char* timeTraceFile;
|
||||
};
|
||||
|
||||
struct structalign_t
|
||||
|
|
|
@ -453,6 +453,17 @@ private int tryMain(size_t argc, const(char)** argv, ref Param params)
|
|||
// m.deleteObjFile();
|
||||
|
||||
m.parse();
|
||||
|
||||
// Finalize output filenames. Update if `-oq` was specified (only feasible after parsing).
|
||||
if (params.fullyQualifiedObjectFiles && m.md)
|
||||
{
|
||||
m.objfile = m.setOutfilename(params.objname, params.objdir, m.arg, FileName.ext(m.objfile.toString()));
|
||||
if (m.docfile)
|
||||
m.setDocfile();
|
||||
if (m.hdrfile)
|
||||
m.hdrfile = m.setOutfilename(params.dihdr.name, params.dihdr.dir, m.arg, hdr_ext);
|
||||
}
|
||||
|
||||
if (m.filetype == FileType.dhdr)
|
||||
{
|
||||
// Remove m's object file from list of object files
|
||||
|
|
|
@ -1286,6 +1286,11 @@ bool parseCommandLine(const ref Strings arguments, const size_t argc, ref Param
|
|||
goto Lerror;
|
||||
params.preservePaths = true;
|
||||
break;
|
||||
case 'q':
|
||||
if (p[3])
|
||||
goto Lerror;
|
||||
params.fullyQualifiedObjectFiles = true;
|
||||
break;
|
||||
case 0:
|
||||
error("-o no longer supported, use -of or -od");
|
||||
break;
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
# -Xf=<filename>
|
||||
|
||||
src_file=${OUTPUT_BASE}/src.d
|
||||
src_file_in_pkg=${OUTPUT_BASE}/pkg/src.d
|
||||
|
||||
clean()
|
||||
{
|
||||
|
@ -26,6 +27,8 @@ prepare()
|
|||
mkdir -p ${OUTPUT_BASE}
|
||||
echo "module mymod;" > ${OUTPUT_BASE}/mymod.d
|
||||
echo "module src; import mymod;" > ${src_file}
|
||||
mkdir ${OUTPUT_BASE}/pkg
|
||||
echo "module pkg.src;" > ${src_file_in_pkg}
|
||||
}
|
||||
|
||||
die()
|
||||
|
@ -59,7 +62,9 @@ $DMD -o- -od=${OUTPUT_BASE} -D -Df=${OUTPUT_BASE}/src.html -Hf=${OUTPUT_BASE}/sr
|
|||
checkFiles;
|
||||
|
||||
prepare;
|
||||
$DMD -o- -od=${OUTPUT_BASE} -D -Dd=${OUTPUT_BASE} -Hd=${OUTPUT_BASE} -I=${OUTPUT_BASE} -L=-v -Xf=${OUTPUT_BASE}/json.json ${src_file}
|
||||
$DMD -o- -oq -od=${OUTPUT_BASE} -D -Dd=${OUTPUT_BASE} -Hd=${OUTPUT_BASE} -I=${OUTPUT_BASE} -L=-v -Xf=${OUTPUT_BASE}/json.json ${src_file} ${src_file_in_pkg}
|
||||
checkFiles;
|
||||
checkFile ${OUTPUT_BASE}/pkg.src.di
|
||||
checkFile ${OUTPUT_BASE}/pkg.src.html
|
||||
|
||||
clean;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue