Zig: Link errors when linking with C static library (GLFW) on Windows

Created on 17 Jul 2019  路  10Comments  路  Source: ziglang/zig

lld: error: undefined symbol: __imp_strncpy
>>> referenced by glfw3.lib(window.obj):(glfwWindowHintString)

lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(window.obj):($LN20)

lld: warning: glfw3.lib(window.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: warning: glfw3.lib(context.obj): locally defined symbol imported: strncmp (defined in libucrtd.lib(strncmp.obj)) [LNK4217]
lld: warning: glfw3.lib(context.obj): locally defined symbol imported: __stdio_common_vsscanf (defined in libucrtd.lib(input.obj)) [LNK4217]
lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(init.obj):($LN40)
>>> referenced by glfw3.lib(init.obj):($LN9)

etc.

Most helpful comment

I think these settings will be generally better because you will produce executables with no dependencies that are easier to ship to your users

All 10 comments

Please provide more information. What build command or build script are you using?

build.zig:

const build_ = @import("std").build;
const Builder = build_.Builder;

pub fn build(b: *Builder) void {
    const mode = b.standardReleaseOptions();

    const exe = b.addExecutable("test", "main.zig");
    exe.setBuildMode(mode);

    exe.linkSystemLibrary("c");
    exe.linkSystemLibrary("glfw3");
    exe.linkSystemLibrary("kernel32");
    exe.linkSystemLibrary("user32");
    exe.linkSystemLibrary("gdi32");
    exe.linkSystemLibrary("winspool");
    exe.linkSystemLibrary("shell32");
    exe.linkSystemLibrary("ole32");
    exe.linkSystemLibrary("oleaut32");
    exe.linkSystemLibrary("uuid");
    exe.linkSystemLibrary("comdlg32");
    exe.linkSystemLibrary("advapi32");

    b.installArtifact(exe);

    const run = b.step("run", "");
    run.dependOn(&exe.step);

    b.default_step.dependOn(run);
}

main.zig:

extern fn glfwInit() void;
extern fn glfwCreateWindow(u32, u32, [*c]const u8, usize, usize) usize;
extern fn glfwWindowShouldClose(usize) bool;
extern fn glfwWaitEvents() void;

pub fn main() void {
    glfwInit();
    const w = glfwCreateWindow(300, 300, c"test", 0, 0);
    while (!glfwWindowShouldClose(w)) {
        glfwWaitEvents();
    }
}

output:

C:\Users\Daniel\Desktop\bug>zig build
lld: error: undefined symbol: __imp_strncpy
>>> referenced by glfw3.lib(window.obj):(glfwWindowHintString)

lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(window.obj):($LN20)

lld: warning: glfw3.lib(window.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(init.obj):($LN40)
>>> referenced by glfw3.lib(init.obj):($LN9)

lld: warning: glfw3.lib(init.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: warning: glfw3.lib(init.obj): locally defined symbol imported: __stdio_common_vsprintf (defined in libucrtd.lib(output.obj)) [LNK4217]
lld: warning: glfw3.lib(context.obj): locally defined symbol imported: strncmp (defined in libucrtd.lib(strncmp.obj)) [LNK4217]
lld: error: undefined symbol: __imp___stdio_common_vsscanf
>>> referenced by glfw3.lib(context.obj):($LN6)

lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(win32_window.obj):($LN128)
>>> referenced by glfw3.lib(win32_window.obj):($LN130)
>>> referenced by glfw3.lib(win32_window.obj):($LN130)

lld: warning: glfw3.lib(win32_window.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: error: undefined symbol: __imp_strcspn
>>> referenced by glfw3.lib(input.obj):($LN45)
>>> referenced by glfw3.lib(input.obj):($LN45)
>>> referenced by glfw3.lib(input.obj):(parseMapping)
>>> referenced by glfw3.lib(input.obj):(parseMapping)
>>> referenced by glfw3.lib(input.obj):(parseMapping)

lld: warning: glfw3.lib(input.obj): locally defined symbol imported: strncmp (defined in libucrtd.lib(strncmp.obj)) [LNK4217]
lld: error: undefined symbol: __imp_strncpy
>>> referenced by glfw3.lib(input.obj):($LN84)

lld: error: undefined symbol: __imp_strspn
>>> referenced by glfw3.lib(input.obj):($LN45)
>>> referenced by glfw3.lib(input.obj):(parseMapping)

lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(input.obj):($LN7)
>>> referenced by glfw3.lib(input.obj):($LN9)
>>> referenced by glfw3.lib(input.obj):($LN84)
>>> referenced by glfw3.lib(input.obj):($LN84)
>>> referenced by glfw3.lib(input.obj):($LN84)

lld: warning: glfw3.lib(input.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: error: undefined symbol: __imp_realloc
>>> referenced by glfw3.lib(input.obj):($LN45)

lld: warning: glfw3.lib(input.obj): locally defined symbol imported: strtoul (defined in libucrtd.lib(strtox.obj)) [LNK4217]
lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(win32_init.obj):($LN7)
>>> referenced by glfw3.lib(win32_init.obj):($LN7)

lld: warning: glfw3.lib(win32_init.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(win32_monitor.obj):($LN67)
>>> referenced by glfw3.lib(win32_monitor.obj):($LN33)

lld: warning: glfw3.lib(win32_monitor.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: error: undefined symbol: __imp_realloc
>>> referenced by glfw3.lib(win32_monitor.obj):($LN33)

lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(monitor.obj):($LN28)
>>> referenced by glfw3.lib(monitor.obj):($LN6)
>>> referenced by glfw3.lib(monitor.obj):($LN4)
>>> referenced by glfw3.lib(monitor.obj):($LN4)
>>> referenced by glfw3.lib(monitor.obj):($LN4)

lld: warning: glfw3.lib(monitor.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: error: undefined symbol: __imp_realloc
>>> referenced by glfw3.lib(monitor.obj):($LN36)

lld: warning: glfw3.lib(monitor.obj): locally defined symbol imported: qsort (defined in libucrtd.lib(qsort.obj)) [LNK4217]
lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(vulkan.obj):($LN37)

lld: warning: glfw3.lib(vulkan.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: error: undefined symbol: __imp_strncpy
>>> referenced by glfw3.lib(win32_joystick.obj):($LN5)

lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(win32_joystick.obj):(deviceCallback)
>>> referenced by glfw3.lib(win32_joystick.obj):(deviceCallback)

lld: warning: glfw3.lib(win32_joystick.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: warning: glfw3.lib(win32_joystick.obj): locally defined symbol imported: qsort (defined in libucrtd.lib(qsort.obj)) [LNK4217]
lld: warning: glfw3.lib(win32_joystick.obj): locally defined symbol imported: __stdio_common_vsprintf (defined in libucrtd.lib(output.obj)) [LNK4217]
lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(wgl_context.obj):(choosePixelFormat)

lld: warning: glfw3.lib(wgl_context.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: warning: glfw3.lib(egl_context.obj): locally defined symbol imported: strncmp (defined in libucrtd.lib(strncmp.obj)) [LNK4217]
lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(egl_context.obj):(chooseEGLConfig)
>>> referenced by glfw3.lib(egl_context.obj):(chooseEGLConfig)

lld: warning: glfw3.lib(egl_context.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]
lld: error: undefined symbol: __imp_calloc
>>> referenced by glfw3.lib(osmesa_context.obj):(makeContextCurrentOSMesa)

lld: warning: glfw3.lib(osmesa_context.obj): locally defined symbol imported: free (defined in libucrtd.lib(free.obj)) [LNK4217]

The following command exited with error code 1:
C:\Users\Daniel\zig\zig.exe build-exe C:\Users\Daniel\Desktop\bug\main.zig --library c --library glfw3 --library kernel32 --library user32 --library gdi32 --library winspool --library shell32 --library ole32 --library oleaut32 --library uuid --library comdlg32 --library advapi32 --cache-dir C:\Users\Daniel\Desktop\bug\zig-cache --name test --cache on

Build failed. The following command failed:
C:\Users\Daniel\Desktop\bug\zig-cache\o\_UWqb4JCHlWSVdtHxh94Onf2kfwnYfFSWkFAX-E0Sv4671a37IAWdRkE_-yEdcdR\build.exe C:\Users\Daniel\zig\zig.exe C:\Users\Daniel\Desktop\bug C:\Users\Daniel\Desktop\bug\zig-cache

This builds and runs successfully with zig 0.4.0+d39dcd6d but fails to compile with zig 0.4.0+c0b4121f.

Do you have a source build of Zig? Willing to test a change for me?

--- a/src/target.cpp
+++ b/src/target.cpp
@@ -1477,9 +1477,9 @@ ZigLLVM_EnvironmentType target_default_abi(ZigLLVM_ArchType arch, Os os) {
         case OsKFreeBSD:
         case OsNetBSD:
         case OsHurd:
-        case OsWindows:
             return ZigLLVM_GNU;
         case OsUefi:
+        case OsWindows:
             return ZigLLVM_MSVC;
         case OsLinux:
         case OsWASI:

I think I'd like to do this, which would undo the change I made last week to make mingw-w64 the default C ABI on windows. I'd like to know if it solves the problem for you.

Actually I'm pretty sure this is a good idea so I'm just going to go through with it. The new build should be live on ziglang.org/download within 3 hours.

@danielabbott how did you compile glfw3? are you using vcpkg?

Edit: I can not replicate the error on that particular commit using the same build.zig/main.zig. Did you delete zig-cache & any .def/.lib files in the base directory?

I've compiled the latest zig source code and the change did not fix the issue. I compiled glfw with cmake cmake -DBUILD_SHARED_LIBS=OFF -DGLFW_BUILD_EXAMPLES=OFF -DGLFW_BUILD_TESTS=OFF -DGLFW_BUILD_DOCS=OFF -DUSE_MSVC_RUNTIME_LIBRARY_DLL=ON -G "Visual Studio 15 2017 Win64" . and visual studio and have also tried the precompiled static library of GLFW 3.3 64-bit from the website. Using the DLL version of GLFW works fine. And yes I cleared the zig-cache directory.

I have created a static library in visual studio which is just a wrapper around puts and the error still happens.

code.c:

#include <stdio.h>
void myputs(const char * s) {
    puts(s);
}

main.zig:

extern fn myputs(s: [*c]const u8) void;
const s = c"hello";
pub fn main() void {
    myputs(s);
}

build.zig same as before but linking the new library instead of glfw.

error:

C:\Users\Daniel\Desktop\bug>zig version
0.4.0+95e04e38
C:\Users\Daniel\Desktop\bug>zig build
lld: error: undefined symbol: __imp_puts
>>> referenced by c:\users\daniel\source\repos\myputs\myputs\code.c:3
>>>               myputs.lib(code.obj):(myputs)

The following command exited with error code 1:
C:\Users\Daniel\zig\zig.exe build-exe C:\Users\Daniel\Desktop\bug\main.zig --library c --library myputs --cache-dir C:\Users\Daniel\Desktop\bug\zig-cache --name test --cache on

Build failed. The following command failed:
C:\Users\Daniel\Desktop\bug\zig-cache\o\zB0g5nLChdwgX4xAxAiQzU6pxYUylLAiquoD4Syixpoe4ZshYkPqKRPbkS47EbQA\build.exe C:\Users\Daniel\zig\zig.exe C:\Users\Daniel\Desktop\bug C:\Users\Daniel\Desktop\bug\zig-cache

This looks like the problem: -DUSE_MSVC_RUNTIME_LIBRARY_DLL=ON. What was the motivation for this configuration?

And yes I cleared the zig-cache directory.

There are no known bugs in zig's caching system - this is not ever necessary.

That was the problem. After recompiling glfw without that flag it is working fine. I don't remember why I added it but it works fine without. For the other static library I created for testing I have changed the Runtime Library setting from Multithreaded DLL (the default setting) to Multithreaded and it works (that is what the GLFW USE_MSVC_RUNTIME_LIBRARY_DLL setting does).

I think these settings will be generally better because you will produce executables with no dependencies that are easier to ship to your users

Was this page helpful?
0 / 5 - 0 ratings

Related issues

daurnimator picture daurnimator  路  3Comments

dobkeratops picture dobkeratops  路  3Comments

andrewrk picture andrewrk  路  3Comments

jayschwa picture jayschwa  路  3Comments

zimmi picture zimmi  路  3Comments