Skip to content

Commit

Permalink
add eSink to library file generation (#15505)
Browse files Browse the repository at this point in the history
  • Loading branch information
WalterBright authored Aug 13, 2023
1 parent db216af commit 5fb9de2
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 39 deletions.
17 changes: 10 additions & 7 deletions compiler/src/dmd/glue.d
Original file line number Diff line number Diff line change
Expand Up @@ -80,21 +80,21 @@ alias toSymbol = dmd.tocsym.toSymbol;
* libmodules = array of objects/libraries already generated (passed on command line)
* libname = {.lib,.a} file output name
* objdir = directory to write object files to
* lib = write library file instead of object file(s)
* writeLibrary = write library file instead of object file(s)
* obj = generate object files
* oneobj = write one object file instead of multiple ones
* multiobj = break one object file into multiple ones
* verbose = print progress message when generatig code
*/
void generateCodeAndWrite(Module[] modules, const(char)*[] libmodules,
const(char)[] libname, const(char)[] objdir,
bool lib, bool obj, bool oneobj, bool multiobj,
bool writeLibrary, bool obj, bool oneobj, bool multiobj,
bool verbose)
{
Library library = null;
if (lib)
if (writeLibrary)
{
library = Library.factory();
library = Library.factory(target.objectFormat(), target.lib_ext, global.errorSink);
library.setFilename(objdir, libname);
// Add input object and input library files to output library
foreach (p; libmodules)
Expand Down Expand Up @@ -139,12 +139,15 @@ void generateCodeAndWrite(Module[] modules, const(char)*[] libmodules,
genObjFile(m, multiobj);
obj_end(objbuf, library, m.objfile.toChars());
obj_write_deferred(objbuf, library, glue.obj_symbols_towrite);
if (global.errors && !lib)
if (global.errors && !writeLibrary)
m.deleteObjFile();
}
}
if (lib && !global.errors)
library.write();
if (writeLibrary && !global.errors)
{
if (!library.write())
fatal();
}
}

extern (C++):
Expand Down
54 changes: 30 additions & 24 deletions compiler/src/dmd/lib.d
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,8 @@ import core.stdc.stdarg;

import dmd.globals;
import dmd.location;
import dmd.errors;
import dmd.target;
import dmd.errorsink;
import dmd.target : Target;
import dmd.utils;

import dmd.common.outbuffer;
Expand All @@ -35,15 +35,22 @@ private enum LOG = false;

class Library
{
static Library factory()
const(char)[] lib_ext; // library file extension
ErrorSink eSink; // where the error messages go

static Library factory(Target.ObjectFormat of, const char[] lib_ext, ErrorSink eSink)
{
final switch (target.objectFormat())
Library lib;
final switch (of)
{
case Target.ObjectFormat.elf: return LibElf_factory();
case Target.ObjectFormat.macho: return LibMach_factory();
case Target.ObjectFormat.coff: return LibMSCoff_factory();
case Target.ObjectFormat.omf: return LibOMF_factory();
case Target.ObjectFormat.elf: lib = LibElf_factory(); break;
case Target.ObjectFormat.macho: lib = LibMach_factory(); break;
case Target.ObjectFormat.coff: lib = LibMSCoff_factory(); break;
case Target.ObjectFormat.omf: lib = LibOMF_factory(); break;
}
lib.lib_ext = lib_ext;
lib.eSink = eSink;
return lib;
}

abstract void addObject(const(char)[] module_name, const ubyte[] buf);
Expand Down Expand Up @@ -72,46 +79,45 @@ class Library
// Generate lib file name from first obj name
const(char)[] n = global.params.objfiles[0].toDString;
n = FileName.name(n);
arg = FileName.forceExt(n, target.lib_ext);
arg = FileName.forceExt(n, lib_ext);
}
if (!FileName.absolute(arg))
arg = FileName.combine(dir, arg);

loc = Loc(FileName.defaultExt(arg, target.lib_ext).ptr, 0, 0);
loc = Loc(FileName.defaultExt(arg, lib_ext).ptr, 0, 0);
}

final const(char)* getFilename() const
{
return loc.filename;
}

