This command compiles the given target, along with their dependencies, into an executable.
Usage:
v [build flags] ['run'] [run options]
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
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
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.
-ldflags
Pass the provided flag as is to the C compiler *after every other C option*.
Can be specified multiple times to provide multiple flags.
Use quotes to wrap the flag argument, if it contains spaces.
Note: 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 error diagnosis.
-cmain
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.
-subsystem
Useful to change the generated main function on Windows.
Ignored on other platforms. The default is `auto`.
When set to `console` V will generate a `wmain` main function.
When set to `windows` V will generate a `wWinMain` main function,
even when you are not compiling `gg` apps.
-icon
--icon=
-seticon
Embed the provided `.ico` or `.png` file as the icon of the generated
Windows executable. Use it only when V is producing a Windows `.exe`.
-showcc
Prints the C command that is used to build the program.
-generate-c-project
Generate a C project folder with:
* the generated `.c` source file;
* `build.sh`, `build.bat`, `Makefile` and `build_command.txt`.
The generated build command prefers source files (`.c`, `.cpp`, `.S`) over
cached `.o` files when V can find the corresponding source on disk.
-freestanding
Build the executable without dependency on libc.
Supported only on `linux` targets currently.
-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 characters from the buffer pointed to by buf to stdout.
bare_eprint(buf &byte, len u64)
Print len characters 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, const_src &C.void, n usize) &C.void
Moves n bytes from dest to src, and returns dest
memmove(dest &C.void, const_src &C.void, n usize) &C.void
Like memcpy, but guaranteed to work if dest and src overlap.
memcmp(const_a &C.void, const_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(const_s &char) 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.
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`.
-cross
With `-cross`, V will attempt to output cross-platform C code.
-os , -target-os
Change the target OS that V tries to compile for.
By default, the target OS is the host system.
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):
`vinix`,
`ios`,
`android`, `termux`,
`freebsd`, `openbsd`, `netbsd`, `dragonfly`,
`solaris`, `serenity`, `haiku`,
`plan9`,
`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 `-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.
On x86 C backend builds, `-m32` also selects the i386 target unless you
already passed an explicit `-arch`, so `$if i386 {}` and `*.i386.v`
files follow the same target width.
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 or pass `-cc your-compiler` for a one-off override,
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).
Note: the bundled Linux cross-compilation sysroot currently contains
x86_64 runtime files only, so `-os linux -arch arm64` is not supported yet.
-macosx-version-min 11.0
Only relevant on macos. It will be passed as -mmacosx-version-min=11.0 to
the C backend compiler clang . By default V does not pass any
-mmacosx-version-min flag, so you can also control it directly with
-cflags. Pass `-macosx-version-min 0` to keep that default.
-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
-is_o
Tell V to compile an .o object file instead of an executable.
This is useful if you plan to create a module, that will be later linked to a
larger program, potentially written in another language.
The flag can also be combined with `-o file.c`, to generate C source that can be
compiled and linked together with other `-is_o` generated V units.
Note: this option currently works with gcc/clang/tcc, but not msvc.
Note: use either -no-skip-unused or tag the functions you expect to be publicly
usable in the .o file with `@[markused]` . Adding `-gc none` may be also needed,
unless you plan to link with -lgc later.
# 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
On most supported C targets, V uses a garbage collector by default. Musl keeps the
historical default of `-gc none`. Only the Boehm–Demers–Weiser garbage collector is
supported currently with the following sub-options:
`-gc boehm` ........... use the default Boehm garbage collector mode
`-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
`-gc none` ............ no garbage collector
Note: the garbage collector is complementary to -autofree. The Boehm garbage
collector is conservative, and it may affect program speed if it does many small
allocations in a loop.
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.
Use `-gc none` to completely disable the garbage collector, in case of
wanting to handle memory manually, or strictly using `-autofree`.
Note: some short lived applications, like compilers and other CLI tools can be
more performant, without autofree, and without a garbage collector, instead
relying on the OS to free the allocated memory automatically, after their
process ends.
On most supported platforms, the source of the used garbage collector is
located in `thirdparty/libgc/`, produced by post-processing
`https://github.com/ivmai/bdwgc`. If you have installed libgc by other means,
(through your distro's package manager or by compiling it yourself and
installing it), you can also tell V to use it instead of its own copy,
by adding `-d dynamic_boehm` to the command line while compiling your program.
On Debian you can use `sudo apt install libgc-dev`.
On macOS, you can install it, using homebrew (https://homebrew.sh/)
with `brew install libgc`.
# Miscellaneous:
-printfn
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-preludes
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
Useful for similar use-case as above option, except it replaces V-generated prelude with
your custom one loaded from specified .
# Debugging:
-g, -debug
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, -cdebug
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 `-`, write to stdout instead.
-dump-modules file.txt
Write all module names used by the program in `file.txt`, one module per line.
If `file.txt` is `-`, write to stdout instead.
-dump-files file.txt
Write all used V file paths used by the program in `file.txt`, one module per line.
If `file.txt` is `-`, write to stdout instead.
-dump-defines file.txt
Write all system and user defines, that V knows about for the current program, one per line.
If `file.txt` is `-`, write to stdout instead.
Example sample of the content of that file:
system,linux,eval
system,amd64,eval
system,solaris,skip
system,solaris,skip
user,gcboehm,eval
user,gg_record_trace,skip
-no-closures
Produce a compile time error early, if V generates a closure. That happens implicitly,
if you try to treat methods as values, or explicitly through `fn [captures] (){}`.
This option is useful to prevent accidental introduction of closures for environments,
that do not support closures well (projects targeting wasm, or projects that have to be
ported for less supported platforms, that do not have implementations for the closure thunks).
Note: the CI for the V compiler, checks that V itself, can be compiled with `-no-closures`,
to ease porting.
-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=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.
-assert continues
Just prints the failed assertion then continues. Useful if you want to see
the failures of many assertions that are all in the same test_ function.
-thread-stack-size 4194304
Set the thread stack size to 4MB. Use multiples of 4096.
The default is 8MB on 64-bit targets and 2MB on 32-bit targets.
8MB is enough for compiling V programs, with deeply nested
expressions (~40 levels), while 32-bit targets use a smaller default
to reduce per-thread memory usage.
It may need to be increased, if you are getting stack overflow errors for
deeply recursive programs like some of the stages of the V compiler itself,
that use relatively few threads.
It may be decreased, to reduce the memory footprint of programs that launch
hundreds/thousands of threads, but where each of the threads does not need
a big stack.
-fast-math
When present, pass either -ffast-math or /fp:fast (for msvc) to the C compiler.
See https://en.wikipedia.org/wiki/Floating-point_arithmetic#%22Fast_math%22_optimization
https://learn.microsoft.com/en-us/cpp/build/reference/fp-specify-floating-point-behavior?view=msvc-170&redirectedfrom=MSDN
https://clang.llvm.org/docs/UsersManual.html#cmdoption-ffast-math
https://gcc.gnu.org/onlinedocs/gcc/Optimize-Options.html#index-ffast-math
-div-by-zero-is-zero
Avoids division by zero errors, by treating `x / 0` as being equal to `0`.
It also treats `x % 0` as being equal to `x`, because `x%y`==`x-y*(x/y)`,
which in turn eliminates another source of division by zero errors.
It is mainly useful when prototyping games, and other experimental code with
lots of arithmetic expressions, where you do not want to check for the zero divisor
all the time (which can break your flow).
-check-overflow
Enable runtime overflow checking for integer arithmetic operations (+, -, *).
Triggers a panic when integer overflow is detected.