ability to create import libs from def files without LLVM
andrewrk opened this issue · 0 comments
andrewrk commented
Here we have a dependency on
Lines 413 to 417 in 8457439
if (llvm_bindings.WriteImportLibrary(def_final_path_z.ptr, arch_tag, lib_final_path_z.ptr, true)) { | |
// TODO surface a proper error here | |
log.err("unable to turn {s}.def into {s}.lib", .{ lib_name, lib_name }); | |
return error.WritingImportLibFailed; | |
} |
which ultimately calls into this code:
Lines 988 to 1065 in 8457439
bool ZigLLVMWriteImportLibrary(const char *def_path, const ZigLLVM_ArchType arch, | |
const char *output_lib_path, bool kill_at) | |
{ | |
COFF::MachineTypes machine = COFF::IMAGE_FILE_MACHINE_UNKNOWN; | |
switch (arch) { | |
case ZigLLVM_x86: | |
machine = COFF::IMAGE_FILE_MACHINE_I386; | |
break; | |
case ZigLLVM_x86_64: | |
machine = COFF::IMAGE_FILE_MACHINE_AMD64; | |
break; | |
case ZigLLVM_arm: | |
case ZigLLVM_armeb: | |
case ZigLLVM_thumb: | |
case ZigLLVM_thumbeb: | |
machine = COFF::IMAGE_FILE_MACHINE_ARMNT; | |
break; | |
case ZigLLVM_aarch64: | |
case ZigLLVM_aarch64_be: | |
machine = COFF::IMAGE_FILE_MACHINE_ARM64; | |
break; | |
default: | |
break; | |
} | |
if (machine == COFF::IMAGE_FILE_MACHINE_UNKNOWN) { | |
return true; | |
} | |
auto bufOrErr = MemoryBuffer::getFile(def_path); | |
if (!bufOrErr) { | |
return false; | |
} | |
MemoryBuffer& buf = *bufOrErr.get(); | |
Expected<object::COFFModuleDefinition> def = | |
object::parseCOFFModuleDefinition(buf, machine, /* MingwDef */ true); | |
if (!def) { | |
return true; | |
} | |
// The exports-juggling code below is ripped from LLVM's DllToolDriver.cpp | |
// If ExtName is set (if the "ExtName = Name" syntax was used), overwrite | |
// Name with ExtName and clear ExtName. When only creating an import | |
// library and not linking, the internal name is irrelevant. This avoids | |
// cases where writeImportLibrary tries to transplant decoration from | |
// symbol decoration onto ExtName. | |
for (object::COFFShortExport& E : def->Exports) { | |
if (!E.ExtName.empty()) { | |
E.Name = E.ExtName; | |
E.ExtName.clear(); | |
} | |
} | |
if (machine == COFF::IMAGE_FILE_MACHINE_I386 && kill_at) { | |
for (object::COFFShortExport& E : def->Exports) { | |
if (!E.AliasTarget.empty() || (!E.Name.empty() && E.Name[0] == '?')) | |
continue; | |
E.SymbolName = E.Name; | |
// Trim off the trailing decoration. Symbols will always have a | |
// starting prefix here (either _ for cdecl/stdcall, @ for fastcall | |
// or ? for C++ functions). Vectorcall functions won't have any | |
// fixed prefix, but the function base name will still be at least | |
// one char. | |
E.Name = E.Name.substr(0, E.Name.find('@', 1)); | |
// By making sure E.SymbolName != E.Name for decorated symbols, | |
// writeImportLibrary writes these symbols with the type | |
// IMPORT_NAME_UNDECORATE. | |
} | |
} | |
return static_cast<bool>( | |
object::writeImportLibrary(def->OutputFile, output_lib_path, | |
def->Exports, machine, /* MinGW */ true)); | |
} |
which is using the LLVM C++ API.
Instead, the zig compiler needs to directly support creating import libraries from .def files in order to eliminate this dependency on LLVM.