Open ameyp opened 4 years ago
I've run into something this before. IIRC it's because the glfw lib is compiled with /MD but zig builds with the equivalent of /MT. (documentation) You need a version of glfw that was built for windows with /MT. They've noted that they don't want to host precompiled versions for multiple library types. If you want to get up and running quickly, I have a /MT version that I built for one of my zig projects hosted here: https://github.com/SpexGuy/Zig-ImGui/tree/master/examples/lib/win
Yep, that did turn out to be the problem. I built my own GLFW locally with USE_MSVC_RUNTIME_LIBRARY_DLL
set to OFF
and linking succeeded without any errors or warnings. This issue can be closed now, but perhaps this should be documented somewhere?
Also worth noting (for posterity) that the static libraries built for vcpkg work as well.
Leaving this issue open for now to audit this use case and make sure zig is doing everything it should be doing here.
It looks like USE_MSVC_RUNTIME_LIBRARY_DLL
is deprecated or broken as of CMake 3.15, and replaced by CMAKE_MSVC_RUNTIME_LIBRARY
. If you use a newer version of CMake than this you'll have problems as of https://github.com/glfw/glfw/commit/539535a367f78a393b48a910956ba9a4ee04e364.
So, to build GLFW so that it links to the CRT statically the correct build flag would be -DCMAKE_MSVC_RUNTIME_LIBRARY=MultiThreaded
. If this is omitted (and the old flag is used instead) it will append -MD
to the CFLAGS in flags.cmake
regardless of whether USE_MSVC_RUNTIME_LIBRARY_DLL=OFF
adds /MT
to the list or not. This seems like an oversight on CMake's end, but it is what it is.
I'm getting similar errors despite the flag suggested by @vassvik and @ameyp. vcpkg static libraries not working either!
lld-link: error: could not open 'libuuid.a': no such file or directory
lld-link: error: could not open 'libLIBCMT.a': no such file or directory
lld-link: error: could not open 'libOLDNAMES.a': no such file or directory
Anyone found a workflow that works on Win10 currently?
If you've built glfw3 with MSVC, set /MT(d) accordingly (check this in Visual Studio -> right click "glfw" project -> select Properties -> Configuration Properties -> C/C++ -> Code Generation -> Runtime Library -> should be /MT or /MTd) and linked with everything you needed in build.zig
(libc, glfw3, gdi32, opengl32 etc.) try to change the target to:
zig build -Dtarget=x86_64-windows-msvc
You may need to setTarget
for the exe in build.zig
if the -Dtarget option doesn't work:
pub fn build(self: Target, b: *Builder) void {
const exe = b.addExecutable(self.name, self.src);
exe.setTarget(b.standardTargetOptions(.{}));
...
Alternatively, for -Dtarget=x86_64-windows-gnu
, you can build glfw3 using mingw64 (not with MSVC like above):
msys64\mingw64\bin
to the windows PATH (for cmake to find gcc there, verify with where gcc
in cmd);cmake . -G "MinGW Makefiles" -B build_mingw
(useful to set the build type -D CMAKE_BUILD_TYPE=Debug
or Release
) in the glfw repository (or select "MinGW Makefiles" from the GUI instead of "Visual Studio X 201Y");cd build_mingw && mingw32-make glfw
should generate build_mingw\src\libglfw3.a
;build.zig
replace addLibPath("path_to_glfw3.lib")
and linkSystemLibrary("glfw3")
with addObjectFile("path_to_build_mingw/src/libglfw3.a")
;zig build
(or zig build -Dtarget=x86_64-windows-gnu
) should work now.Optional: If you also add -D CMAKE_C_FLAGS=-D_STDIO_DEFINED
to the cmd at step 3 and rebuild the library, you'll be able to build with both -Dtarget=x86_64-windows-msvc
and -Dtarget=x86_64-windows-gnu
using libglfw3.a.
I was able to use the above steps to successfully build with both x86_64-windows-gnu
and x86_64-windows-msvc
using a libglfw3.a
built with MinGW.
The only change is that for -gnu
I needed to add exe.linkLibCpp();
. Otherwise it failed to find __cxa_guard_acquire
, __cxa_guard_release
, __cxa_guard_release
, _Unwind_Resume
, __gxx_personality_seh0
, __cxa_begin_catch
, and std::terminate()
.
I wasn't able to link a MSVC-built glfw3 (with either /MD or /MT) using x86_64-windows-gnu
, as it tried to link against the .a
versions:
lld-link: error: could not open 'libuuid.a': no such file or directory
lld-link: error: could not open 'libMSVCRTD.a': no such file or directory
lld-link: error: could not open 'libOLDNAMES.a': no such file or directory
After using mingw to build I thought why not use zig to build, it's one of it's use cases after all and I had some issues using the ones built with mvsc/mingw. This is the build file:
const std = @import("std");
const builtin = @import("builtin");
pub fn build(b: *std.build.Builder) void {
const lib = b.addStaticLibrary("glfw3", null);
// modify the paths here with the ones from the https://github.com/glfw/glfw repository
lib.addIncludeDir("F:/Development/glfw/include");
const src_dir = "F:/Development/glfw/src";
lib.setBuildMode(b.standardReleaseOptions());
lib.setTarget(b.standardTargetOptions(.{}));
lib.linkLibC();
const c_flags = [_][]const u8{
// when compiling this lib in debug mode, it seems to add -fstack-protector so if you want to link it
// with an exe built with -Dtarget=x86_64-windows-msvc you need the line below or you'll get undefined symbols
"-fno-stack-protector",
// don't want to add some functions (__mingw_vsscanf etc.), also needed for building exe with msvc abi
"-D_STDIO_DEFINED",
// we're compiling for windows (https://github.com/glfw/glfw/blob/076bfd55be45e7ba5c887d4b32aa03d26881a1fb/src/glfw_config.h.in#L40) _GLFW_USE_CONFIG_H is used to get this define in cmake
"-D_GLFW_WIN32",
// added to windows builds (https://github.com/glfw/glfw/blob/076bfd55be45e7ba5c887d4b32aa03d26881a1fb/src/CMakeLists.txt#L144)
"-D_UNICODE",
"-DUNICODE",
};
if (lib.build_mode != .Debug) {
lib.strip = true;
}
const src_files = [_][]const u8{
// .c files for all targets (https://github.com/glfw/glfw/blob/076bfd55be45e7ba5c887d4b32aa03d26881a1fb/src/CMakeLists.txt#L4)
"context.c",
"init.c",
"input.c",
"monitor.c",
"vulkan.c",
"window.c",
// .c files for windows build (https://github.com/glfw/glfw/blob/076bfd55be45e7ba5c887d4b32aa03d26881a1fb/src/CMakeLists.txt#L14)
"win32_init.c",
"win32_joystick.c",
"win32_monitor.c",
"win32_time.c",
"win32_thread.c",
"win32_window.c",
"wgl_context.c",
"egl_context.c",
"osmesa_context.c",
};
inline for (src_files) |src| {
lib.addCSourceFile(src_dir ++ "/" ++ src, &c_flags);
}
lib.install();
}
You only need zig and the GLFW repository.
Runzig init-lib
, copy this in build.zig and set your GLFW src and include paths. No other files are needed.
It should also work with the MSVC abi, though I'd recommend leaving the default.
I was able to use the above steps to successfully build with both
x86_64-windows-gnu
andx86_64-windows-msvc
using alibglfw3.a
built with MinGW.The only change is that for
-gnu
I needed to addexe.linkLibCpp();
. Otherwise it failed to find__cxa_guard_acquire
,__cxa_guard_release
,__cxa_guard_release
,_Unwind_Resume
,__gxx_personality_seh0
,__cxa_begin_catch
, andstd::terminate()
.I wasn't able to link a MSVC-built glfw3 (with either /MD or /MT) using
x86_64-windows-gnu
, as it tried to link against the.a
versions:lld-link: error: could not open 'libuuid.a': no such file or directory lld-link: error: could not open 'libMSVCRTD.a': no such file or directory lld-link: error: could not open 'libOLDNAMES.a': no such file or directory
Yes, you also should link libc.
I'd recommend the lib built with zig (and to not waste time with issues like missing symbols avoid the msvc abi and use the default everywhere).
Ah, that sounds simpler! Just build with zig!
I'm going to leave a note here unless anyone else bumps into this using the above directions: I found linking with the Debug version glfw.a caused me to not have stack traces when errors were returned, it was like there were no debug symbols. Linking with Release instead solved the issue.
I'm trying to build an application that uses GLFW3 on Windows. I've downloaded the "Windows pre-compiled binaries" from https://www.glfw.org/download.html and extracted the contents of the zip to a folder in my zig project.
Here's my
build.zig
:Here's my
main.zig
:And here's the build log:
Also, should I be worried about the warnings regarding locally defined symbols being imported?