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 }