$if condition

    If you want an if to be evaluated at compile time it must be prefixed with a $ sign. Right now it can be used to detect an OS, compiler, platform or compilation options. $if debug is a special option like $if windows or $if x32. If you’re using a custom ifdef, then you do need $if option ? {} and compile withv -d option. Full list of builtin options: | OS | Compilers | Platforms | Other | | —- | —- | —- | —- | | windows, linux, macos | gcc, tinyc | amd64, arm64 | debug, prod, test | | mac, darwin, ios, | clang, mingw | x64, x32 | js, glibc, prealloc | | android,mach, dragonfly | msvc | little_endian | no_bounds_checking, freestanding | | gnu, hpux, haiku, qnx | cplusplus | big_endian | no_segfault_handler, no_backtrace, no_main | | solaris | | | |

    1. // ignore
    2. import os
    3. fn main() {
    4. embedded_file := $embed_file('v.png')
    5. os.write_file('exported.png', embedded_file.to_string())?
    6. }

    V can embed arbitrary files into the executable with the $embed_file(<path>) compile time call. Paths can be absolute or relative to the source file.

    When you do not use -prod, the file will not be embedded. Instead, it will be loaded the first time your program calls embedded_file.data() at runtime, making it easier to change in external editor programs, without needing to recompile your executable.

    When you compile with -prod, the file will be embedded inside your executable, increasing your binary size, but making it more self contained and thus easier to distribute. In this case, embedded_file.data() will cause no IO, and it will always return the same data.

    $embed_file supports compression of the embedded file when compiling with -prod. Currently only one compression type is supported: zlib

    1. // ignore
    2. import os
    3. fn main() {
    4. embedded_file := $embed_file('v.png', .zlib) // compressed using zlib
    5. os.write_file('exported.png', embedded_file.to_string())?
    6. }

    $tmpl for embedding and parsing V template files

    V has a simple template language for text and html templates, and they can easily be embedded via $tmpl('path/to/template.txt'):

    1. // ignore
    2. fn build() string {
    3. name := 'Peter'
    4. age := 25
    5. numbers := [1, 2, 3]
    6. return $tmpl('1.txt')
    7. }
    8. println(build())
    9. }

    output:

    1. name: Peter
    2. age: 25
    3. numbers: [1, 2, 3]
    4. 1
    5. 2
    6. 3

    $env

    1. module main
    2. fn main() {
    3. compile_time_env := $env('ENV_VAR')
    4. println(compile_time_env)
    5. }

    V can bring in values at compile time from environment variables. $env('ENV_VAR') can also be used in top-level #flag and statements: #flag linux -I $env('JAVA_HOME')/include.

    $compile_error and $compile_warn

    These two comptime functions are very useful for displaying custom errors/warnings during compile time.

    Both receive as their only argument a string literal that contains the message to display:

    1. // failcompile nofmt
    2. // x.v
    3. module main
    4. $if linux {
    5. $compile_error('Linux is not supported')
    6. }
    7. fn main() {
    8. }
    9. $ v run x.v
    10. x.v:4:5: error: Linux is not supported
    11. 2 |
    12. 3 | $if linux {
    13. 4 | $compile_error('Linux is not supported')
    14. | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    15. 5 | }
    16. 6 |

    Environment specific files

    If a file has an environment-specific suffix, it will only be compiled for that environment.

    • .js.v => will be used only by the JS backend. These files can contain JS. code.
    • .c.v => will be used only by the C backend. These files can contain C. code.
    • .native.v => will be used only by V’s native backend.
    • _nix.c.v => will be used only on Unix systems (non Windows).
    • _${os}.c.v => will be used only on the specific os system. For example, _windows.c.v will be used only when compiling on Windows, or with -os windows.
    • _default.c.v => will be used only if there is NOT a more specific platform file. For example, if you have both file_linux.c.v and file_default.c.v, and you are compiling for linux, then only file_linux.c.v will be used, and file_default.c.v will be ignored.

    Here is a more complete example: main.v:

    1. // ignore
    2. module main
    3. const ( message = 'Hello world' )

    main_linux.c.v:

    1. // ignore
    2. module main
    3. const ( message = 'Hello linux' )

    main_windows.c.v:

    1. // ignore
    2. module main
    3. const ( message = 'Hello windows' )

    With the example above:

    • when you compile for windows, you will get ‘Hello windows’
    • when you compile for linux, you will get ‘Hello linux’
    • when you compile for any other platform, you will get the non specific ‘Hello world’ message.

    • _d_customflag.v => will be used only if you pass -d customflag to V. That corresponds to $if customflag ? {}, but for a whole file, not just a single block. customflag should be a snakecase identifier, it can not contain arbitrary characters (only lower case latin letters + numbers + `). NB: a combinatorial_d_customflag_linux.c.vpostfix will not work. If you do need a custom flag file, that has platform dependent code, use the postfix_d_customflag.v, and then use plaftorm dependent compile time conditional blocks inside it, i.e.$if linux {}` etc.