Skip to content

ability to create import libs from def files without LLVM #17807

Open
@andrewrk

Description

@andrewrk

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    contributor friendlyThis issue is limited in scope and/or knowledge of Zig internals.enhancementSolving this issue will likely involve adding new logic or components to the codebase.linkingos-windows

    Type

    No type

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions