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