Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

--libc flag doesn't work properly on Windows #20781

Open
noxabellus opened this issue Jul 24, 2024 · 4 comments
Open

--libc flag doesn't work properly on Windows #20781

noxabellus opened this issue Jul 24, 2024 · 4 comments
Labels
bug Observed behavior contradicts documented or intended behavior os-windows
Milestone

Comments

@noxabellus
Copy link

noxabellus commented Jul 24, 2024

Zig Version

0.13.0

Steps to Reproduce

I first noticed this issue while trying to cross compile my project which depends on bdwgc, from a windows 11 x86_64 vm for an aarch64-windows-msvc target. Strangely, I am able to compile the bdwgc module I've created directly, but trying to build it as a dependency from my own module's build script causes errors: either I get a series of errors saying the libc libs are x64 and I need aarch ones; or when I supply a libc file pointing to the correct binaries, an error saying that process.h cannot be found.

Why the former error is happening, I haven't been able to nail down. As I said, I do have the binaries and if I run the cross targeted build in bdwgc's directory it works fine. The second issue seems more definitely a compiler issue, though, so I decided to try and track that first.

I have produced a minimal reproduction here that recreates the missing header issue with no cross compilation or external libraries (other than libc, of course).

I can compile the following code with zig build-exe repro.zig -Dtarget=x86_64-windows-msvc

const std = @import("std");

const c = @cImport(@cInclude("process.h"));

pub fn main() void {
    std.debug.print("pid: {}\n", .{c.getpid()});
}

However, if I run zig libc, I get the following output:

# The directory that contains `stdlib.h`.
# On POSIX-like systems, include directories be found with: `cc -E -Wp,-v -xc /dev/null`
include_dir=C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt

# The system-specific include directory. May be the same as `include_dir`.
# On Windows it's the directory that includes `vcruntime.h`.
# On POSIX it's the directory that includes `sys/errno.h`.
sys_include_dir=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.40.33807\include

# The directory that contains `crt1.o` or `crt2.o`.
# On POSIX, can be found with `cc -print-file-name=crt1.o`.
# Not needed when targeting MacOS.
crt_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\ucrt\x64

# The directory that contains `vcruntime.lib`.
# Only needed when targeting MSVC on Windows.
msvc_lib_dir=C:\Program Files (x86)\Microsoft Visual Studio\2022\BuildTools\VC\Tools\MSVC\14.40.33807\Lib\x64

# The directory that contains `kernel32.lib`.
# Only needed when targeting MSVC on Windows.
kernel32_lib_dir=C:\Program Files (x86)\Windows Kits\10\Lib\10.0.22621.0\um\x64

# The directory that contains `crtbeginS.o` and `crtendS.o`
# Only needed when targeting Haiku.
gcc_dir=

Saving this to x86_64.libc and running the command again, supplying this libc file like so
zig build-exe repro.zig -Dtarget=x86_64-windows-msvc -lc --libc x86_64.libc

Produces this error:

repro.zig:3:11: error: C import failed
const c = @cImport(@cInclude("process.h"));
          ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
referenced by:
    main: repro.zig:6:36
    callMain: C:\Users\noxab\.zvm\0.13.0\lib\std\start.zig:514:17
    remaining reference traces hidden; use '-freference-trace' to see all reference traces
C:\Users\noxab\AppData\Local\zig\o\aabd1583e5f4b478fdf610e387722295\cimport.h:1:10: error: 'process.h' file not found       
#include <process.h>

If I run Get-Item "C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt\process.h" | Format-List, I can confirm the file does exist in the directory supplied in the libc file:

    Directory: C:\Program Files (x86)\Windows Kits\10\Include\10.0.22621.0\ucrt
    
Name           : process.h
Length         : 11893
CreationTime   : 1/8/2024 5:04:24 PM
LastWriteTime  : 1/8/2024 5:04:24 PM
LastAccessTime : 7/24/2024 4:15:17 PM
Mode           : -a----
...

Observed Behavior

Passing a generated libc file directly into a libc compiler option produces errors.

Expected Behavior

Passing a generated libc file directly into a libc compiler option works the same as no libc compiler option

@noxabellus noxabellus added the bug Observed behavior contradicts documented or intended behavior label Jul 24, 2024
@squeek502
Copy link
Collaborator

squeek502 commented Jul 25, 2024

Attempting to reproduce this, but I'm getting completely different results/errors.

This command is a bit strange:

zig build-exe repro.zig -Dtarget=x86_64-windows-msvc
  1. -Dtarget=x86_64-windows-msvc is a build system-specific option. The build-exe equivalent is -target
  2. This isn't linking libc

Changing to -target and adding -lc gives me:

> zig build-exe repro.zig -target x86_64-windows-msvc -lc
error: lld-link: undefined symbol: getpid
    note: referenced by C:\Users\Ryan\Programming\Zig\tmp\repro.zig:6
    note:               repro.exe.obj:(repro.main)

To fix that, I have to add -loldnames


For the --libc part:

> zig libc > x86_64.libc
> zig build-exe repro.zig -target x86_64-windows-msvc -lc -loldnames --libc x86_64.libc
error: unable to find dynamic system library 'oldnames' using strategy 'paths_first'. searched paths: none

Without oldnames I'm back to the getpid linker error:

> zig build-exe repro.zig -target x86_64-windows-msvc -lc --libc x86_64.libc
error: lld-link: undefined symbol: getpid
    note: referenced by C:\Users\Ryan\Programming\Zig\tmp\repro.zig:8
    note:               repro.exe.obj:(repro.main)

@noxabellus
Copy link
Author

noxabellus commented Jul 25, 2024

  1. -Dtarget=x86_64-windows-msvc is a build system-specific option. The build-exe equivalent is -target

What the heck is happening when I run with that flag, then? Is it still doing a gnu build?

  1. This isn't linking libc

This one is just a copy/paste problem, I did in fact pass -lc, but when I was copying out my inputs to make the issue I missed that bit.

After changing -Dtarget=x86_64-windows-msvc to -target x85_64-windows-msvc I needed to add oldnames as well, which compiles; but then adding the libc parameter I get the same unable to find dynamic system library 'oldnames' and without -loldnames I'm back to 'process.h' file not found

(Edit: Apologies for accidentally closing the issue, noob mistake. I've reopened it now.)

@alexrp
Copy link
Contributor

alexrp commented Jul 25, 2024

What the heck is happening when I run with that flag, then?

Excerpt from zig build-exe --help:

  -D[macro]=[value]         Define C [macro] to [value] (1 if [value] omitted)

Is it still doing a gnu build?

Yes, Zig defaults to MinGW for Windows.

@noxabellus noxabellus changed the title zig libc command / --libc flag don't work properly on Windows --libc flag doesn' work properly on Windows Jul 25, 2024
@noxabellus noxabellus changed the title --libc flag doesn' work properly on Windows --libc flag doesn't work properly on Windows Jul 25, 2024
@noxabellus
Copy link
Author

I bypassed the header issue by just manually adding the symbols I needed in my zig code, now it's saying that the libs are all missing. And again, if I go to the provided directory and Get-Item the files it says are missing, they in fact are not

@andrewrk andrewrk added this to the 0.16.0 milestone Jul 26, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Observed behavior contradicts documented or intended behavior os-windows
Projects
None yet
Development

No branches or pull requests

4 participants