compiler: add `[console]` attribute for main function to force console subsystem on windows (#7721)
parent
a834f33661
commit
bf9b0c6345
|
@ -36,6 +36,7 @@ pub const (
|
||||||
#flag linux -DSOKOL_NO_ENTRY
|
#flag linux -DSOKOL_NO_ENTRY
|
||||||
#flag darwin -DSOKOL_NO_ENTRY
|
#flag darwin -DSOKOL_NO_ENTRY
|
||||||
#flag windows -DSOKOL_NO_ENTRY
|
#flag windows -DSOKOL_NO_ENTRY
|
||||||
|
#flag windows -DSOKOL_WIN32_FORCE_MAIN
|
||||||
#flag freebsd -DSOKOL_NO_ENTRY
|
#flag freebsd -DSOKOL_NO_ENTRY
|
||||||
#flag solaris -DSOKOL_NO_ENTRY
|
#flag solaris -DSOKOL_NO_ENTRY
|
||||||
// TODO end
|
// TODO end
|
||||||
|
|
|
@ -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)
|
c.error('function `main` cannot return values', stmt.pos)
|
||||||
}
|
}
|
||||||
} else {
|
} 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 {
|
if stmt.is_pub && !stmt.is_method {
|
||||||
c.warn('function `$stmt.name` $no_pub_in_main_warning', stmt.pos)
|
c.warn('function `$stmt.name` $no_pub_in_main_warning', stmt.pos)
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
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
|
branch_parent_pos int // used in BranchStmt (continue/break) for autofree stop position
|
||||||
timers &util.Timers = util.new_timers(false)
|
timers &util.Timers = util.new_timers(false)
|
||||||
|
force_main_console bool // true when [console] used on fn main()
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -43,6 +43,10 @@ fn (mut g Gen) gen_vlines_reset() {
|
||||||
fn (mut g Gen) gen_c_main_function_header() {
|
fn (mut g Gen) gen_c_main_function_header() {
|
||||||
if g.pref.os == .windows {
|
if g.pref.os == .windows {
|
||||||
if g.is_gui_app() {
|
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
|
// GUI application
|
||||||
g.writeln('int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPWSTR cmd_line, int show_cmd){')
|
g.writeln('int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPWSTR cmd_line, int show_cmd){')
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -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 {
|
fn (mut g Gen) is_gui_app() bool {
|
||||||
$if windows {
|
$if windows {
|
||||||
|
if g.force_main_console {
|
||||||
|
return false
|
||||||
|
}
|
||||||
for cf in g.table.cflags {
|
for cf in g.table.cflags {
|
||||||
if cf.value == 'gdi32' {
|
if cf.value == 'gdi32' {
|
||||||
return true
|
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.
|
// prefixed by windows to indicate they're for advanced users only and not really supported by V.
|
||||||
msvc_attrs += '__stdcall '
|
msvc_attrs += '__stdcall '
|
||||||
}
|
}
|
||||||
|
'console' {
|
||||||
|
g.force_main_console = true
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
// nothing but keep V happy
|
// nothing but keep V happy
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue