compiler: add `[console]` attribute for main function to force console subsystem on windows (#7721)

pull/7750/head
Emily Hudson 2020-12-31 05:38:55 -06:00 committed by GitHub
parent a834f33661
commit bf9b0c6345
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 18 additions and 0 deletions

View File

@ -36,6 +36,7 @@ pub const (
#flag linux -DSOKOL_NO_ENTRY
#flag darwin -DSOKOL_NO_ENTRY
#flag windows -DSOKOL_NO_ENTRY
#flag windows -DSOKOL_WIN32_FORCE_MAIN
#flag freebsd -DSOKOL_NO_ENTRY
#flag solaris -DSOKOL_NO_ENTRY
// TODO end

View File

@ -240,6 +240,12 @@ fn (mut c Checker) check_file_in_main(file ast.File) bool {
c.error('function `main` cannot return values', stmt.pos)
}
} else {
for attr in stmt.attrs {
if attr.name == 'console' {
c.error('only `main` can have the `[console]` attribute',
stmt.pos)
}
}
if stmt.is_pub && !stmt.is_method {
c.warn('function `$stmt.name` $no_pub_in_main_warning', stmt.pos)
}

View File

@ -131,6 +131,7 @@ mut:
returned_var_name string // to detect that a var doesn't need to be freed since it's being returned
branch_parent_pos int // used in BranchStmt (continue/break) for autofree stop position
timers &util.Timers = util.new_timers(false)
force_main_console bool // true when [console] used on fn main()
}
const (

View File

@ -43,6 +43,10 @@ fn (mut g Gen) gen_vlines_reset() {
fn (mut g Gen) gen_c_main_function_header() {
if g.pref.os == .windows {
if g.is_gui_app() {
$if msvc {
// This is kinda bad but I dont see a way that is better
g.writeln('#pragma comment(linker, "/SUBSYSTEM:WINDOWS")')
}
// GUI application
g.writeln('int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPWSTR cmd_line, int show_cmd){')
} else {

View File

@ -890,6 +890,9 @@ fn (mut g Gen) ref_or_deref_arg(arg ast.CallArg, expected_type table.Type) {
fn (mut g Gen) is_gui_app() bool {
$if windows {
if g.force_main_console {
return false
}
for cf in g.table.cflags {
if cf.value == 'gdi32' {
return true
@ -966,6 +969,9 @@ fn (mut g Gen) write_fn_attrs(attrs []table.Attr) string {
// prefixed by windows to indicate they're for advanced users only and not really supported by V.
msvc_attrs += '__stdcall '
}
'console' {
g.force_main_console = true
}
else {
// nothing but keep V happy
}