-
-
Notifications
You must be signed in to change notification settings - Fork 594
/
lib.d
144 lines (125 loc) · 3.78 KB
/
lib.d
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
/**
* Compiler implementation of the
* $(LINK2 http://www.dlang.org, D programming language).
*
* Copyright: Copyright (C) 1999-2018 by The D Language Foundation, All Rights Reserved
* Authors: $(LINK2 http://www.digitalmars.com, Walter Bright)
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/lib.d, _lib.d)
* Documentation: https://dlang.org/phobos/dmd_lib.html
* Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/lib.d
*/
module dmd.lib;
import core.stdc.stdio;
import core.stdc.stdarg;
import dmd.globals;
import dmd.errors;
import dmd.utils;
import dmd.root.outbuffer;
import dmd.root.file;
import dmd.root.filename;
static if (TARGET.Windows)
{
import dmd.libomf;
import dmd.libmscoff;
}
else static if (TARGET.Linux || TARGET.FreeBSD || TARGET.OpenBSD || TARGET.Solaris || TARGET.DragonFlyBSD)
{
import dmd.libelf;
}
else static if (TARGET.OSX)
{
import dmd.libmach;
}
else
{
static assert(0, "unsupported system");
}
enum LOG = false;
class Library
{
static Library factory()
{
static if (TARGET.Windows)
{
return (global.params.mscoff || global.params.is64bit) ? LibMSCoff_factory() : LibOMF_factory();
}
else static if (TARGET.Linux || TARGET.FreeBSD || TARGET.OpenBSD || TARGET.Solaris || TARGET.DragonFlyBSD)
{
return LibElf_factory();
}
else static if (TARGET.OSX)
{
return LibMach_factory();
}
else
{
assert(0); // unsupported system
}
}
abstract void addObject(const(char)* module_name, const ubyte[] buf);
protected abstract void WriteLibToBuffer(OutBuffer* libbuf);
/***********************************
* Set the library file name based on the output directory
* and the filename.
* Add default library file name extension.
* Params:
* dir = path to file
* filename = name of file relative to `dir`
*/
final void setFilename(const(char)* dir, const(char)* filename)
{
static if (LOG)
{
printf("LibElf::setFilename(dir = '%s', filename = '%s')\n", dir ? dir : "", filename ? filename : "");
}
const(char)* arg = filename;
if (!arg || !*arg)
{
// Generate lib file name from first obj name
const(char)* n = global.params.objfiles[0];
n = FileName.name(n);
arg = FileName.forceExt(n, global.lib_ext);
}
if (!FileName.absolute(arg))
arg = FileName.combine(dir, arg);
loc.filename = FileName.defaultExt(arg, global.lib_ext);
loc.linnum = 0;
loc.charnum = 0;
}
final void write()
{
if (global.params.verbose)
message("library %s", loc.filename);
OutBuffer libbuf;
WriteLibToBuffer(&libbuf);
// Transfer image to file
File* libfile = File.create(loc.filename);
libfile.setbuffer(libbuf.data, libbuf.offset);
libbuf.extractData();
ensurePathToNameExists(Loc.initial, libfile.name.toChars());
writeFile(Loc.initial, libfile);
}
final void error(const(char)* format, ...)
{
va_list ap;
va_start(ap, format);
.verror(loc, format, ap);
va_end(ap);
}
protected:
Loc loc; // the filename of the library
}
version (D_LP64)
alias cpp_size_t = size_t;
else version (OSX)
{
import core.stdc.config : cpp_ulong;
alias cpp_size_t = cpp_ulong;
}
else
alias cpp_size_t = size_t;
extern (C++) void addObjectToLibrary(Library lib, const(char)* module_name, const(ubyte)* buf, cpp_size_t buflen)
{
lib.addObject(module_name, buf[0 .. buflen]);
}