cgen: add support for `v -cmain SDL_main sdl_example.v`

master
Delyan Angelov 2022-05-28 21:16:48 +03:00
parent c0ef6dbde8
commit c006d5c242
No known key found for this signature in database
GPG Key ID: 66886C0F12D595ED
3 changed files with 33 additions and 7 deletions

View File

@ -25,7 +25,20 @@ see also `v help build`.
-cstrict -cstrict
Turn on additional C warnings. This slows down compilation Turn on additional C warnings. This slows down compilation
slightly (~10% for gcc), but sometimes provides better diagnosis. slightly (~10% for gcc), but sometimes provides better error diagnosis.
-cmain <MainFunctionName>
Useful with framework like code, that uses macros to re-define `main`, like SDL2 does for example.
With that option, V will always generate:
`int MainFunctionName(int ___argc, char** ___argv) {` , for the program entry point function, *no matter* the OS.
Without it, on non Windows systems, it will generate:
`int main(int ___argc, char** ___argv) {`
... and on Windows, it will generate:
a) `int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPWSTR cmd_line, int show_cmd){`
when you are compiling applications that `import gg`.
... or it will generate:
b) `int wmain(int ___argc, wchar_t* ___argv[], wchar_t* ___envp[]){`
when you are compiling console apps.
-showcc -showcc
Prints the C command that is used to build the program. Prints the C command that is used to build the program.

View File

@ -50,7 +50,11 @@ fn (mut g Gen) gen_vlines_reset() {
} }
} }
fn (mut g Gen) gen_c_main_function_header() { fn (mut g Gen) gen_c_main_function_only_header() {
if g.pref.cmain != '' {
g.writeln('int ${g.pref.cmain}(int ___argc, char** ___argv){')
return
}
if g.pref.os == .windows { if g.pref.os == .windows {
if g.is_gui_app() { if g.is_gui_app() {
$if msvc { $if msvc {
@ -65,13 +69,17 @@ fn (mut g Gen) gen_c_main_function_header() {
g.writeln('\tcmd_line_to_argv CommandLineToArgvW = (cmd_line_to_argv)GetProcAddress(shell32_module, "CommandLineToArgvW");') g.writeln('\tcmd_line_to_argv CommandLineToArgvW = (cmd_line_to_argv)GetProcAddress(shell32_module, "CommandLineToArgvW");')
g.writeln('\tint ___argc;') g.writeln('\tint ___argc;')
g.writeln('\twchar_t** ___argv = CommandLineToArgvW(full_cmd_line, &___argc);') g.writeln('\twchar_t** ___argv = CommandLineToArgvW(full_cmd_line, &___argc);')
} else { return
// Console application
g.writeln('int wmain(int ___argc, wchar_t* ___argv[], wchar_t* ___envp[]){')
} }
} else { // Console application
g.writeln('int main(int ___argc, char** ___argv){') g.writeln('int wmain(int ___argc, wchar_t* ___argv[], wchar_t* ___envp[]){')
return
} }
g.writeln('int main(int ___argc, char** ___argv){')
}
fn (mut g Gen) gen_c_main_function_header() {
g.gen_c_main_function_only_header()
g.writeln('\tg_main_argc = ___argc;') g.writeln('\tg_main_argc = ___argc;')
g.writeln('\tg_main_argv = ___argv;') g.writeln('\tg_main_argv = ___argv;')
if g.nr_closures > 0 { if g.nr_closures > 0 {

View File

@ -163,6 +163,7 @@ pub mut:
bare_builtin_dir string // Set by -bare-builtin-dir xyz/ . The xyz/ module should contain implementations of malloc, memset, etc, that are used by the rest of V's `builtin` module. That option is only useful with -freestanding (i.e. when is_bare is true). bare_builtin_dir string // Set by -bare-builtin-dir xyz/ . The xyz/ module should contain implementations of malloc, memset, etc, that are used by the rest of V's `builtin` module. That option is only useful with -freestanding (i.e. when is_bare is true).
no_preludes bool // Prevents V from generating preludes in resulting .c files no_preludes bool // Prevents V from generating preludes in resulting .c files
custom_prelude string // Contents of custom V prelude that will be prepended before code in resulting .c files custom_prelude string // Contents of custom V prelude that will be prepended before code in resulting .c files
cmain string // The name of the generated C main function. Useful with framework like code, that uses macros to re-define `main`, like SDL2 does. When set, V will always generate `int THE_NAME(int ___argc, char** ___argv){`, *no matter* the platform.
lookup_path []string lookup_path []string
output_cross_c bool // true, when the user passed `-os cross` output_cross_c bool // true, when the user passed `-os cross`
output_es5 bool output_es5 bool
@ -686,6 +687,10 @@ pub fn parse_args_and_show_errors(known_external_commands []string, args []strin
res.custom_prelude = prelude res.custom_prelude = prelude
i++ i++
} }
'-cmain' {
res.cmain = cmdline.option(current_args, '-cmain', '')
i++
}
else { else {
if command == 'build' && is_source_file(arg) { if command == 'build' && is_source_file(arg) {
eprintln('Use `v $arg` instead.') eprintln('Use `v $arg` instead.')