final void write()
/***************************
* Write the library file.
* Returns: false on failure
*/
final bool write()
{
if (global.params.verbose)
message("library %s", loc.filename);
eSink.message(Loc.initial, "library %s", loc.filename);

auto filenameString = loc.filename.toDString;
if (!ensurePathToNameExists(Loc.initial, filenameString))
return;
return false;

auto tmpname = filenameString ~ ".tmp\0";
scope(exit) destroy(tmpname);

auto libbuf = OutBuffer(tmpname.ptr);
WriteLibToBuffer(&libbuf);

if (!libbuf.moveToFile(loc.filename))
{
.error(loc, "error writing file '%s'", loc.filename);
fatal();
eSink.error(loc, "error writing file '%s'", loc.filename);
destroy(tmpname);
return false;
}
}

final void error(const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
.verrorReport(loc, format, ap, ErrorKind.error);
va_end(ap);
destroy(tmpname);
return true;
}

protected:
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dmd/libelf.d
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ final class LibElf : Library

void corrupt(int reason)
{
error("corrupt ELF object module %.*s %d",
eSink.error(loc, "corrupt ELF object module %.*s %d",
cast(int)module_name.length, module_name.ptr, reason);
}

Expand Down Expand Up @@ -324,7 +324,7 @@ final class LibElf : Library
s = tab.lookup(name.ptr, name.length);
assert(s);
ElfObjSymbol* os = s.value;
error("multiple definition of %s: %s and %s: %s", om.name.ptr, name.ptr, os.om.name.ptr, os.name.ptr);
eSink.error(loc, "multiple definition of %s: %s and %s: %s", om.name.ptr, name.ptr, os.om.name.ptr, os.name.ptr);
}
}
else
Expand Down
4 changes: 2 additions & 2 deletions compiler/src/dmd/libmach.d
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ final class LibMach : Library

void corrupt(int reason)
{
error("corrupt Mach object module %.*s %d",
eSink.error(loc, "corrupt Mach object module %.*s %d",
cast(int)module_name.length, module_name.ptr, reason);
}

Expand Down Expand Up @@ -281,7 +281,7 @@ final class LibMach : Library
s = tab.lookup(name.ptr, name.length);
assert(s);
MachObjSymbol* os = cast(MachObjSymbol*)s.ptrvalue;
error("multiple definition of %s: %s and %s: %s", om.name.ptr, name.ptr, os.om.name.ptr, os.name.ptr);
eSink.error(loc, "multiple definition of %s: %s and %s: %s", om.name.ptr, name.ptr, os.om.name.ptr, os.name.ptr);
}
}
else
Expand Down
2 changes: 1 addition & 1 deletion compiler/src/dmd/libmscoff.d
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@ final class LibMSCoff : Library

void corrupt(int reason)
{
error("corrupt MS Coff object module %.*s %d",
eSink.error(loc, "corrupt MS Coff object module %.*s %d",
cast(int)module_name.length, module_name.ptr, reason);
}

Expand Down
6 changes: 3 additions & 3 deletions compiler/src/dmd/libomf.d
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ final class LibOMF : Library

void corrupt(int reason)
{
error("corrupt OMF object module %.*s %d",
eSink.error(loc, "corrupt OMF object module %.*s %d",
cast(int)module_name.length, module_name.ptr, reason);
}

Expand Down Expand Up @@ -132,7 +132,7 @@ final class LibOMF : Library
}
else if (lh.recTyp == '!' && memcmp(lh, "!<arch>\n".ptr, 8) == 0)
{
error("COFF libraries not supported");
eSink.error(loc, "COFF libraries not supported");
return;
}
else
Expand Down Expand Up @@ -197,7 +197,7 @@ final class LibOMF : Library
const s2 = tab.lookup(name);
assert(s2);
const os = s2.value;
error("multiple definition of %.*s: %.*s and %.*s: %s",
eSink.error(loc, "multiple definition of %.*s: %.*s and %.*s: %s",
cast(int)om.name.length, om.name.ptr,
cast(int)name.length, name.ptr,
cast(int)os.om.name.length, os.om.name.ptr, os.name);
Expand Down

0 comments on commit 5fb9de2

Please sign in to comment.