v: deprecate `@VROOT` in favour of `@VMODROOT` (#9795)

pull/9805/head
Delyan Angelov 2021-04-19 19:01:47 +03:00 committed by GitHub
parent 4b230d16b3
commit d4f31412b7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
41 changed files with 194 additions and 109 deletions

View File

@ -3555,20 +3555,20 @@ Module {
* Add these lines to the top of your module: * Add these lines to the top of your module:
```v oksyntax ```v oksyntax
#flag -I @VROOT/c #flag -I @VMODROOT/c
#flag @VROOT/c/implementation.o #flag @VMODROOT/c/implementation.o
#include "header.h" #include "header.h"
``` ```
NB: @VROOT will be replaced by V with the *nearest parent folder, where there is a v.mod file*. NB: @VMODROOT will be replaced by V with the *nearest parent folder, where there is a v.mod file*.
Any .v file beside or below the folder where the v.mod file is, Any .v file beside or below the folder where the v.mod file is,
can use `#flag @VROOT/abc` to refer to this folder. can use `#flag @VMODROOT/abc` to refer to this folder.
The @VROOT folder is also *prepended* to the module lookup path, The @VMODROOT folder is also *prepended* to the module lookup path,
so you can *import* other modules under your @VROOT, by just naming them. so you can *import* other modules under your @VMODROOT, by just naming them.
The instructions above will make V look for an compiled .o file in The instructions above will make V look for an compiled .o file in
your module `folder/c/implementation.o`. your module `folder/c/implementation.o`.
If V finds it, the .o file will get linked to the main executable, that used the module. If V finds it, the .o file will get linked to the main executable, that used the module.
If it does not find it, V assumes that there is a `@VROOT/c/implementation.c` file, If it does not find it, V assumes that there is a `@VMODROOT/c/implementation.c` file,
and tries to compile it to a .o file, then will use that. and tries to compile it to a .o file, then will use that.
This allows you to have C code, that is contained in a V module, so that its distribution is easier. This allows you to have C code, that is contained in a V module, so that its distribution is easier.
@ -3904,8 +3904,12 @@ that are substituted at compile time:
- `@LINE` => replaced with the V line number where it appears (as a string). - `@LINE` => replaced with the V line number where it appears (as a string).
- `@COLUMN` => replaced with the column where it appears (as a string). - `@COLUMN` => replaced with the column where it appears (as a string).
- `@VEXE` => replaced with the path to the V compiler - `@VEXE` => replaced with the path to the V compiler
- `@VEXEROOT` => will be substituted with the *folder*,
where the V executable is (as a string).
- `@VHASH` => replaced with the shortened commit hash of the V compiler (as a string). - `@VHASH` => replaced with the shortened commit hash of the V compiler (as a string).
- `@VMOD_FILE` => replaced with the contents of the nearest v.mod file (as a string). - `@VMOD_FILE` => replaced with the contents of the nearest v.mod file (as a string).
- `@VMODROOT` => will be substituted with the *folder*,
where the nearest v.mod file is (as a string).
That allows you to do the following example, useful while debugging/logging/tracing your code: That allows you to do the following example, useful while debugging/logging/tracing your code:
```v ```v

View File

@ -40,7 +40,7 @@ import time
import gg.m4 import gg.m4
// GLSL Include and functions // GLSL Include and functions
#flag -I @VROOT/. #flag -I @VMODROOT/.
#include "cube_glsl.h" #Please use sokol-shdc to generate the necessary cube_glsl.h file from cube_glsl.glsl (see the instructions at the top of this file) #include "cube_glsl.h" #Please use sokol-shdc to generate the necessary cube_glsl.h file from cube_glsl.glsl (see the instructions at the top of this file)
fn C.cube_shader_desc(gfx.Backend) &C.sg_shader_desc fn C.cube_shader_desc(gfx.Backend) &C.sg_shader_desc

View File

@ -41,7 +41,7 @@ import time
// GLSL Include and functions // GLSL Include and functions
#flag -I @VROOT/. #flag -I @VMODROOT/.
#include "rt_glsl.h" #Please use sokol-shdc to generate the necessary rt_glsl.h file from rt_glsl.glsl (see the instructions at the top of this file) #include "rt_glsl.h" #Please use sokol-shdc to generate the necessary rt_glsl.h file from rt_glsl.glsl (see the instructions at the top of this file)
fn C.rt_shader_desc(gfx.Backend) &C.sg_shader_desc fn C.rt_shader_desc(gfx.Backend) &C.sg_shader_desc

View File

@ -42,7 +42,7 @@ import sokol.sgl
import time import time
// GLSL Include and functions // GLSL Include and functions
#flag -I @VROOT/. #flag -I @VMODROOT/.
#include "rt_glsl_march.h" #Please use sokol-shdc to generate the necessary rt_glsl_march.h file from rt_glsl_march.glsl (see the instructions at the top of this file) #include "rt_glsl_march.h" #Please use sokol-shdc to generate the necessary rt_glsl_march.h file from rt_glsl_march.glsl (see the instructions at the top of this file)
#include "rt_glsl_puppy.h" #Please use sokol-shdc to generate the necessary rt_glsl_puppy.h file from rt_glsl_puppy.glsl (see the instructions at the top of this file) #include "rt_glsl_puppy.h" #Please use sokol-shdc to generate the necessary rt_glsl_puppy.h file from rt_glsl_puppy.glsl (see the instructions at the top of this file)
fn C.rt_march_shader_desc(gfx.Backend) &C.sg_shader_desc fn C.rt_march_shader_desc(gfx.Backend) &C.sg_shader_desc

View File

@ -79,7 +79,7 @@ mut:
/****************************************************************************** /******************************************************************************
* GLSL Include and functions * GLSL Include and functions
******************************************************************************/ ******************************************************************************/
#flag -I @VROOT/. #flag -I @VMODROOT/.
#include "rt_glsl_instancing.h" #Please use sokol-shdc to generate the necessary rt_glsl_march.h file from rt_glsl_march.glsl (see the instructions at the top of this file) #include "rt_glsl_instancing.h" #Please use sokol-shdc to generate the necessary rt_glsl_march.h file from rt_glsl_march.glsl (see the instructions at the top of this file)
fn C.instancing_shader_desc(gfx.Backend) &C.sg_shader_desc fn C.instancing_shader_desc(gfx.Backend) &C.sg_shader_desc

View File

@ -50,7 +50,7 @@ import obj
// GLSL Include and functions // GLSL Include and functions
#flag -I @VROOT/. #flag -I @VMODROOT/.
#include "gouraud.h" #Please use sokol-shdc to generate the necessary rt_glsl.h file from rt_glsl.glsl (see the instructions at the top of this file) #include "gouraud.h" #Please use sokol-shdc to generate the necessary rt_glsl.h file from rt_glsl.glsl (see the instructions at the top of this file)
fn C.gouraud_shader_desc(gfx.Backend) &C.sg_shader_desc fn C.gouraud_shader_desc(gfx.Backend) &C.sg_shader_desc

View File

@ -186,7 +186,7 @@ pub fn print(s string) {
} }
/* /*
#include "@VROOT/vlib/darwin/darwin.m" #include "@VEXEROOT/vlib/darwin/darwin.m"
fn C.nsstring2(s string) voidptr fn C.nsstring2(s string) voidptr
fn C.NSLog(x voidptr) fn C.NSLog(x voidptr)
#include <asl.h> #include <asl.h>

View File

@ -16,8 +16,8 @@ $if static_boehm ? {
#pkgconfig bdw-gc #pkgconfig bdw-gc
} }
$if windows { $if windows {
#flag -I@VROOT/thirdparty/libgc/include #flag -I@VEXEROOT/thirdparty/libgc/include
#flag -L@VROOT/thirdparty/libgc #flag -L@VEXEROOT/thirdparty/libgc
} }
#flag -lgc #flag -lgc
} }

View File

@ -2,5 +2,5 @@ module builtin
// TODO: Remove this later, added to make sure v self works // TODO: Remove this later, added to make sure v self works
$if ios { $if ios {
#include "@VROOT/thirdparty/ios/ios.m" #include "@VEXEROOT/thirdparty/ios/ios.m"
} }

View File

@ -3,7 +3,7 @@ module clipboard
#include <libkern/OSAtomic.h> #include <libkern/OSAtomic.h>
#include <Cocoa/Cocoa.h> #include <Cocoa/Cocoa.h>
#flag -framework Cocoa #flag -framework Cocoa
#include "@VROOT/vlib/clipboard/clipboard_darwin.m" #include "@VEXEROOT/vlib/clipboard/clipboard_darwin.m"
pub struct Clipboard { pub struct Clipboard {
pb voidptr pb voidptr
@ -14,7 +14,7 @@ mut:
fn C.darwin_new_pasteboard() voidptr fn C.darwin_new_pasteboard() voidptr
fn C.darwin_get_pasteboard_text(voidptr) byteptr fn C.darwin_get_pasteboard_text(voidptr) &byte
fn C.darwin_set_pasteboard_text(voidptr, string) bool fn C.darwin_set_pasteboard_text(voidptr, string) bool

View File

@ -8,7 +8,7 @@ module darwin
struct C.NSString {} struct C.NSString {}
#include "@VROOT/vlib/darwin/darwin.m" #include "@VEXEROOT/vlib/darwin/darwin.m"
fn C.nsstring2(s string) voidptr fn C.nsstring2(s string) voidptr
@ -30,10 +30,10 @@ pub fn nsstring(s string) voidptr {
// for .app packages: .../my.app/Contents/Resources // for .app packages: .../my.app/Contents/Resources
// for cli: .../parent_folder/Resources // for cli: .../parent_folder/Resources
fn C.CFBundleCopyResourcesDirectoryURL(bundle voidptr) byteptr fn C.CFBundleCopyResourcesDirectoryURL(bundle voidptr) &byte
fn C.CFBundleGetMainBundle() voidptr fn C.CFBundleGetMainBundle() voidptr
fn C.CFURLGetFileSystemRepresentation(url byteptr, resolve_against_base bool, buffer byteptr, buffer_size int) int fn C.CFURLGetFileSystemRepresentation(url &byte, resolve_against_base bool, buffer &byte, buffer_size int) int
fn C.CFRelease(url byteptr) fn C.CFRelease(url &byte)
pub fn resource_path() string { pub fn resource_path() string {
main_bundle := C.CFBundleGetMainBundle() main_bundle := C.CFBundleGetMainBundle()
@ -42,8 +42,10 @@ pub fn resource_path() string {
panic('CFBundleCopyResourcesDirectoryURL failed') panic('CFBundleCopyResourcesDirectoryURL failed')
} }
buffer_size := 4096 buffer_size := 4096
mut buffer := unsafe{ malloc(buffer_size) } mut buffer := unsafe { malloc(buffer_size) }
unsafe{ buffer[0] = 0 } unsafe {
buffer[0] = 0
}
conv_result := C.CFURLGetFileSystemRepresentation(resource_dir_url, true, buffer, conv_result := C.CFURLGetFileSystemRepresentation(resource_dir_url, true, buffer,
buffer_size) buffer_size)
if conv_result == 0 { if conv_result == 0 {

View File

@ -1,8 +1,8 @@
module fontstash module fontstash
#define FONS_USE_FREETYPE 1 #define FONS_USE_FREETYPE 1
#flag windows -I @VROOT/thirdparty/freetype/include #flag windows -I @VEXEROOT/thirdparty/freetype/include
#flag windows -L @VROOT/thirdparty/freetype/win64 #flag windows -L @VEXEROOT/thirdparty/freetype/win64
#flag linux -I/usr/include/freetype2 #flag linux -I/usr/include/freetype2
#flag darwin -I/usr/local/include/freetype2 #flag darwin -I/usr/local/include/freetype2
// brew on m1 // brew on m1

View File

@ -1,6 +1,6 @@
module fontstash module fontstash
#flag -I @VROOT/thirdparty/fontstash #flag -I @VEXEROOT/thirdparty/fontstash
#define FONTSTASH_IMPLEMENTATION #define FONTSTASH_IMPLEMENTATION
$if gcboehm ? { $if gcboehm ? {
#define FONTSTASH_MALLOC GC_MALLOC #define FONTSTASH_MALLOC GC_MALLOC

View File

@ -1,6 +1,6 @@
module gg module gg
#include "@VROOT/vlib/gg/gg_darwin.m" #include "@VEXEROOT/vlib/gg/gg_darwin.m"
fn C.gg_get_screen_size() Size fn C.gg_get_screen_size() Size

View File

@ -1,6 +1,6 @@
module hash module hash
//#flag -I @VROOT/thirdparty/wyhash //#flag -I @VEXEROOT/thirdparty/wyhash
//#include "wyhash.h" //#include "wyhash.h"
fn C.wyhash(byteptr, u64, u64, &u64) u64 fn C.wyhash(byteptr, u64, u64, &u64) u64
fn C.wyhash64(u64, u64) u64 fn C.wyhash64(u64, u64) u64

View File

@ -3,8 +3,8 @@
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module json module json
#flag -I @VROOT/thirdparty/cJSON #flag -I @VEXEROOT/thirdparty/cJSON
#flag @VROOT/thirdparty/cJSON/cJSON.o #flag @VEXEROOT/thirdparty/cJSON/cJSON.o
#include "cJSON.h" #include "cJSON.h"
#define js_get(object, key) cJSON_GetObjectItemCaseSensitive((object), (key)) #define js_get(object, key) cJSON_GetObjectItemCaseSensitive((object), (key))

View File

@ -1,8 +1,8 @@
module big module big
// Wrapper for https://github.com/kokke/tiny-bignum-c // Wrapper for https://github.com/kokke/tiny-bignum-c
#flag -I @VROOT/thirdparty/bignum #flag -I @VEXEROOT/thirdparty/bignum
#flag @VROOT/thirdparty/bignum/bn.o #flag @VEXEROOT/thirdparty/bignum/bn.o
#include "bn.h" #include "bn.h"
struct C.bn { struct C.bn {

View File

@ -6,7 +6,7 @@ module math
#include <math.h> #include <math.h>
$if windows { $if windows {
$if tinyc { $if tinyc {
#flag @VROOT/thirdparty/tcc/lib/openlibm.o #flag @VEXEROOT/thirdparty/tcc/lib/openlibm.o
} }
} }
fn C.acos(x f64) f64 fn C.acos(x f64) f64

View File

@ -1,5 +1,5 @@
module mysql module mysql
#flag windows -I@VROOT/thirdparty/mysql/include #flag windows -I@VEXEROOT/thirdparty/mysql/include
#flag windows @VROOT/thirdparty/mysql/lib/libmysql.dll #flag windows @VEXEROOT/thirdparty/mysql/lib/libmysql.dll
#include <mysql.h> # Please install https://dev.mysql.com/downloads/installer/ , then put the include/ and lib/ folders in thirdparty/mysql #include <mysql.h> # Please install https://dev.mysql.com/downloads/installer/ , then put the include/ and lib/ folders in thirdparty/mysql

View File

@ -3,7 +3,7 @@
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module http module http
#flag windows -I @VROOT/thirdparty/vschannel #flag windows -I @VEXEROOT/thirdparty/vschannel
#flag -l ws2_32 -l crypt32 -l secur32 -l user32 #flag -l ws2_32 -l crypt32 -l secur32 -l user32
#include "vschannel.c" #include "vschannel.c"

View File

@ -5,8 +5,8 @@ import io
#flag -lpq #flag -lpq
#flag linux -I/usr/include/postgresql #flag linux -I/usr/include/postgresql
#flag darwin -I/opt/local/include/postgresql11 #flag darwin -I/opt/local/include/postgresql11
#flag windows -I @VROOT/thirdparty/pg/include #flag windows -I @VEXEROOT/thirdparty/pg/include
#flag windows -L @VROOT/thirdparty/pg/win64 #flag windows -L @VEXEROOT/thirdparty/pg/win64
// PostgreSQL Source Code // PostgreSQL Source Code
// https://doxygen.postgresql.org/libpq-fe_8h.html // https://doxygen.postgresql.org/libpq-fe_8h.html

View File

@ -11,9 +11,9 @@ import picohttpparser
#include <netinet/tcp.h> #include <netinet/tcp.h>
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#flag -I @VROOT/thirdparty/picoev #flag -I @VEXEROOT/thirdparty/picoev
#flag -L @VROOT/thirdparty/picoev #flag -L @VEXEROOT/thirdparty/picoev
#flag @VROOT/thirdparty/picoev/picoev.o #flag @VEXEROOT/thirdparty/picoev/picoev.o
#include "src/picoev.h" #include "src/picoev.h"
const ( const (
max_fds = 1024 max_fds = 1024

View File

@ -3,9 +3,9 @@
// that can be found in the LICENSE file. // that can be found in the LICENSE file.
module picohttpparser module picohttpparser
#flag -I @VROOT/thirdparty/picohttpparser #flag -I @VEXEROOT/thirdparty/picohttpparser
#flag -L @VROOT/thirdparty/picohttpparser #flag -L @VEXEROOT/thirdparty/picohttpparser
#flag @VROOT/thirdparty/picohttpparser/picohttpparser.o #flag @VEXEROOT/thirdparty/picohttpparser/picohttpparser.o
#include "picohttpparser.h" #include "picohttpparser.h"

View File

@ -1,6 +1,6 @@
module audio module audio
#flag -I @VROOT/thirdparty/sokol #flag -I @VEXEROOT/thirdparty/sokol
#define SOKOL_IMPL #define SOKOL_IMPL
#include "sokol_audio.h" #include "sokol_audio.h"
#flag linux -lasound #flag linux -lasound

View File

@ -4,8 +4,8 @@ pub const (
used_import = 1 used_import = 1
) )
#flag -I @VROOT/thirdparty/sokol #flag -I @VEXEROOT/thirdparty/sokol
#flag -I @VROOT/thirdparty/sokol/util #flag -I @VEXEROOT/thirdparty/sokol/util
#flag freebsd -I /usr/local/include #flag freebsd -I /usr/local/include
#flag darwin -fobjc-arc #flag darwin -fobjc-arc
#flag linux -lX11 -lGL -lXcursor -lXi #flag linux -lX11 -lGL -lXcursor -lXi

View File

@ -5,11 +5,11 @@ module sqlite
#flag solaris -lsqlite3 #flag solaris -lsqlite3
#flag freebsd -I/usr/local/include #flag freebsd -I/usr/local/include
#flag freebsd -Wl -L/usr/local/lib -lsqlite3 #flag freebsd -Wl -L/usr/local/lib -lsqlite3
#flag windows -I@VROOT/thirdparty/sqlite #flag windows -I@VEXEROOT/thirdparty/sqlite
#flag windows -L@VROOT/thirdparty/sqlite #flag windows -L@VEXEROOT/thirdparty/sqlite
#flag windows @VROOT/thirdparty/sqlite/sqlite3.o #flag windows @VEXEROOT/thirdparty/sqlite/sqlite3.o
// #flag linux -I @VROOT/thirdparty/sqlite // #flag linux -I @VEXEROOT/thirdparty/sqlite
// #flag @VROOT/thirdparty/sqlite/sqlite.c // #flag @VEXEROOT/thirdparty/sqlite/sqlite.c
#include "sqlite3.h" #include "sqlite3.h"
// //
struct C.sqlite3 { struct C.sqlite3 {

View File

@ -4,9 +4,9 @@
module stbi module stbi
#flag -I @VROOT/thirdparty/stb_image #flag -I @VEXEROOT/thirdparty/stb_image
#include "stb_image.h" #include "stb_image.h"
#flag @VROOT/thirdparty/stb_image/stbi.o #flag @VEXEROOT/thirdparty/stb_image/stbi.o
pub struct Image { pub struct Image {
pub mut: pub mut:

View File

@ -5,17 +5,17 @@ Implements the atomic operations. For now TCC does not support
the atomic versions on nix so it uses locks to simulate the same behavor. the atomic versions on nix so it uses locks to simulate the same behavor.
On windows tcc can simulate with other atomic operations. On windows tcc can simulate with other atomic operations.
The @VROOT/thirdparty/stdatomic contains compability header files The @VEXEROOT/thirdparty/stdatomic contains compability header files
for stdatomic that supports both nix, windows and c++. for stdatomic that supports both nix, windows and c++.
This implementations should be regarded as alpha stage and be This implementations should be regarded as alpha stage and be
further tested. further tested.
*/ */
#flag windows -I @VROOT/thirdparty/stdatomic/win #flag windows -I @VEXEROOT/thirdparty/stdatomic/win
#flag linux -I @VROOT/thirdparty/stdatomic/nix #flag linux -I @VEXEROOT/thirdparty/stdatomic/nix
#flag darwin -I @VROOT/thirdparty/stdatomic/nix #flag darwin -I @VEXEROOT/thirdparty/stdatomic/nix
#flag freebsd -I @VROOT/thirdparty/stdatomic/nix #flag freebsd -I @VEXEROOT/thirdparty/stdatomic/nix
#flag solaris -I @VROOT/thirdparty/stdatomic/nix #flag solaris -I @VEXEROOT/thirdparty/stdatomic/nix
$if linux { $if linux {
$if tinyc { $if tinyc {
// most Linux distributions have /usr/lib/libatomic.so, but Ubuntu uses gcc version specific dir // most Linux distributions have /usr/lib/libatomic.so, but Ubuntu uses gcc version specific dir

View File

@ -3,11 +3,10 @@ module sync
import time import time
import rand import rand
$if windows { $if windows {
#flag -I @VROOT/thirdparty/stdatomic/win #flag -I @VEXEROOT/thirdparty/stdatomic/win
} $else { } $else {
#flag -I @VROOT/thirdparty/stdatomic/nix #flag -I @VEXEROOT/thirdparty/stdatomic/nix
} }
$if linux { $if linux {
@ -198,7 +197,7 @@ fn (mut ch Channel) try_push_priv(src voidptr, no_block bool) ChanState {
if C.atomic_load_u16(&ch.closed) != 0 { if C.atomic_load_u16(&ch.closed) != 0 {
return .closed return .closed
} }
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { spinloops, spinloops_sem } spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { sync.spinloops, sync.spinloops_sem }
mut have_swapped := false mut have_swapped := false
for { for {
mut got_sem := false mut got_sem := false
@ -387,7 +386,7 @@ pub fn (mut ch Channel) try_pop(dest voidptr) ChanState {
} }
fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState { fn (mut ch Channel) try_pop_priv(dest voidptr, no_block bool) ChanState {
spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { spinloops, spinloops_sem } spinloops_sem_, spinloops_ := if no_block { 1, 1 } else { sync.spinloops, sync.spinloops_sem }
mut have_swapped := false mut have_swapped := false
mut write_in_progress := false mut write_in_progress := false
for { for {

View File

@ -2,7 +2,7 @@ module szip
import os import os
#flag -I @VROOT/thirdparty/zip #flag -I @VEXEROOT/thirdparty/zip
#include "zip.c" #include "zip.c"
#include "zip.h" #include "zip.h"

View File

@ -18,16 +18,16 @@ const int_min = int(0x80000000)
const int_max = int(0x7FFFFFFF) const int_max = int(0x7FFFFFFF)
const ( const (
valid_comp_if_os = ['windows', 'ios', 'macos', 'mach', 'darwin', 'hpux', 'gnu', 'qnx', valid_comp_if_os = ['windows', 'ios', 'macos', 'mach', 'darwin', 'hpux', 'gnu',
'linux', 'freebsd', 'openbsd', 'netbsd', 'bsd', 'dragonfly', 'android', 'solaris', 'haiku', 'qnx', 'linux', 'freebsd', 'openbsd', 'netbsd', 'bsd', 'dragonfly', 'android', 'solaris',
'linux_or_macos', 'haiku', 'linux_or_macos']
] valid_comp_if_compilers = ['gcc', 'tinyc', 'clang', 'mingw', 'msvc', 'cplusplus']
valid_comp_if_compilers = ['gcc', 'tinyc', 'clang', 'mingw', 'msvc', 'cplusplus'] valid_comp_if_platforms = ['amd64', 'aarch64', 'x64', 'x32', 'little_endian', 'big_endian']
valid_comp_if_platforms = ['amd64', 'aarch64', 'x64', 'x32', 'little_endian', 'big_endian'] valid_comp_if_other = ['js', 'debug', 'prod', 'test', 'glibc', 'prealloc',
valid_comp_if_other = ['js', 'debug', 'prod', 'test', 'glibc', 'prealloc',
'no_bounds_checking', 'freestanding'] 'no_bounds_checking', 'freestanding']
array_builtin_methods = ['filter', 'clone', 'repeat', 'reverse', 'map', 'slice', 'sort', array_builtin_methods = ['filter', 'clone', 'repeat', 'reverse', 'map', 'slice', 'sort',
'contains', 'index', 'wait', 'any', 'all', 'first', 'last', 'pop'] 'contains', 'index', 'wait', 'any', 'all', 'first', 'last', 'pop']
vroot_is_deprecated_message = '@VROOT is deprecated, use @VMODROOT or @VEXEROOT instead'
) )
pub struct Checker { pub struct Checker {
@ -99,7 +99,7 @@ pub fn new_checker(table &ast.Table, pref &pref.Preferences) Checker {
} }
pub fn (mut c Checker) check(ast_file &ast.File) { pub fn (mut c Checker) check(ast_file &ast.File) {
c.file = ast_file c.change_current_file(ast_file)
for i, ast_import in ast_file.imports { for i, ast_import in ast_file.imports {
for j in 0 .. i { for j in 0 .. i {
if ast_import.mod == ast_file.imports[j].mod { if ast_import.mod == ast_file.imports[j].mod {
@ -139,13 +139,19 @@ pub fn (mut c Checker) check_scope_vars(sc &ast.Scope) {
// not used right now // not used right now
pub fn (mut c Checker) check2(ast_file &ast.File) []errors.Error { pub fn (mut c Checker) check2(ast_file &ast.File) []errors.Error {
c.file = ast_file c.change_current_file(ast_file)
for stmt in ast_file.stmts { for stmt in ast_file.stmts {
c.stmt(stmt) c.stmt(stmt)
} }
return c.errors return c.errors
} }
pub fn (mut c Checker) change_current_file(file &ast.File) {
c.file = file
c.vmod_file_content = ''
c.mod = file.mod.name
}
pub fn (mut c Checker) check_files(ast_files []ast.File) { pub fn (mut c Checker) check_files(ast_files []ast.File) {
// c.files = ast_files // c.files = ast_files
mut has_main_mod_file := false mut has_main_mod_file := false
@ -183,21 +189,18 @@ pub fn (mut c Checker) check_files(ast_files []ast.File) {
} }
c.timers.start('checker_post_process_generic_fns') c.timers.start('checker_post_process_generic_fns')
last_file := c.file last_file := c.file
last_mod := c.mod
// post process generic functions. must be done after all files have been // post process generic functions. must be done after all files have been
// checked, to eunsure all generic calls are processed as this information // checked, to eunsure all generic calls are processed as this information
// is needed when the generic type is auto inferred from the call argument // is needed when the generic type is auto inferred from the call argument
for i in 0 .. ast_files.len { for i in 0 .. ast_files.len {
file := unsafe { &ast_files[i] } file := unsafe { &ast_files[i] }
if file.generic_fns.len > 0 { if file.generic_fns.len > 0 {
c.file = file c.change_current_file(file)
c.mod = file.mod.name
c.post_process_generic_fns() c.post_process_generic_fns()
} }
} }
// restore the original c.file && c.mod after post processing // restore the original c.file && c.mod after post processing
c.file = last_file c.change_current_file(last_file)
c.mod = last_mod
c.timers.show('checker_post_process_generic_fns') c.timers.show('checker_post_process_generic_fns')
// //
c.timers.start('checker_verify_all_vweb_routes') c.timers.start('checker_verify_all_vweb_routes')
@ -3968,7 +3971,23 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
'include' { 'include' {
mut flag := node.main mut flag := node.main
if flag.contains('@VROOT') { if flag.contains('@VROOT') {
vroot := util.resolve_vroot(flag, c.file.path) or { // c.note(checker.vroot_is_deprecated_message, node.pos)
vroot := util.resolve_vmodroot(flag.replace('@VROOT', '@VMODROOT'), c.file.path) or {
c.error(err.msg, node.pos)
return
}
node.val = 'include $vroot'
node.main = vroot
flag = vroot
}
if flag.contains('@VEXEROOT') {
vroot := flag.replace('@VEXEROOT', os.dir(pref.vexe_path()))
node.val = 'include $vroot'
node.main = vroot
flag = vroot
}
if flag.contains('@VMODROOT') {
vroot := util.resolve_vmodroot(flag, c.file.path) or {
c.error(err.msg, node.pos) c.error(err.msg, node.pos)
return return
} }
@ -4012,9 +4031,19 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
'flag' { 'flag' {
// #flag linux -lm // #flag linux -lm
mut flag := node.main mut flag := node.main
// expand `@VROOT` to its absolute path
if flag.contains('@VROOT') { if flag.contains('@VROOT') {
flag = util.resolve_vroot(flag, c.file.path) or { // c.note(checker.vroot_is_deprecated_message, node.pos)
flag = util.resolve_vmodroot(flag.replace('@VROOT', '@VMODROOT'), c.file.path) or {
c.error(err.msg, node.pos)
return
}
}
if flag.contains('@VEXEROOT') {
// expand `@VEXEROOT` to its absolute path
flag = flag.replace('@VEXEROOT', os.dir(pref.vexe_path()))
}
if flag.contains('@VMODROOT') {
flag = util.resolve_vmodroot(flag, c.file.path) or {
c.error(err.msg, node.pos) c.error(err.msg, node.pos)
return return
} }
@ -4027,7 +4056,10 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) {
} }
for deprecated in ['@VMOD', '@VMODULE', '@VPATH', '@VLIB_PATH'] { for deprecated in ['@VMOD', '@VMODULE', '@VPATH', '@VLIB_PATH'] {
if flag.contains(deprecated) { if flag.contains(deprecated) {
c.error('$deprecated had been deprecated, use @VROOT instead.', node.pos) if !flag.contains('@VMODROOT') {
c.error('$deprecated had been deprecated, use @VMODROOT instead.',
node.pos)
}
} }
} }
// println('adding flag "$flag"') // println('adding flag "$flag"')
@ -4644,6 +4676,7 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type {
node.val = util.vhash() node.val = util.vhash()
} }
.vmod_file { .vmod_file {
// cache the vmod content, do not read it many times
if c.vmod_file_content.len == 0 { if c.vmod_file_content.len == 0 {
mut mcache := vmod.get_cache() mut mcache := vmod.get_cache()
vmod_file_location := mcache.get_by_file(c.file.path) vmod_file_location := mcache.get_by_file(c.file.path)
@ -4652,14 +4685,21 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type {
node.pos) node.pos)
} }
vmod_content := os.read_file(vmod_file_location.vmod_file) or { '' } vmod_content := os.read_file(vmod_file_location.vmod_file) or { '' }
$if windows { c.vmod_file_content = vmod_content.replace('\r\n', '\n') // normalise EOLs just in case
c.vmod_file_content = vmod_content.replace('\r\n', '\n')
} $else {
c.vmod_file_content = vmod_content
}
} }
node.val = c.vmod_file_content node.val = c.vmod_file_content
} }
.vroot_path {
node.val = os.dir(pref.vexe_path())
}
.vexeroot_path {
node.val = os.dir(pref.vexe_path())
}
.vmodroot_path {
mut mcache := vmod.get_cache()
vmod_file_location := mcache.get_by_file(c.file.path)
node.val = os.dir(vmod_file_location.vmod_file)
}
.unknown { .unknown {
c.error('unknown @ identifier: ${node.name}. Available identifiers: $token.valid_at_tokens', c.error('unknown @ identifier: ${node.name}. Available identifiers: $token.valid_at_tokens',
node.pos) node.pos)
@ -6594,6 +6634,7 @@ fn (mut c Checker) verify_all_vweb_routes() {
return return
} }
typ_vweb_result := c.table.find_type_idx('vweb.Result') typ_vweb_result := c.table.find_type_idx('vweb.Result')
old_file := c.file
for vgt in c.vweb_gen_types { for vgt in c.vweb_gen_types {
sym_app := c.table.get_type_symbol(vgt) sym_app := c.table.get_type_symbol(vgt)
for m in sym_app.methods { for m in sym_app.methods {
@ -6606,7 +6647,7 @@ fn (mut c Checker) verify_all_vweb_routes() {
} }
if f.return_type == typ_vweb_result && f.receiver.typ == m.params[0].typ if f.return_type == typ_vweb_result && f.receiver.typ == m.params[0].typ
&& f.name == m.name { && f.name == m.name {
c.file = f.source_file // setup of file path for the warning c.change_current_file(f.source_file) // setup of file path for the warning
c.warn('mismatched parameters count between vweb method `${sym_app.name}.$m.name` ($nargs) and route attribute $m.attrs ($nroute_attributes)', c.warn('mismatched parameters count between vweb method `${sym_app.name}.$m.name` ($nargs) and route attribute $m.attrs ($nroute_attributes)',
f.pos) f.pos)
} }
@ -6614,6 +6655,7 @@ fn (mut c Checker) verify_all_vweb_routes() {
} }
} }
} }
c.change_current_file(old_file)
} }
fn (mut c Checker) trace(fbase string, message string) { fn (mut c Checker) trace(fbase string, message string) {

View File

@ -279,12 +279,15 @@ fn (mut p Parser) at() ast.AtExpr {
'@METHOD' { token.AtKind.method_name } '@METHOD' { token.AtKind.method_name }
'@MOD' { token.AtKind.mod_name } '@MOD' { token.AtKind.mod_name }
'@STRUCT' { token.AtKind.struct_name } '@STRUCT' { token.AtKind.struct_name }
'@VEXE' { token.AtKind.vexe_path }
'@FILE' { token.AtKind.file_path } '@FILE' { token.AtKind.file_path }
'@LINE' { token.AtKind.line_nr } '@LINE' { token.AtKind.line_nr }
'@COLUMN' { token.AtKind.column_nr } '@COLUMN' { token.AtKind.column_nr }
'@VHASH' { token.AtKind.vhash } '@VHASH' { token.AtKind.vhash }
'@VMOD_FILE' { token.AtKind.vmod_file } '@VMOD_FILE' { token.AtKind.vmod_file }
'@VEXE' { token.AtKind.vexe_path }
'@VEXEROOT' { token.AtKind.vexeroot_path }
'@VMODROOT' { token.AtKind.vmodroot_path }
'@VROOT' { token.AtKind.vroot_path } // deprecated, use @VEXEROOT or @VMODROOT
else { token.AtKind.unknown } else { token.AtKind.unknown }
} }
p.next() p.next()

View File

@ -0,0 +1,4 @@
int add(int a, int b) {
return a + b;
}

View File

@ -0,0 +1,3 @@
This file has invalid content, but is here just
to make sure that @VMODROOT works by locating the folder
of the nearest v.mod file, and using it as an anchor.

View File

@ -0,0 +1,18 @@
// Tests that VMODROOT finds the nearest v.mod file, which in
// this case is in the current folder, so in effect, @VMODROOT
// is the same as the absolute path of `.` .
// ==> @VMODROOT/includes === ./includes
#flag -I@VMODROOT/includes
#include "myinclude.h"
fn C.add(int, int) int
// Tests that VROOT works no matter the current folder
#flag -I @VEXEROOT/thirdparty/stb_image
#include "stb_image.h"
fn test_vroot_and_vmodroot() {
x := C.add(123, 456)
dump(x)
assert x == 579
}

View File

@ -9,7 +9,7 @@
import rand import rand
import sync import sync
#flag -I@VROOT/vlib/v/tests #flag -I@VEXEROOT/vlib/v/tests
#include "keep_args_alive_test_c.h" #include "keep_args_alive_test_c.h"
fn C.atomic_load_ptr(voidptr) voidptr fn C.atomic_load_ptr(voidptr) voidptr

View File

@ -1,4 +1,4 @@
#include "@VROOT/cstruct.h" #include "@VMODROOT/cstruct.h"
const the_string = 'the string' const the_string = 'the string'

View File

@ -1,7 +1,7 @@
module mod1 module mod1
#flag -I @VROOT/c #flag -I @VMODROOT/c
#flag @VROOT/c/implementation.o #flag @VMODROOT/c/implementation.o
#include "header.h" #include "header.h"

View File

@ -1,7 +1,7 @@
module modc module modc
#flag -I @VROOT #flag -I @VMODROOT
#flag @VROOT/impl.o #flag @VMODROOT/impl.o
#include "header.h" #include "header.h"
struct C.Atype { struct C.Atype {

View File

@ -141,17 +141,24 @@ const (
// @METHOD => will be substituted with ReceiverType.MethodName // @METHOD => will be substituted with ReceiverType.MethodName
// @MOD => will be substituted with the name of the current V module // @MOD => will be substituted with the name of the current V module
// @STRUCT => will be substituted with the name of the current V struct // @STRUCT => will be substituted with the name of the current V struct
// @VEXE => will be substituted with the path to the V compiler
// @FILE => will be substituted with the path of the V source file // @FILE => will be substituted with the path of the V source file
// @LINE => will be substituted with the V line number where it appears (as a string). // @LINE => will be substituted with the V line number where it appears (as a string).
// @COLUMN => will be substituted with the column where it appears (as a string). // @COLUMN => will be substituted with the column where it appears (as a string).
// @VHASH => will be substituted with the shortened commit hash of the V compiler (as a string). // @VHASH => will be substituted with the shortened commit hash of the V compiler (as a string).
// @VMOD_FILE => will be substituted with the contents of the nearest v.mod file (as a string). // @VMOD_FILE => will be substituted with the contents of the nearest v.mod file (as a string).
// This allows things like this: // @VMODROOT => will be substituted with the *folder* where the nearest v.mod file is (as a string).
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @MOD + '.' + @FN) // @VEXE => will be substituted with the path to the V compiler
// ... which is useful while debugging/tracing // @VEXEROOT => will be substituted with the *folder* where the V executable is (as a string).
// @VROOT => the old name for @VMODROOT; sometimes it was used as @VEXEROOT;
// NB: @VROOT is now deprecated, use either @VMODROOT or @VEXEROOT instead.
// NB: @VEXEROOT & @VMODROOT are used for compilation options like this:
// #include "@VMODROOT/include/abc.h"
// #flag -L@VEXEROOT/thirdparty/libgc
//
// The @XYZ tokens allow for code like this:
// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @MOD + '.' + @FN)
// ... which is useful while debugging/tracing.
// //
// @VROOT is special and handled in places like '#include ...'
// @<type> is allowed for keyword variable names. E.g. 'type' // @<type> is allowed for keyword variable names. E.g. 'type'
pub enum AtKind { pub enum AtKind {
unknown unknown
@ -165,11 +172,14 @@ pub enum AtKind {
column_nr column_nr
vhash vhash
vmod_file vmod_file
vmodroot_path
vroot_path // obsolete
vexeroot_path
} }
pub const ( pub const (
valid_at_tokens = ['@FN', '@METHOD', '@MOD', '@STRUCT', '@VEXE', '@FILE', '@LINE', '@COLUMN', valid_at_tokens = ['@VROOT', '@VMODROOT', '@VEXEROOT', '@FN', '@METHOD', '@MOD', '@STRUCT',
'@VHASH', '@VMOD_FILE'] '@VEXE', '@FILE', '@LINE', '@COLUMN', '@VHASH', '@VMOD_FILE']
) )
// build_keys genereates a map with keywords' string values: // build_keys genereates a map with keywords' string values:

View File

@ -134,15 +134,15 @@ pub fn set_vroot_folder(vroot_path string) {
os.setenv('VCHILD', 'true', true) os.setenv('VCHILD', 'true', true)
} }
pub fn resolve_vroot(str string, dir string) ?string { pub fn resolve_vmodroot(str string, dir string) ?string {
mut mcache := vmod.get_cache() mut mcache := vmod.get_cache()
vmod_file_location := mcache.get_by_folder(dir) vmod_file_location := mcache.get_by_folder(dir)
if vmod_file_location.vmod_file.len == 0 { if vmod_file_location.vmod_file.len == 0 {
// There was no actual v.mod file found. // There was no actual v.mod file found.
return error('To use @VROOT, you need to have a "v.mod" file in $dir, or in one of its parent folders.') return error('To use @VMODROOT, you need to have a "v.mod" file in $dir, or in one of its parent folders.')
} }
vmod_path := vmod_file_location.vmod_folder vmod_path := vmod_file_location.vmod_folder
return str.replace('@VROOT', os.real_path(vmod_path)) return str.replace('@VMODROOT', os.real_path(vmod_path))
} }
// resolve_env_value replaces all occurrences of `$env('ENV_VAR_NAME')` // resolve_env_value replaces all occurrences of `$env('ENV_VAR_NAME')`