Usage: v [C build flags] ['run'] <target.v|target_directory> [run options]

This command compiles the given target, along with their dependencies, into an executable.

This help topic explores the C-backend specific build flags. For more general build help,
see also `v help build`.

# Interfacing the C compiler, passing options to it:
   -cc <compiler>
      Change the C compiler V invokes to the specified compiler.
      The C compiler is required to support C99.
      Officially supported/tested C compilers include:
      `clang`, `gcc`, `tcc`, `mingw-w64` and `msvc`.

   -cflags <flag>
      Pass the provided flag as is to the C compiler.
      Can be specified multiple times to provide multiple flags.
      Use quotes to wrap the flag argument if it contains spaces.

      V also supports the environment variables CFLAGS and LDFLAGS.
      The contents of the CFLAGS variable will be prepended as is, at the start
      of the C backend command, right after the name of the compiler.
      The contents of the LDFLAGS variable will be appended as is, at the end
      of the C backend command, after all other options.

   -cstrict
      Turn on additional C warnings. This slows down compilation
      slightly (~10% for gcc), but sometimes provides better diagnosis.

   -showcc
      Prints the C command that is used to build the program.

   -freestanding
      Build the executable without dependency on libc.
      Supported only on `linux` targets currently.

   -bare-builtin-dir <bare-builtin-dir>
      Use with `-freestanding`. This specifies the directory to the
      implementation of some basic builtin functions. The list is as follows:
         bare_print(buf &byte, len u64)
            Print len charecters from the buffer pointed to by buf to stdout.
         bare_eprint(buf &byte, len u64)
            Print len charecters from the buffer pointed to by buf to stderr.
         bare_panic(msg string)
            Print "V panic: " + msg, along with an optional backtrace and/or the V commit hash, and then exit.
         [export: 'malloc']
         __malloc(n usize) &C.void
            Allocates n bytes of memory and returns the pointer to the first byte
         [export: 'free']
         __free(ptr &C.void)
            Free the block of memory ptr allocated by malloc.
         realloc(old_area &C.void, new_size usize) &C.void
            Allocates a new area of size new_size, copies old_area
            to the new area, and returns a pointer to the new area.
         [export: 'calloc']
         __calloc(nmemb usize, size usize) &C.void
            Like malloc, but sets all the bytes to `0` first.
         memcpy(dest &C.void, src &C.void, n usize) &C.void
            Moves n bytes from dest to src, and returns dest
         memmove(dest &C.void, src &C.void, n usize) &C.void
            Like memcpy, but guaranteed to work if dest and src overlap.
         memcmp(a &C.void, b &C.void, n usize) int
            Compare two buffers of length n. If a and b are equal, return 0.
            Otherwise, return the difference between the first different letter.
         strlen(s &C.void) usize
            Returns the amount of bytes until the first `0`, starting at s
         memset(s &C.void, c int, n usize) &C.void
            Sets n bytes starting at s to c (c is casted to a char)
            and returns s.
         getchar() int
            Read one character from stdin and return it.
            Print "V Panic" + msg, along with an optional backtrace, and then exit.
         vsprintf(str &char, format &char, ap va_list) int
            See `man vsprintf`.
         vsnprintf(str &char, size usize, format &char, ap va_list) int
            See `man vsnprintf`.
         bare_backtrace() string
            Return a backtrace that can be printed. If backtraces are not
            supported, return a message stating that backtraces do not work.
         [export: 'exit']
         __exit(code int)
            Exit with code code. code is allowed to be ignored.

         The module declaration should be `builtin`. The default Linux
         implementation can be found in `vlib/builtin/linux_bare`.

   -os <os>, -target-os <os>
      Change the target OS that V tries to compile for.
      By default, the target OS is the host system.
      When OS is `cross`, V will attempt to output cross-platform C code.

      Here is a list of the operating systems, supported by V:
      (CI tests runs on every commit/PR for each of these):
            `windows`, `linux`, `macos`

      The compiler is known to also work, and has support for these operating
      systems also (although we do not test it as regularly as for the above):
            `android`, `ios`,
            `freebsd`, `openbsd`, `netbsd`, `dragonfly`,
            `solaris`, `serenity`, `haiku`, `vinix`,
            `wasm32`, `wasm32-wasi`, `wasm32-emscripten`

      Note that V has the concept of platform files, i.e. files ending
      with `_platform.c.v`, and usually only the matching files are used in
      a compilation, and also it supports a `_default.c.v` file, that will
      be used, when no other more specific `_platform.c.v` file is found.
      The default is mainly useful for writing shims for new platforms,
      until a more specialized _platform.c.v is written instead.

      For example, suppose you have these 3 files:
          x_default.c.v
          x_windows.c.v
          x_linux.c.v
      If you compile with `-os freebsd`, then x_default.c.v will be used.
      If you compile with `-os linux`, then x_linux.c.v will be used.
      If you compile with `-os windows`, then x_windows.c.v will be used.
      If you compile with `-os cross`, then all, *except x_default.c.v*
      will be used, wrapped in conditional compilation guards, so that
      the generated C source code will be larger, but will compile on all
      explicitly supported platforms without source changes.

   -m32, -m64
      Whether 32-bit or 64-bit machine code will be generated.
      NB: if you need to produce 32-bit code, *and* you are cross compiling
      to another OS, you may need to also set the environment variable
      VCROSS_COMPILER_NAME, in order to override the default cross compiler,
      that V will use (`x86_64-w64-mingw32-gcc` for targeting Windows, and
      `clang` for targeting Linux from other operating systems).

   -sanitize
      Pass flags related to sanitization to the C compiler.

   -shared
      Tell V to compile a shared object instead of an executable.
      The resulting file extension will be `.dll` on Windows and `.so` on Unix systems

