diff --git a/doc/docs.md b/doc/docs.md index f3417d2aec..632479aedb 100644 --- a/doc/docs.md +++ b/doc/docs.md @@ -3555,20 +3555,20 @@ Module { * Add these lines to the top of your module: ```v oksyntax -#flag -I @VROOT/c -#flag @VROOT/c/implementation.o +#flag -I @VMODROOT/c +#flag @VMODROOT/c/implementation.o #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, -can use `#flag @VROOT/abc` to refer to this folder. -The @VROOT folder is also *prepended* to the module lookup path, -so you can *import* other modules under your @VROOT, by just naming them. +can use `#flag @VMODROOT/abc` to refer to this folder. +The @VMODROOT folder is also *prepended* to the module lookup path, +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 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 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. 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). - `@COLUMN` => replaced with the column where it appears (as a string). - `@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). - `@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: ```v diff --git a/examples/sokol/02_cubes_glsl/cube_glsl.v b/examples/sokol/02_cubes_glsl/cube_glsl.v index 75331788fe..2c4289d211 100644 --- a/examples/sokol/02_cubes_glsl/cube_glsl.v +++ b/examples/sokol/02_cubes_glsl/cube_glsl.v @@ -40,7 +40,7 @@ import time import gg.m4 // 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) fn C.cube_shader_desc(gfx.Backend) &C.sg_shader_desc diff --git a/examples/sokol/03_march_tracing_glsl/rt_glsl.v b/examples/sokol/03_march_tracing_glsl/rt_glsl.v index 4d43164b09..cdafec9d08 100644 --- a/examples/sokol/03_march_tracing_glsl/rt_glsl.v +++ b/examples/sokol/03_march_tracing_glsl/rt_glsl.v @@ -41,7 +41,7 @@ import time // 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) fn C.rt_shader_desc(gfx.Backend) &C.sg_shader_desc diff --git a/examples/sokol/04_multi_shader_glsl/rt_glsl.v b/examples/sokol/04_multi_shader_glsl/rt_glsl.v index 0f849fa8e5..8299831f43 100644 --- a/examples/sokol/04_multi_shader_glsl/rt_glsl.v +++ b/examples/sokol/04_multi_shader_glsl/rt_glsl.v @@ -42,7 +42,7 @@ import sokol.sgl import time // 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_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 diff --git a/examples/sokol/05_instancing_glsl/rt_glsl.v b/examples/sokol/05_instancing_glsl/rt_glsl.v index 21a7180ea2..90a6163c4b 100644 --- a/examples/sokol/05_instancing_glsl/rt_glsl.v +++ b/examples/sokol/05_instancing_glsl/rt_glsl.v @@ -79,7 +79,7 @@ mut: /****************************************************************************** * 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) fn C.instancing_shader_desc(gfx.Backend) &C.sg_shader_desc diff --git a/examples/sokol/06_obj_viewer/show_obj.v b/examples/sokol/06_obj_viewer/show_obj.v index 7f11cf977c..346537d01f 100644 --- a/examples/sokol/06_obj_viewer/show_obj.v +++ b/examples/sokol/06_obj_viewer/show_obj.v @@ -50,7 +50,7 @@ import obj // 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) fn C.gouraud_shader_desc(gfx.Backend) &C.sg_shader_desc diff --git a/vlib/builtin/builtin.c.v b/vlib/builtin/builtin.c.v index 4bfa0a5989..a91e44da8f 100644 --- a/vlib/builtin/builtin.c.v +++ b/vlib/builtin/builtin.c.v @@ -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.NSLog(x voidptr) #include diff --git a/vlib/builtin/builtin_d_gcboehm.v b/vlib/builtin/builtin_d_gcboehm.v index f773c3ca8b..f6a6bc88b7 100644 --- a/vlib/builtin/builtin_d_gcboehm.v +++ b/vlib/builtin/builtin_d_gcboehm.v @@ -16,8 +16,8 @@ $if static_boehm ? { #pkgconfig bdw-gc } $if windows { - #flag -I@VROOT/thirdparty/libgc/include - #flag -L@VROOT/thirdparty/libgc + #flag -I@VEXEROOT/thirdparty/libgc/include + #flag -L@VEXEROOT/thirdparty/libgc } #flag -lgc } diff --git a/vlib/builtin/builtin_ios.c.v b/vlib/builtin/builtin_ios.c.v index 9b850438f5..f745b4df5b 100644 --- a/vlib/builtin/builtin_ios.c.v +++ b/vlib/builtin/builtin_ios.c.v @@ -2,5 +2,5 @@ module builtin // TODO: Remove this later, added to make sure v self works $if ios { - #include "@VROOT/thirdparty/ios/ios.m" + #include "@VEXEROOT/thirdparty/ios/ios.m" } diff --git a/vlib/clipboard/clipboard_darwin.c.v b/vlib/clipboard/clipboard_darwin.c.v index b2ac704533..eff5d3b2ad 100644 --- a/vlib/clipboard/clipboard_darwin.c.v +++ b/vlib/clipboard/clipboard_darwin.c.v @@ -3,7 +3,7 @@ module clipboard #include #include #flag -framework Cocoa -#include "@VROOT/vlib/clipboard/clipboard_darwin.m" +#include "@VEXEROOT/vlib/clipboard/clipboard_darwin.m" pub struct Clipboard { pb voidptr @@ -14,7 +14,7 @@ mut: 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 diff --git a/vlib/darwin/darwin.v b/vlib/darwin/darwin.v index ef39b98f00..a43912dfd9 100644 --- a/vlib/darwin/darwin.v +++ b/vlib/darwin/darwin.v @@ -8,7 +8,7 @@ module darwin struct C.NSString {} -#include "@VROOT/vlib/darwin/darwin.m" +#include "@VEXEROOT/vlib/darwin/darwin.m" fn C.nsstring2(s string) voidptr @@ -30,10 +30,10 @@ pub fn nsstring(s string) voidptr { // for .app packages: .../my.app/Contents/Resources // for cli: .../parent_folder/Resources -fn C.CFBundleCopyResourcesDirectoryURL(bundle voidptr) byteptr +fn C.CFBundleCopyResourcesDirectoryURL(bundle voidptr) &byte fn C.CFBundleGetMainBundle() voidptr -fn C.CFURLGetFileSystemRepresentation(url byteptr, resolve_against_base bool, buffer byteptr, buffer_size int) int -fn C.CFRelease(url byteptr) +fn C.CFURLGetFileSystemRepresentation(url &byte, resolve_against_base bool, buffer &byte, buffer_size int) int +fn C.CFRelease(url &byte) pub fn resource_path() string { main_bundle := C.CFBundleGetMainBundle() @@ -42,8 +42,10 @@ pub fn resource_path() string { panic('CFBundleCopyResourcesDirectoryURL failed') } buffer_size := 4096 - mut buffer := unsafe{ malloc(buffer_size) } - unsafe{ buffer[0] = 0 } + mut buffer := unsafe { malloc(buffer_size) } + unsafe { + buffer[0] = 0 + } conv_result := C.CFURLGetFileSystemRepresentation(resource_dir_url, true, buffer, buffer_size) if conv_result == 0 { diff --git a/vlib/fontstash/a_d_use_freetype.v b/vlib/fontstash/a_d_use_freetype.v index 757c9270f8..199fe31072 100644 --- a/vlib/fontstash/a_d_use_freetype.v +++ b/vlib/fontstash/a_d_use_freetype.v @@ -1,8 +1,8 @@ module fontstash #define FONS_USE_FREETYPE 1 -#flag windows -I @VROOT/thirdparty/freetype/include -#flag windows -L @VROOT/thirdparty/freetype/win64 +#flag windows -I @VEXEROOT/thirdparty/freetype/include +#flag windows -L @VEXEROOT/thirdparty/freetype/win64 #flag linux -I/usr/include/freetype2 #flag darwin -I/usr/local/include/freetype2 // brew on m1 diff --git a/vlib/fontstash/fontstash.v b/vlib/fontstash/fontstash.v index 9dccdad017..00f72cf13f 100644 --- a/vlib/fontstash/fontstash.v +++ b/vlib/fontstash/fontstash.v @@ -1,6 +1,6 @@ module fontstash -#flag -I @VROOT/thirdparty/fontstash +#flag -I @VEXEROOT/thirdparty/fontstash #define FONTSTASH_IMPLEMENTATION $if gcboehm ? { #define FONTSTASH_MALLOC GC_MALLOC diff --git a/vlib/gg/gg_darwin.c.v b/vlib/gg/gg_darwin.c.v index c44ccf87f6..78e8a4545c 100644 --- a/vlib/gg/gg_darwin.c.v +++ b/vlib/gg/gg_darwin.c.v @@ -1,6 +1,6 @@ module gg -#include "@VROOT/vlib/gg/gg_darwin.m" +#include "@VEXEROOT/vlib/gg/gg_darwin.m" fn C.gg_get_screen_size() Size diff --git a/vlib/hash/wyhash.c.v b/vlib/hash/wyhash.c.v index 4671ae2bcd..acd6eb8ab2 100644 --- a/vlib/hash/wyhash.c.v +++ b/vlib/hash/wyhash.c.v @@ -1,6 +1,6 @@ module hash -//#flag -I @VROOT/thirdparty/wyhash +//#flag -I @VEXEROOT/thirdparty/wyhash //#include "wyhash.h" fn C.wyhash(byteptr, u64, u64, &u64) u64 fn C.wyhash64(u64, u64) u64 diff --git a/vlib/json/json_primitives.v b/vlib/json/json_primitives.v index 86c0684726..0631899144 100644 --- a/vlib/json/json_primitives.v +++ b/vlib/json/json_primitives.v @@ -3,8 +3,8 @@ // that can be found in the LICENSE file. module json -#flag -I @VROOT/thirdparty/cJSON -#flag @VROOT/thirdparty/cJSON/cJSON.o +#flag -I @VEXEROOT/thirdparty/cJSON +#flag @VEXEROOT/thirdparty/cJSON/cJSON.o #include "cJSON.h" #define js_get(object, key) cJSON_GetObjectItemCaseSensitive((object), (key)) diff --git a/vlib/math/big/big.v b/vlib/math/big/big.v index b07c44e05e..0bbb5717d9 100644 --- a/vlib/math/big/big.v +++ b/vlib/math/big/big.v @@ -1,8 +1,8 @@ module big // Wrapper for https://github.com/kokke/tiny-bignum-c -#flag -I @VROOT/thirdparty/bignum -#flag @VROOT/thirdparty/bignum/bn.o +#flag -I @VEXEROOT/thirdparty/bignum +#flag @VEXEROOT/thirdparty/bignum/bn.o #include "bn.h" struct C.bn { diff --git a/vlib/math/math.c.v b/vlib/math/math.c.v index f6ce74dbed..534d9ae842 100644 --- a/vlib/math/math.c.v +++ b/vlib/math/math.c.v @@ -6,7 +6,7 @@ module math #include $if windows { $if tinyc { - #flag @VROOT/thirdparty/tcc/lib/openlibm.o + #flag @VEXEROOT/thirdparty/tcc/lib/openlibm.o } } fn C.acos(x f64) f64 diff --git a/vlib/mysql/_cdefs_windows.c.v b/vlib/mysql/_cdefs_windows.c.v index 64f96efb95..9e186966ed 100644 --- a/vlib/mysql/_cdefs_windows.c.v +++ b/vlib/mysql/_cdefs_windows.c.v @@ -1,5 +1,5 @@ module mysql -#flag windows -I@VROOT/thirdparty/mysql/include -#flag windows @VROOT/thirdparty/mysql/lib/libmysql.dll +#flag windows -I@VEXEROOT/thirdparty/mysql/include +#flag windows @VEXEROOT/thirdparty/mysql/lib/libmysql.dll #include # Please install https://dev.mysql.com/downloads/installer/ , then put the include/ and lib/ folders in thirdparty/mysql diff --git a/vlib/net/http/backend_windows.c.v b/vlib/net/http/backend_windows.c.v index 8c06478f1e..702afee234 100644 --- a/vlib/net/http/backend_windows.c.v +++ b/vlib/net/http/backend_windows.c.v @@ -3,7 +3,7 @@ // that can be found in the LICENSE file. module http -#flag windows -I @VROOT/thirdparty/vschannel +#flag windows -I @VEXEROOT/thirdparty/vschannel #flag -l ws2_32 -l crypt32 -l secur32 -l user32 #include "vschannel.c" diff --git a/vlib/pg/pg.v b/vlib/pg/pg.v index cb83d05916..615c781406 100644 --- a/vlib/pg/pg.v +++ b/vlib/pg/pg.v @@ -5,8 +5,8 @@ import io #flag -lpq #flag linux -I/usr/include/postgresql #flag darwin -I/opt/local/include/postgresql11 -#flag windows -I @VROOT/thirdparty/pg/include -#flag windows -L @VROOT/thirdparty/pg/win64 +#flag windows -I @VEXEROOT/thirdparty/pg/include +#flag windows -L @VEXEROOT/thirdparty/pg/win64 // PostgreSQL Source Code // https://doxygen.postgresql.org/libpq-fe_8h.html diff --git a/vlib/picoev/picoev.v b/vlib/picoev/picoev.v index 58678d69fc..3277b376a8 100644 --- a/vlib/picoev/picoev.v +++ b/vlib/picoev/picoev.v @@ -11,9 +11,9 @@ import picohttpparser #include #include #include -#flag -I @VROOT/thirdparty/picoev -#flag -L @VROOT/thirdparty/picoev -#flag @VROOT/thirdparty/picoev/picoev.o +#flag -I @VEXEROOT/thirdparty/picoev +#flag -L @VEXEROOT/thirdparty/picoev +#flag @VEXEROOT/thirdparty/picoev/picoev.o #include "src/picoev.h" const ( max_fds = 1024 diff --git a/vlib/picohttpparser/picohttpparser.v b/vlib/picohttpparser/picohttpparser.v index 9b2680e840..85db6551f7 100644 --- a/vlib/picohttpparser/picohttpparser.v +++ b/vlib/picohttpparser/picohttpparser.v @@ -3,9 +3,9 @@ // that can be found in the LICENSE file. module picohttpparser -#flag -I @VROOT/thirdparty/picohttpparser -#flag -L @VROOT/thirdparty/picohttpparser -#flag @VROOT/thirdparty/picohttpparser/picohttpparser.o +#flag -I @VEXEROOT/thirdparty/picohttpparser +#flag -L @VEXEROOT/thirdparty/picohttpparser +#flag @VEXEROOT/thirdparty/picohttpparser/picohttpparser.o #include "picohttpparser.h" diff --git a/vlib/sokol/audio/audio.v b/vlib/sokol/audio/audio.v index 27a64ac08c..f3f11e61bf 100644 --- a/vlib/sokol/audio/audio.v +++ b/vlib/sokol/audio/audio.v @@ -1,6 +1,6 @@ module audio -#flag -I @VROOT/thirdparty/sokol +#flag -I @VEXEROOT/thirdparty/sokol #define SOKOL_IMPL #include "sokol_audio.h" #flag linux -lasound diff --git a/vlib/sokol/c/declaration.c.v b/vlib/sokol/c/declaration.c.v index d9f8bef683..c1ee5b7782 100644 --- a/vlib/sokol/c/declaration.c.v +++ b/vlib/sokol/c/declaration.c.v @@ -4,8 +4,8 @@ pub const ( used_import = 1 ) -#flag -I @VROOT/thirdparty/sokol -#flag -I @VROOT/thirdparty/sokol/util +#flag -I @VEXEROOT/thirdparty/sokol +#flag -I @VEXEROOT/thirdparty/sokol/util #flag freebsd -I /usr/local/include #flag darwin -fobjc-arc #flag linux -lX11 -lGL -lXcursor -lXi diff --git a/vlib/sqlite/sqlite.v b/vlib/sqlite/sqlite.v index ca4bcaee93..f28b3d7118 100644 --- a/vlib/sqlite/sqlite.v +++ b/vlib/sqlite/sqlite.v @@ -5,11 +5,11 @@ module sqlite #flag solaris -lsqlite3 #flag freebsd -I/usr/local/include #flag freebsd -Wl -L/usr/local/lib -lsqlite3 -#flag windows -I@VROOT/thirdparty/sqlite -#flag windows -L@VROOT/thirdparty/sqlite -#flag windows @VROOT/thirdparty/sqlite/sqlite3.o -// #flag linux -I @VROOT/thirdparty/sqlite -// #flag @VROOT/thirdparty/sqlite/sqlite.c +#flag windows -I@VEXEROOT/thirdparty/sqlite +#flag windows -L@VEXEROOT/thirdparty/sqlite +#flag windows @VEXEROOT/thirdparty/sqlite/sqlite3.o +// #flag linux -I @VEXEROOT/thirdparty/sqlite +// #flag @VEXEROOT/thirdparty/sqlite/sqlite.c #include "sqlite3.h" // struct C.sqlite3 { diff --git a/vlib/stbi/stbi.v b/vlib/stbi/stbi.v index 7375a50582..a8d5139a4e 100644 --- a/vlib/stbi/stbi.v +++ b/vlib/stbi/stbi.v @@ -4,9 +4,9 @@ module stbi -#flag -I @VROOT/thirdparty/stb_image +#flag -I @VEXEROOT/thirdparty/stb_image #include "stb_image.h" -#flag @VROOT/thirdparty/stb_image/stbi.o +#flag @VEXEROOT/thirdparty/stb_image/stbi.o pub struct Image { pub mut: diff --git a/vlib/sync/atomic2/atomic.v b/vlib/sync/atomic2/atomic.v index 8831b93d9b..7b5d3f0379 100644 --- a/vlib/sync/atomic2/atomic.v +++ b/vlib/sync/atomic2/atomic.v @@ -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. 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++. This implementations should be regarded as alpha stage and be further tested. */ -#flag windows -I @VROOT/thirdparty/stdatomic/win -#flag linux -I @VROOT/thirdparty/stdatomic/nix -#flag darwin -I @VROOT/thirdparty/stdatomic/nix -#flag freebsd -I @VROOT/thirdparty/stdatomic/nix -#flag solaris -I @VROOT/thirdparty/stdatomic/nix +#flag windows -I @VEXEROOT/thirdparty/stdatomic/win +#flag linux -I @VEXEROOT/thirdparty/stdatomic/nix +#flag darwin -I @VEXEROOT/thirdparty/stdatomic/nix +#flag freebsd -I @VEXEROOT/thirdparty/stdatomic/nix +#flag solaris -I @VEXEROOT/thirdparty/stdatomic/nix $if linux { $if tinyc { // most Linux distributions have /usr/lib/libatomic.so, but Ubuntu uses gcc version specific dir diff --git a/vlib/sync/channels.v b/vlib/sync/channels.v index f7c7187c0a..574a11e1e1 100644 --- a/vlib/sync/channels.v +++ b/vlib/sync/channels.v @@ -3,11 +3,10 @@ module sync import time import rand - $if windows { - #flag -I @VROOT/thirdparty/stdatomic/win + #flag -I @VEXEROOT/thirdparty/stdatomic/win } $else { - #flag -I @VROOT/thirdparty/stdatomic/nix + #flag -I @VEXEROOT/thirdparty/stdatomic/nix } $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 { 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 for { 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 { - 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 write_in_progress := false for { diff --git a/vlib/szip/szip.v b/vlib/szip/szip.v index ae732d715f..4929aa23b0 100644 --- a/vlib/szip/szip.v +++ b/vlib/szip/szip.v @@ -2,7 +2,7 @@ module szip import os -#flag -I @VROOT/thirdparty/zip +#flag -I @VEXEROOT/thirdparty/zip #include "zip.c" #include "zip.h" diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index e6fa08f4d8..a064919618 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -18,16 +18,16 @@ const int_min = int(0x80000000) const int_max = int(0x7FFFFFFF) const ( - valid_comp_if_os = ['windows', 'ios', 'macos', 'mach', 'darwin', 'hpux', 'gnu', 'qnx', - 'linux', 'freebsd', 'openbsd', 'netbsd', 'bsd', 'dragonfly', 'android', 'solaris', 'haiku', - 'linux_or_macos', - ] - 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_other = ['js', 'debug', 'prod', 'test', 'glibc', 'prealloc', + valid_comp_if_os = ['windows', 'ios', 'macos', 'mach', 'darwin', 'hpux', 'gnu', + 'qnx', 'linux', 'freebsd', 'openbsd', 'netbsd', 'bsd', 'dragonfly', 'android', 'solaris', + 'haiku', 'linux_or_macos'] + 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_other = ['js', 'debug', 'prod', 'test', 'glibc', 'prealloc', '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'] + vroot_is_deprecated_message = '@VROOT is deprecated, use @VMODROOT or @VEXEROOT instead' ) 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) { - c.file = ast_file + c.change_current_file(ast_file) for i, ast_import in ast_file.imports { for j in 0 .. i { 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 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 { c.stmt(stmt) } 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) { // c.files = ast_files 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') last_file := c.file - last_mod := c.mod // post process generic functions. must be done after all files have been // checked, to eunsure all generic calls are processed as this information // is needed when the generic type is auto inferred from the call argument for i in 0 .. ast_files.len { file := unsafe { &ast_files[i] } if file.generic_fns.len > 0 { - c.file = file - c.mod = file.mod.name + c.change_current_file(file) c.post_process_generic_fns() } } // restore the original c.file && c.mod after post processing - c.file = last_file - c.mod = last_mod + c.change_current_file(last_file) c.timers.show('checker_post_process_generic_fns') // c.timers.start('checker_verify_all_vweb_routes') @@ -3968,7 +3971,23 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) { 'include' { mut flag := node.main 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) return } @@ -4012,9 +4031,19 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) { 'flag' { // #flag linux -lm mut flag := node.main - // expand `@VROOT` to its absolute path 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) return } @@ -4027,7 +4056,10 @@ fn (mut c Checker) hash_stmt(mut node ast.HashStmt) { } for deprecated in ['@VMOD', '@VMODULE', '@VPATH', '@VLIB_PATH'] { 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"') @@ -4644,6 +4676,7 @@ fn (mut c Checker) at_expr(mut node ast.AtExpr) ast.Type { node.val = util.vhash() } .vmod_file { + // cache the vmod content, do not read it many times if c.vmod_file_content.len == 0 { mut mcache := vmod.get_cache() 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) } vmod_content := os.read_file(vmod_file_location.vmod_file) or { '' } - $if windows { - c.vmod_file_content = vmod_content.replace('\r\n', '\n') - } $else { - c.vmod_file_content = vmod_content - } + c.vmod_file_content = vmod_content.replace('\r\n', '\n') // normalise EOLs just in case } 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 { c.error('unknown @ identifier: ${node.name}. Available identifiers: $token.valid_at_tokens', node.pos) @@ -6594,6 +6634,7 @@ fn (mut c Checker) verify_all_vweb_routes() { return } typ_vweb_result := c.table.find_type_idx('vweb.Result') + old_file := c.file for vgt in c.vweb_gen_types { sym_app := c.table.get_type_symbol(vgt) 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 && 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)', 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) { diff --git a/vlib/v/parser/comptime.v b/vlib/v/parser/comptime.v index b839d7864f..d4a3454f4a 100644 --- a/vlib/v/parser/comptime.v +++ b/vlib/v/parser/comptime.v @@ -279,12 +279,15 @@ fn (mut p Parser) at() ast.AtExpr { '@METHOD' { token.AtKind.method_name } '@MOD' { token.AtKind.mod_name } '@STRUCT' { token.AtKind.struct_name } - '@VEXE' { token.AtKind.vexe_path } '@FILE' { token.AtKind.file_path } '@LINE' { token.AtKind.line_nr } '@COLUMN' { token.AtKind.column_nr } '@VHASH' { token.AtKind.vhash } '@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 } } p.next() diff --git a/vlib/v/tests/cflags/includes/myinclude.h b/vlib/v/tests/cflags/includes/myinclude.h new file mode 100644 index 0000000000..1d0a601b9b --- /dev/null +++ b/vlib/v/tests/cflags/includes/myinclude.h @@ -0,0 +1,4 @@ + +int add(int a, int b) { + return a + b; +} diff --git a/vlib/v/tests/cflags/v.mod b/vlib/v/tests/cflags/v.mod new file mode 100644 index 0000000000..099e6fa74a --- /dev/null +++ b/vlib/v/tests/cflags/v.mod @@ -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. diff --git a/vlib/v/tests/cflags/vmodroot_and_vroot_test.v b/vlib/v/tests/cflags/vmodroot_and_vroot_test.v new file mode 100644 index 0000000000..182568abf3 --- /dev/null +++ b/vlib/v/tests/cflags/vmodroot_and_vroot_test.v @@ -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 +} diff --git a/vlib/v/tests/keep_args_alive_test.v b/vlib/v/tests/keep_args_alive_test.v index bd1b4ea84a..ace0809392 100644 --- a/vlib/v/tests/keep_args_alive_test.v +++ b/vlib/v/tests/keep_args_alive_test.v @@ -9,7 +9,7 @@ import rand import sync -#flag -I@VROOT/vlib/v/tests +#flag -I@VEXEROOT/vlib/v/tests #include "keep_args_alive_test_c.h" fn C.atomic_load_ptr(voidptr) voidptr diff --git a/vlib/v/tests/printing_c_structs/string_interpolation_test.v b/vlib/v/tests/printing_c_structs/string_interpolation_test.v index 9b6a63eb06..2ea40d63d7 100644 --- a/vlib/v/tests/printing_c_structs/string_interpolation_test.v +++ b/vlib/v/tests/printing_c_structs/string_interpolation_test.v @@ -1,4 +1,4 @@ -#include "@VROOT/cstruct.h" +#include "@VMODROOT/cstruct.h" const the_string = 'the string' diff --git a/vlib/v/tests/project_with_c_code/mod1/wrapper.v b/vlib/v/tests/project_with_c_code/mod1/wrapper.v index 16a04a52a5..f02233fcf0 100644 --- a/vlib/v/tests/project_with_c_code/mod1/wrapper.v +++ b/vlib/v/tests/project_with_c_code/mod1/wrapper.v @@ -1,7 +1,7 @@ module mod1 -#flag -I @VROOT/c -#flag @VROOT/c/implementation.o +#flag -I @VMODROOT/c +#flag @VMODROOT/c/implementation.o #include "header.h" diff --git a/vlib/v/tests/project_with_c_code_2/modc/wrapper.v b/vlib/v/tests/project_with_c_code_2/modc/wrapper.v index 1bdaf8cd95..9ad8dfb3d3 100644 --- a/vlib/v/tests/project_with_c_code_2/modc/wrapper.v +++ b/vlib/v/tests/project_with_c_code_2/modc/wrapper.v @@ -1,7 +1,7 @@ module modc -#flag -I @VROOT -#flag @VROOT/impl.o +#flag -I @VMODROOT +#flag @VMODROOT/impl.o #include "header.h" struct C.Atype { diff --git a/vlib/v/token/token.v b/vlib/v/token/token.v index 7fe27912d1..b72427bec1 100644 --- a/vlib/v/token/token.v +++ b/vlib/v/token/token.v @@ -141,17 +141,24 @@ const ( // @METHOD => will be substituted with ReceiverType.MethodName // @MOD => will be substituted with the name of the current V module // @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 // @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). // @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). -// This allows things like this: -// println( 'file: ' + @FILE + ' | line: ' + @LINE + ' | fn: ' + @MOD + '.' + @FN) -// ... which is useful while debugging/tracing +// @VMODROOT => will be substituted with the *folder* where the nearest v.mod file is (as a string). +// @VEXE => will be substituted with the path to the V compiler +// @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 ...' // @ is allowed for keyword variable names. E.g. 'type' pub enum AtKind { unknown @@ -165,11 +172,14 @@ pub enum AtKind { column_nr vhash vmod_file + vmodroot_path + vroot_path // obsolete + vexeroot_path } pub const ( - valid_at_tokens = ['@FN', '@METHOD', '@MOD', '@STRUCT', '@VEXE', '@FILE', '@LINE', '@COLUMN', - '@VHASH', '@VMOD_FILE'] + valid_at_tokens = ['@VROOT', '@VMODROOT', '@VEXEROOT', '@FN', '@METHOD', '@MOD', '@STRUCT', + '@VEXE', '@FILE', '@LINE', '@COLUMN', '@VHASH', '@VMOD_FILE'] ) // build_keys genereates a map with keywords' string values: diff --git a/vlib/v/util/util.v b/vlib/v/util/util.v index c4b2884f9d..2034784a20 100644 --- a/vlib/v/util/util.v +++ b/vlib/v/util/util.v @@ -134,15 +134,15 @@ pub fn set_vroot_folder(vroot_path string) { 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() vmod_file_location := mcache.get_by_folder(dir) if vmod_file_location.vmod_file.len == 0 { // 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 - 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')`