Skip to content

added subsystem to builtin.zig #2462

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

Closed
wants to merge 3 commits into from
Closed

Conversation

emekoi
Copy link
Contributor

@emekoi emekoi commented May 9, 2019

closes #2455.

@emekoi emekoi force-pushed the builtin-subsystem branch from cd8fe46 to 31a4b15 Compare May 10, 2019 04:04
@andrewrk
Copy link
Member

This code looks good, but there's one tricky thing I want to understand. When you use @import("builtin").subsystem, what are you supposed to do with it if it's Auto? Should Zig resolve the "auto" subsystem and make a choice, before we create builtin.zig?

Does the linker choose a default subsystem if you don't specify one?

@emekoi
Copy link
Contributor Author

emekoi commented May 10, 2019

is my understanding of this correct?

    bool have_pub_main; // pub fn main()
    bool have_c_main; // export fn main(argc: c_int, argv: **u8)
    bool have_winmain; // export fn WinMain(...)
    bool have_winmain_crt_startup; // extern fn WinMainCRTStartup() noreturn
    bool have_dllmain_crt_startup; // stdcallcc fn _DllMainCRTStartup(...)

@emekoi
Copy link
Contributor Author

emekoi commented May 10, 2019

according to the here, the subsystem sets the environment for executables so for DLL's i set the subsystem field to null. for executables, i set the subsystem according to here.

@emekoi emekoi force-pushed the builtin-subsystem branch from d9e9151 to 0d04348 Compare May 10, 2019 15:09
@andrewrk
Copy link
Member

is my understanding of this correct?

Yes

@andrewrk
Copy link
Member

@Sahnvour if you're around do you have any insight into these questions?

@Sahnvour
Copy link
Contributor

@andrewrk I'm not very knownledgeable on this, but it seems the subsystem and the entry point are two different things, even if the former is usually deduced from the latter by link.exe. In other words we can mix the /SUBSYSTEM:foo and /ENTRY:bar to our liking.

The auto mode would probably be resolved by the linker as the docs say, but we could also choose to have a hardcoded default one, and still support main or WinMain entry point.

As per the practical differences between console and windows (the two mainly used ones), I don't know if it does something more than juste having or not a console launch at startup.

@emekoi
Copy link
Contributor Author

emekoi commented May 18, 2019

according to here

The /SUBSYSTEM option specifies the environment for the executable.

The choice of subsystem affects the entry point symbol (or entry point function) that the linker will select.

though that may just be for the msvc linker.

@andrewrk
Copy link
Member

I started to merge this, and I committed some cleanups here:

https://github.com/ziglang/zig/compare/emekoi-builtin-subsystem

But I don't think this can work without substantial changes. builtin.zig is created before the root source file is scanned, so the builtin.zig file would have the incorrect value for subsystem.

const std = @import("std");

pub fn main() !void {
    std.debug.warn("{}\n", @import("builtin").subsystem);
}
[nix-shell:~/downloads/zig/build]$ ./zig build-exe test.zig -target x86_64-windows 
/home/andy/downloads/zig/build/test.zig:4:46: error: container 'builtin' has no member called 'subsystem'
    std.debug.warn("{}\n", @import("builtin").subsystem);
                                             ^

If you do zig builtin you can see the subsystem decl is missing (I changed it from null to be simply omitted), because the value is still "auto" and isn't figured out until the root source file is scanned.

@andrewrk
Copy link
Member

One possible solution would be to implement the subsystem in builtin.zig as a userland function that could take advantage of #2189 and do the logic, like this:

const root = @import("root");
pub const subsystem = blk: {
    if (@hasDecl(root, "main")) break :blk SubSystem.Console;
    if (@hasDecl(root, "WinMain")) break :blk SubSystem.Windows;
    // etc...
};

@andrewrk
Copy link
Member

In fact, bootstrap.zig already has access to the root source file, so if we merged this PR - in which builtin.zig has subsystem missing unless explicitly provided - bootstrap.zig would have enough information to do the correct thing.

@emekoi
Copy link
Contributor Author

emekoi commented May 29, 2019

the problem with that is what if the user passes --subsystem console, but has WinMain in their root file? builtin.zig will report that the subsystem is windows despite the fact the user requested the subsystem be console.
on a side note, does @hasDecl report true regardless of whether the declaration is private or public?

@andrewrk
Copy link
Member

the problem with that is what if the user passes --subsystem console, but has WinMain in their root file? builtin.zig will report that the subsystem is windows despite the fact the user requested the subsystem be console.

When the subsystem is explicitly provided, then it would be present in @import("builtin"). So as long as the logic checks builtin first then does the other logic, it would be correct.

on a side note, does @hasDecl report true regardless of whether the declaration is private or public?

I did answer this question in the docs, but maybe it could be made clearer.

@andrewrk
Copy link
Member

OK I went ahead and merged this (landed in 6dbaae4). The semantics aren't incredibly convenient since it requires userland logic using @hasDecl, but it is possible to be correct (thinking of #2445)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

expose subsystem on windows
3 participants