# Memory management
   -autofree
      Free memory used in functions automatically.

   -manualfree
      Do not free memory used in functions (the developer has to put x.free()
      and unsafe{free(x)} calls manually in this mode).
      Some short lived applications, like compilers and other CLI tools are
      more performant without autofree.

   -gc <mode>
      Use and link an optional garbage collector. Only the Boehm–Demers–Weiser
      garbage collector is supported currently with the following sub-options:

      `-gc boehm` ........... selects the default mode for the architecture
      `-gc boehm_full` ...... full garbage collection mode
      `-gc boehm_incr` ...... incremental/generational garbage collection mode
      `-gc boehm_full_opt` .. optimized full garbage collection mode
      `-gc boehm_incr_opt` .. optimized incremental/generational garbage collection mode
      `-gc boehm_leak` ...... leak detection mode

      You need to install a `libgc-dev` package first, or install it manually from:

          https://github.com/ivmai/bdwgc

      On Mac OS, it can be installed using homebrew (https://homebrew.sh/) with
      `brew install libgc`.

      Note, `-gc boehm` is complementary to -autofree. The Boehm garbage
      collector is conservative, and it may make your program significantly
      slower if it does many small allocations in a loop. This option
      is intended *mainly* for reducing the memory usage of programs, that
      process large amounts of text in *batch mode* on low/limited memory
      environments like small VPSes, and for which a few ms of garbage
      collection pauses from time to time *do not matter much*.

      The option `-gc boehm_leak` is intended for leak detection in
      manual memory management. The function `gc_check_leaks()`
      can be called to get detection results. This function is a no-op
      when `-gc boehm_leak` is not supplied.

# Miscellaneous:
   -printfn <fn_name>
      Print the content of the generated C function named fn_name.
      You can repeat that many times with different function names.
      This is useful when you just want to quickly tweak the generated
      C code, without opening the generated .c file in a text editor,
      i.e. it enables this workflow:

      1) change vlib/v/gen/cgen.v
      2) ./v -o v2 cmd/v && ./v2 -printfn main__main bug.v
      3) inspect the produced C, and goto 1) till the bug is fixed.

      Since V compiles itself very fast (especially with tcc),
      this loop is very short usually.

   -compress
      Compress the compiled executable with UPX.
	  Note: `upx` should be installed beforehand.
	  In most Linux distros it is in a package named `upx-ucl`.
	  On macOS, you can install it with `brew install upx`.
	  On Windows, you can download it from https://upx.github.io/ .

   -live
      Build the executable with live capabilities (`[live]`).

   -no-prelude
      Prevents V from generating a prelude in generated .c files, useful for freestanding targets
      where eg. you replace C standard library with your own, or some definitions/headers break something.

   -custom-prelude <path>
      Useful for similar use-case as above option, except it replaces V-generated prelude with
      your custom one loaded from specified <path>.

# Debugging:
   -g
      Generate more debug information in the compiled executable.
      This makes program backtraces more useful.
      Using debuggers like gdb/lldb with such executables is easier too.
      Unlike `-cg` (described below), `-g` will enforce V source line numbers
      so that your debugger and the stacktraces will show you directly
      what .v file is responsible for each call/panic.

   -cg
      Like -g, but do not use V source line numbers.
      When debugging code that wraps C libraries, this option may be
      more useful than -g, since it will reduce the amount of context
      switching, that you need to do, while looking at .v and .c sources.
      This option is usually used in combination with `-keepc`.

   -keepc
      Do not remove the temporary .tmp.c and .tmp.c.rsp files.
      Also do not use a random prefix for them, so they would be fixed and predictable.

      NB: when writing low level code that interfaces/wraps an existing C library,
      it is frequently helpful to use these together: -keepc -cg -showcc -show-c-output

   -showcc
      Prints the C command that is used to build the program.

   -show-c-output
      Prints the output, that your C compiler produced, while compiling your program.

   -dump-c-flags file.txt
      Write all C flags into `file.txt`, one flag per line.
      If `file.txt` is `-`, then write the flags to stdout, one flag per line.

   -no-rsp
      By default, V passes all C compiler options to the backend C compiler
      in so called "response files" (https://gcc.gnu.org/wiki/Response_Files).
      This works in most cases, since it works around command line length
      limitations on older systems (and windows), but some C compilers
      (older versions of tcc for example) do not support them at all. When
      you use -no-rsp, V will pass the C compiler options directly to the C
      compiler, on the command line, without writing an .rsp file first.

   -no-std
      By default, V passes -std=gnu99(linux)/-std=c99 to the C backend, but some compilers do
      not support that, even though they may be able to compile the produced
      code, or have other options that can be tuned to allow it.
      Passing -no-std will remove that flag, and you can then use -cflags ''
      to pass the other options for your specific C compiler.

-assert aborts
      Call abort() after an assertion failure. Debuggers usually
      install signal handlers for SIGABRT, so your program will stop and you
      will get a backtrace. If you are running your program outside of a
      debugger, you will most likely get a core dump file.

   -assert backtraces
      Call print_backtrace() after an assertion failure. Note that
      backtraces are not implemented yet on all combinations of
      platform/compiler.
