1 /** 2 * A module defining an abstract library. 3 * Implementations for various formats are in separate `libXXX.d` modules. 4 * 5 * Copyright: Copyright (C) 1999-2021 by The D Language Foundation, 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: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/lib.d, _lib.d) 9 * Documentation: https://dlang.org/phobos/dmd_lib.html 10 * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/lib.d 11 */ 12 13 module dmd.lib; 14 15 import core.stdc.stdio; 16 import core.stdc.stdarg; 17 18 import dmd.globals; 19 import dmd.errors; 20 import dmd.utils; 21 22 import dmd.root.outbuffer; 23 import dmd.root.file; 24 import dmd.root.filename; 25 import dmd.root.string; 26 27 static if (TARGET.Windows) 28 { 29 import dmd.libomf; 30 import dmd.libmscoff; 31 } 32 else static if (TARGET.Linux || TARGET.FreeBSD || TARGET.OpenBSD || TARGET.Solaris || TARGET.DragonFlyBSD) 33 { 34 import dmd.libelf; 35 } 36 else static if (TARGET.OSX) 37 { 38 import dmd.libmach; 39 } 40 else 41 { 42 static assert(0, "unsupported system"); 43 } 44 45 private enum LOG = false; 46 47 class Library 48 { 49 static Library factory() 50 { 51 static if (TARGET.Windows) 52 { 53 return (global.params.mscoff || global.params.is64bit) ? LibMSCoff_factory() : LibOMF_factory(); 54 } 55 else static if (TARGET.Linux || TARGET.FreeBSD || TARGET.OpenBSD || TARGET.Solaris || TARGET.DragonFlyBSD) 56 { 57 return LibElf_factory(); 58 } 59 else static if (TARGET.OSX) 60 { 61 return LibMach_factory(); 62 } 63 } 64 65 abstract void addObject(const(char)[] module_name, const ubyte[] buf); 66 67 protected abstract void WriteLibToBuffer(OutBuffer* libbuf); 68 69 70 /*********************************** 71 * Set the library file name based on the output directory 72 * and the filename. 73 * Add default library file name extension. 74 * Params: 75 * dir = path to file 76 * filename = name of file relative to `dir` 77 */ 78 final void setFilename(const(char)[] dir, const(char)[] filename) 79 { 80 static if (LOG) 81 { 82 printf("LibElf::setFilename(dir = '%.*s', filename = '%.*s')\n", 83 cast(int)dir.length, dir.ptr, cast(int)filename.length, filename.ptr); 84 } 85 const(char)[] arg = filename; 86 if (!arg.length) 87 { 88 // Generate lib file name from first obj name 89 const(char)[] n = global.params.objfiles[0].toDString; 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 = Loc(FileName.defaultExt(arg, global.lib_ext).ptr, 0, 0); 97 } 98 99 final const(char)* getFilename() const 100 { 101 return loc.filename; 102 } 103 104 final void write() 105 { 106 if (global.params.verbose) 107 message("library %s", loc.filename); 108 109 OutBuffer libbuf; 110 WriteLibToBuffer(&libbuf); 111 112 writeFile(Loc.initial, loc.filename.toDString, libbuf[]); 113 } 114 115 final void error(const(char)* format, ...) 116 { 117 va_list ap; 118 va_start(ap, format); 119 .verror(loc, format, ap); 120 va_end(ap); 121 } 122 123 protected: 124 Loc loc; // the filename of the library 125 }