ziglang/zig

ability to create import libs from def files without LLVM

andrewrk opened this issue · 0 comments

Here we have a dependency on

zig/src/mingw.zig

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:

zig/src/zig_llvm.cpp

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.