aboutsummaryrefslogtreecommitdiff
path: root/v_windows/v/old/vlib/v/pref
diff options
context:
space:
mode:
Diffstat (limited to 'v_windows/v/old/vlib/v/pref')
-rw-r--r--v_windows/v/old/vlib/v/pref/default.v206
-rw-r--r--v_windows/v/old/vlib/v/pref/os.v116
-rw-r--r--v_windows/v/old/vlib/v/pref/pref.v828
-rw-r--r--v_windows/v/old/vlib/v/pref/should_compile.v217
4 files changed, 1367 insertions, 0 deletions
diff --git a/v_windows/v/old/vlib/v/pref/default.v b/v_windows/v/old/vlib/v/pref/default.v
new file mode 100644
index 0000000..2862c57
--- /dev/null
+++ b/v_windows/v/old/vlib/v/pref/default.v
@@ -0,0 +1,206 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license
+// that can be found in the LICENSE file.
+module pref
+
+import os
+import v.vcache
+
+pub const (
+ default_module_path = os.vmodules_dir()
+)
+
+pub fn new_preferences() &Preferences {
+ mut p := &Preferences{}
+ p.fill_with_defaults()
+ return p
+}
+
+fn (mut p Preferences) expand_lookup_paths() {
+ if p.vroot == '' {
+ // Location of all vlib files
+ p.vroot = os.dir(vexe_path())
+ }
+ vlib_path := os.join_path(p.vroot, 'vlib')
+ if p.lookup_path.len == 0 {
+ p.lookup_path = ['@vlib', '@vmodules']
+ }
+ mut expanded_paths := []string{}
+ for path in p.lookup_path {
+ match path {
+ '@vlib' { expanded_paths << vlib_path }
+ '@vmodules' { expanded_paths << os.vmodules_paths() }
+ else { expanded_paths << path }
+ }
+ }
+ p.lookup_path = expanded_paths
+}
+
+pub fn (mut p Preferences) fill_with_defaults() {
+ if p.arch == ._auto {
+ p.arch = get_host_arch()
+ }
+ p.expand_lookup_paths()
+ rpath := os.real_path(p.path)
+ if p.out_name == '' {
+ filename := os.file_name(rpath).trim_space()
+ mut base := filename.all_before_last('.')
+ if base == '' {
+ // The file name is just `.v` or `.vsh` or `.*`
+ base = filename
+ }
+ target_dir := if os.is_dir(rpath) { rpath } else { os.dir(rpath) }
+ p.out_name = os.join_path(target_dir, base)
+ // Do *NOT* be tempted to generate binaries in the current work folder,
+ // when -o is not given by default, like Go, Clang, GCC etc do.
+ //
+ // These compilers also are frequently used with an external build system,
+ // in part because of that shortcoming, to ensure that they work in a
+ // predictable work folder/environment.
+ //
+ // In comparison, with V, building an executable by default places it
+ // next to its source code, so that it can be used directly with
+ // functions like `os.resource_abs_path()` and `os.executable()` to
+ // locate resources relative to it. That enables running examples like
+ // this:
+ // `./v run examples/flappylearning/`
+ // instead of:
+ // `./v -o examples/flappylearning/flappylearning run examples/flappylearning/`
+ // This topic comes up periodically from time to time on Discord, and
+ // many CI breakages already happened, when someone decides to make V
+ // behave in this aspect similarly to the dumb behaviour of other
+ // compilers.
+ //
+ // If you do decide to break it, please *at the very least*, test it
+ // extensively, and make a PR about it, instead of commiting directly
+ // and breaking the CI, VC, and users doing `v up`.
+ if rpath == '$p.vroot/cmd/v' && os.is_dir('vlib/compiler') {
+ // Building V? Use v2, since we can't overwrite a running
+ // executable on Windows + the precompiled V is more
+ // optimized.
+ println('Saving the resulting V executable in `./v2`')
+ println('Use `v -o v cmd/v` if you want to replace current ' + 'V executable.')
+ p.out_name = 'v2'
+ }
+ }
+ rpath_name := os.file_name(rpath)
+ p.building_v = !p.is_repl && (rpath_name == 'v' || rpath_name == 'vfmt.v')
+ if p.os == ._auto {
+ // No OS specifed? Use current system
+ p.os = get_host_os()
+ }
+ //
+ p.try_to_use_tcc_by_default()
+ if p.ccompiler == '' {
+ p.ccompiler = default_c_compiler()
+ }
+ p.find_cc_if_cross_compiling()
+ p.ccompiler_type = cc_from_string(p.ccompiler)
+ p.is_test = p.path.ends_with('_test.v') || p.path.ends_with('_test.vv')
+ || p.path.all_before_last('.v').all_before_last('.').ends_with('_test')
+ p.is_vsh = p.path.ends_with('.vsh')
+ p.is_script = p.is_vsh || p.path.ends_with('.v') || p.path.ends_with('.vv')
+ if p.third_party_option == '' {
+ p.third_party_option = p.cflags
+ $if !windows {
+ if !p.third_party_option.contains('-fPIC') {
+ p.third_party_option += ' -fPIC'
+ }
+ }
+ }
+ // Prepare the cache manager. All options that can affect the generated cached .c files
+ // should go into res.cache_manager.vopts, which is used as a salt for the cache hash.
+ p.cache_manager = vcache.new_cache_manager([
+ @VHASH,
+ // ensure that different v versions use separate build artefacts
+ '$p.backend | $p.os | $p.ccompiler | $p.is_prod | $p.sanitize',
+ p.cflags.trim_space(),
+ p.third_party_option.trim_space(),
+ '$p.compile_defines_all',
+ '$p.compile_defines',
+ '$p.lookup_path',
+ ])
+ // eprintln('prefs.cache_manager: $p')
+ // disable use_cache for specific cases:
+ if os.user_os() == 'windows' {
+ p.use_cache = false
+ }
+ if p.build_mode == .build_module {
+ // eprintln('-usecache and build-module flags are not compatible')
+ p.use_cache = false
+ }
+ if p.is_shared {
+ // eprintln('-usecache and -shared flags are not compatible')
+ p.use_cache = false
+ }
+ if p.bare_builtin_dir == '' {
+ p.bare_builtin_dir = os.join_path(p.vroot, 'vlib', 'builtin', 'linux_bare')
+ }
+}
+
+fn (mut p Preferences) find_cc_if_cross_compiling() {
+ if p.os == .windows {
+ $if !windows {
+ // Cross compiling to Windows
+ p.ccompiler = 'x86_64-w64-mingw32-gcc'
+ }
+ }
+ if p.os == .linux {
+ $if !linux {
+ // Cross compiling to Linux
+ p.ccompiler = 'clang'
+ }
+ }
+}
+
+fn (mut p Preferences) try_to_use_tcc_by_default() {
+ if p.ccompiler == 'tcc' {
+ p.ccompiler = default_tcc_compiler()
+ return
+ }
+ if p.ccompiler == '' {
+ // tcc is known to fail several tests on macos, so do not
+ // try to use it by default, only when it is explicitly set
+ $if macos {
+ return
+ }
+ // use an optimizing compiler (i.e. gcc or clang) on -prod mode
+ if p.is_prod {
+ return
+ }
+ p.ccompiler = default_tcc_compiler()
+ return
+ }
+}
+
+pub fn default_tcc_compiler() string {
+ vexe := vexe_path()
+ vroot := os.dir(vexe)
+ vtccexe := os.join_path(vroot, 'thirdparty', 'tcc', 'tcc.exe')
+ if os.exists(vtccexe) {
+ return vtccexe
+ }
+ return ''
+}
+
+pub fn default_c_compiler() string {
+ // fast_clang := '/usr/local/Cellar/llvm/8.0.0/bin/clang'
+ // if os.exists(fast_clang) {
+ // return fast_clang
+ // }
+ // TODO fix $if after 'string'
+ $if windows {
+ return 'gcc'
+ }
+ return 'cc'
+}
+
+pub fn vexe_path() string {
+ vexe := os.getenv('VEXE')
+ if vexe != '' {
+ return vexe
+ }
+ real_vexe_path := os.real_path(os.executable())
+ os.setenv('VEXE', real_vexe_path, true)
+ return real_vexe_path
+}
diff --git a/v_windows/v/old/vlib/v/pref/os.v b/v_windows/v/old/vlib/v/pref/os.v
new file mode 100644
index 0000000..578b00d
--- /dev/null
+++ b/v_windows/v/old/vlib/v/pref/os.v
@@ -0,0 +1,116 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license
+// that can be found in the LICENSE file.
+module pref
+
+pub enum OS {
+ _auto // Reserved so .macos cannot be misunderstood as auto
+ ios
+ macos
+ linux
+ windows
+ freebsd
+ openbsd
+ netbsd
+ dragonfly
+ js_node
+ js_browser
+ js_freestanding
+ android
+ solaris
+ serenity
+ vinix
+ haiku
+ raw
+ all
+}
+
+// Helper function to convert string names to OS enum
+pub fn os_from_string(os_str string) ?OS {
+ match os_str {
+ 'linux' { return .linux }
+ 'windows' { return .windows }
+ 'ios' { return .ios }
+ 'macos' { return .macos }
+ 'freebsd' { return .freebsd }
+ 'openbsd' { return .openbsd }
+ 'netbsd' { return .netbsd }
+ 'dragonfly' { return .dragonfly }
+ 'js', 'js_node' { return .js_node }
+ 'js_freestanding' { return .js_freestanding }
+ 'js_browser' { return .js_browser }
+ 'solaris' { return .solaris }
+ 'serenity' { return .serenity }
+ 'vinix' { return .vinix }
+ 'android' { return .android }
+ 'haiku' { return .haiku }
+ 'raw' { return .raw }
+ 'nix' { return .linux }
+ '' { return ._auto }
+ else { return error('bad OS $os_str') }
+ }
+}
+
+pub fn (o OS) str() string {
+ match o {
+ ._auto { return 'RESERVED: AUTO' }
+ .ios { return 'iOS' }
+ .macos { return 'MacOS' }
+ .linux { return 'Linux' }
+ .windows { return 'Windows' }
+ .freebsd { return 'FreeBSD' }
+ .openbsd { return 'OpenBSD' }
+ .netbsd { return 'NetBSD' }
+ .dragonfly { return 'Dragonfly' }
+ .js_node { return 'NodeJS' }
+ .js_freestanding { return 'JavaScript' }
+ .js_browser { return 'JavaScript(Browser)' }
+ .android { return 'Android' }
+ .solaris { return 'Solaris' }
+ .serenity { return 'SerenityOS' }
+ .vinix { return 'Vinix' }
+ .haiku { return 'Haiku' }
+ .raw { return 'Raw' }
+ .all { return 'all' }
+ }
+}
+
+pub fn get_host_os() OS {
+ $if linux {
+ return .linux
+ }
+ $if ios {
+ return .ios
+ }
+ $if macos {
+ return .macos
+ }
+ $if windows {
+ return .windows
+ }
+ $if freebsd {
+ return .freebsd
+ }
+ $if openbsd {
+ return .openbsd
+ }
+ $if netbsd {
+ return .netbsd
+ }
+ $if dragonfly {
+ return .dragonfly
+ }
+ $if serenity {
+ return .serenity
+ }
+ $if vinix {
+ return .vinix
+ }
+ $if solaris {
+ return .solaris
+ }
+ $if haiku {
+ return .haiku
+ }
+ panic('unknown host OS')
+}
diff --git a/v_windows/v/old/vlib/v/pref/pref.v b/v_windows/v/old/vlib/v/pref/pref.v
new file mode 100644
index 0000000..8ca843a
--- /dev/null
+++ b/v_windows/v/old/vlib/v/pref/pref.v
@@ -0,0 +1,828 @@
+// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
+// Use of this source code is governed by an MIT license
+// that can be found in the LICENSE file.
+module pref
+
+// import v.ast // TODO this results in a compiler bug
+import os.cmdline
+import os
+import v.vcache
+import rand
+
+pub enum BuildMode {
+ // `v program.v'
+ // Build user code only, and add pre-compiled vlib (`cc program.o builtin.o os.o...`)
+ default_mode // `v -lib ~/v/os`
+ // build any module (generate os.o + os.vh)
+ build_module
+}
+
+pub enum AssertFailureMode {
+ default
+ aborts
+ backtraces
+}
+
+pub enum GarbageCollectionMode {
+ no_gc
+ boehm_full // full garbage collection mode
+ boehm_incr // incremental garbage colletion mode
+ boehm_full_opt // full garbage collection mode
+ boehm_incr_opt // incremental garbage colletion mode
+ boehm_leak // leak detection mode (makes `gc_check_leaks()` work)
+}
+
+pub enum OutputMode {
+ stdout
+ silent
+}
+
+pub enum ColorOutput {
+ auto
+ always
+ never
+}
+
+pub enum Backend {
+ c // The (default) C backend
+ js_node // The JavaScript NodeJS backend
+ js_browser // The JavaScript browser backend
+ js_freestanding // The JavaScript freestanding backend
+ native // The Native backend
+}
+
+pub fn (b Backend) is_js() bool {
+ match b {
+ .js_node, .js_browser, .js_freestanding {
+ return true
+ }
+ else {
+ return false
+ }
+ }
+}
+
+pub enum CompilerType {
+ gcc
+ tinyc
+ clang
+ mingw
+ msvc
+ cplusplus
+}
+
+pub enum Arch {
+ _auto
+ amd64 // aka x86_64
+ arm64 // 64-bit arm
+ arm32 // 32-bit arm
+ rv64 // 64-bit risc-v
+ rv32 // 32-bit risc-v
+ i386
+ _max
+}
+
+const (
+ list_of_flags_with_param = ['o', 'd', 'define', 'b', 'backend', 'cc', 'os', 'target-os', 'cf',
+ 'cflags', 'path', 'arch']
+)
+
+[heap]
+pub struct Preferences {
+pub mut:
+ os OS // the OS to compile for
+ backend Backend
+ build_mode BuildMode
+ arch Arch
+ output_mode OutputMode = .stdout
+ // verbosity VerboseLevel
+ is_verbose bool
+ // nofmt bool // disable vfmt
+ is_test bool // `v test string_test.v`
+ is_script bool // single file mode (`v program.v`), main function can be skipped
+ is_vsh bool // v script (`file.vsh`) file, the `os` module should be made global
+ is_livemain bool // main program that contains live/hot code
+ is_liveshared bool // a shared library, that will be used in a -live main program
+ is_shared bool // an ordinary shared library, -shared, no matter if it is live or not
+ is_prof bool // benchmark every function
+ profile_file string // the profile results will be stored inside profile_file
+ profile_no_inline bool // when true, [inline] functions would not be profiled
+ translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc
+ is_prod bool // use "-O2"
+ obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"
+ is_repl bool
+ is_run bool
+ is_debug bool // turned on by -g or -cg, it tells v to pass -g to the C backend compiler.
+ is_vlines bool // turned on by -g (it slows down .tmp.c generation slightly).
+ // NB: passing -cg instead of -g will set is_vlines to false and is_debug to true, thus making v generate cleaner C files,
+ // which are sometimes easier to debug / inspect manually than the .tmp.c files by plain -g (when/if v line number generation breaks).
+ sanitize bool // use Clang's new "-fsanitize" option
+ sourcemap bool // JS Backend: -sourcemap will create a source map - default false
+ sourcemap_inline bool = true // JS Backend: -sourcemap-inline will embed the source map in the generated JaaScript file - currently default true only implemented
+ sourcemap_src_included bool // JS Backend: -sourcemap-src-included includes V source code in source map - default false
+ show_cc bool // -showcc, print cc command
+ show_c_output bool // -show-c-output, print all cc output even if the code was compiled correctly
+ show_callgraph bool // -show-callgraph, print the program callgraph, in a Graphviz DOT format to stdout
+ show_depgraph bool // -show-depgraph, print the program module dependency graph, in a Graphviz DOT format to stdout
+ dump_c_flags string // `-dump-c-flags file.txt` - let V store all C flags, passed to the backend C compiler in `file.txt`, one C flag/value per line.
+ use_cache bool // when set, use cached modules to speed up subsequent compilations, at the cost of slower initial ones (while the modules are cached)
+ retry_compilation bool = true // retry the compilation with another C compiler, if tcc fails.
+ is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run
+ // TODO Convert this into a []string
+ cflags string // Additional options which will be passed to the C compiler.
+ // For example, passing -cflags -Os will cause the C compiler to optimize the generated binaries for size.
+ // You could pass several -cflags XXX arguments. They will be merged with each other.
+ // You can also quote several options at the same time: -cflags '-Os -fno-inline-small-functions'.
+ m64 bool // true = generate 64-bit code, defaults to x64
+ ccompiler string // the name of the C compiler used
+ ccompiler_type CompilerType // the type of the C compiler used
+ third_party_option string
+ building_v bool
+ autofree bool // `v -manualfree` => false, `v -autofree` => true; false by default for now.
+ // Disabling `free()` insertion results in better performance in some applications (e.g. compilers)
+ compress bool // when set, use `upx` to compress the generated executable
+ // skip_builtin bool // Skips re-compilation of the builtin module
+ // to increase compilation time.
+ // This is on by default, since a vast majority of users do not
+ // work on the builtin module itself.
+ // generating_vh bool
+ enable_globals bool // allow __global for low level code
+ is_fmt bool
+ is_vet bool
+ is_bare bool
+ no_preludes bool // Prevents V from generating preludes in resulting .c files
+ custom_prelude string // Contents of custom V prelude that will be prepended before code in resulting .c files
+ lookup_path []string
+ bare_builtin_dir string // Path to implementation of malloc, memset, etc. Only used if is_bare is true
+ output_cross_c bool // true, when the user passed `-os cross`
+ prealloc bool
+ vroot string
+ out_name_c string // full os.real_path to the generated .tmp.c file; set by builder.
+ out_name string
+ path string // Path to file/folder to compile
+ // -d vfmt and -d another=0 for `$if vfmt { will execute }` and `$if another ? { will NOT get here }`
+ compile_defines []string // just ['vfmt']
+ compile_defines_all []string // contains both: ['vfmt','another']
+ run_args []string // `v run x.v 1 2 3` => `1 2 3`
+ printfn_list []string // a list of generated function names, whose source should be shown, for debugging
+ print_v_files bool // when true, just print the list of all parsed .v files then stop.
+ skip_running bool // when true, do no try to run the produced file (set by b.cc(), when -o x.c or -o x.js)
+ skip_warnings bool // like C's "-w", forces warnings to be ignored.
+ warn_impure_v bool // -Wimpure-v, force a warning for JS.fn()/C.fn(), outside of .js.v/.c.v files. TODO: turn to an error by default
+ warns_are_errors bool // -W, like C's "-Werror", treat *every* warning is an error
+ fatal_errors bool // unconditionally exit after the first error with exit(1)
+ reuse_tmpc bool // do not use random names for .tmp.c and .tmp.c.rsp files, and do not remove them
+ use_color ColorOutput // whether the warnings/errors should use ANSI color escapes.
+ is_parallel bool
+ error_limit int
+ is_vweb bool // skip _ var warning in templates
+ only_check_syntax bool // when true, just parse the files, then stop, before running checker
+ experimental bool // enable experimental features
+ skip_unused bool // skip generating C code for functions, that are not used
+ show_timings bool // show how much time each compiler stage took
+ is_ios_simulator bool
+ is_apk bool // build as Android .apk format
+ cleanup_files []string // list of temporary *.tmp.c and *.tmp.c.rsp files. Cleaned up on successfull builds.
+ build_options []string // list of options, that should be passed down to `build-module`, if needed for -usecache
+ cache_manager vcache.CacheManager
+ is_help bool // -h, -help or --help was passed
+ gc_mode GarbageCollectionMode = .no_gc // .no_gc, .boehm, .boehm_leak, ...
+ is_cstrict bool // turn on more C warnings; slightly slower
+ assert_failure_mode AssertFailureMode // whether to call abort() or print_backtrace() after an assertion failure
+ // checker settings:
+ checker_match_exhaustive_cutoff_limit int = 12
+}
+
+pub fn parse_args(known_external_commands []string, args []string) (&Preferences, string) {
+ mut res := &Preferences{}
+ $if x64 {
+ res.m64 = true // follow V model by default
+ }
+ mut command := ''
+ mut command_pos := 0
+ // for i, arg in args {
+ for i := 0; i < args.len; i++ {
+ arg := args[i]
+ current_args := args[i..].clone()
+ match arg {
+ '-apk' {
+ res.is_apk = true
+ res.build_options << arg
+ }
+ '-arch' {
+ target_arch := cmdline.option(current_args, '-arch', '')
+ i++
+ target_arch_kind := arch_from_string(target_arch) or {
+ eprintln('unknown architecture target `$target_arch`')
+ exit(1)
+ }
+ res.arch = target_arch_kind
+ res.build_options << '$arg $target_arch'
+ }
+ '-assert' {
+ assert_mode := cmdline.option(current_args, '-assert', '')
+ match assert_mode {
+ 'aborts' {
+ res.assert_failure_mode = .aborts
+ }
+ 'backtraces' {
+ res.assert_failure_mode = .backtraces
+ }
+ else {
+ eprintln('unknown assert mode `-gc $assert_mode`, supported modes are:`')
+ eprintln(' `-assert aborts` .... calls abort() after assertion failure')
+ eprintln(' `-assert backtraces` .... calls print_backtrace() after assertion failure')
+ exit(1)
+ }
+ }
+ i++
+ }
+ '-show-timings' {
+ res.show_timings = true
+ }
+ '-check-syntax' {
+ res.only_check_syntax = true
+ }
+ '-h', '-help', '--help' {
+ // NB: help is *very important*, just respond to all variations:
+ res.is_help = true
+ }
+ '-v' {
+ // `-v` flag is for setting verbosity, but without any args it prints the version, like Clang
+ if args.len > 1 {
+ res.is_verbose = true
+ } else {
+ command = 'version'
+ command_pos = i
+ }
+ }
+ '-progress' {
+ // processed by testing tools in cmd/tools/modules/testing/common.v
+ }
+ '-Wimpure-v' {
+ res.warn_impure_v = true
+ }
+ '-Wfatal-errors' {
+ res.fatal_errors = true
+ }
+ '-silent' {
+ res.output_mode = .silent
+ }
+ '-cstrict' {
+ res.is_cstrict = true
+ }
+ '-gc' {
+ gc_mode := cmdline.option(current_args, '-gc', '')
+ match gc_mode {
+ '', 'none' {
+ res.gc_mode = .no_gc
+ }
+ 'boehm_full' {
+ res.gc_mode = .boehm_full
+ parse_define(mut res, 'gcboehm')
+ parse_define(mut res, 'gcboehm_full')
+ }
+ 'boehm_incr' {
+ res.gc_mode = .boehm_incr
+ parse_define(mut res, 'gcboehm')
+ parse_define(mut res, 'gcboehm_incr')
+ }
+ 'boehm_full_opt' {
+ res.gc_mode = .boehm_full_opt
+ parse_define(mut res, 'gcboehm')
+ parse_define(mut res, 'gcboehm_full')
+ parse_define(mut res, 'gcboehm_opt')
+ }
+ 'boehm_incr_opt' {
+ res.gc_mode = .boehm_incr_opt
+ parse_define(mut res, 'gcboehm')
+ parse_define(mut res, 'gcboehm_incr')
+ parse_define(mut res, 'gcboehm_opt')
+ }
+ 'boehm' {
+ res.gc_mode = .boehm_full_opt // default mode
+ parse_define(mut res, 'gcboehm')
+ parse_define(mut res, 'gcboehm_full')
+ parse_define(mut res, 'gcboehm_opt')
+ }
+ 'boehm_leak' {
+ res.gc_mode = .boehm_leak
+ parse_define(mut res, 'gcboehm')
+ parse_define(mut res, 'gcboehm_leak')
+ }
+ else {
+ eprintln('unknown garbage collection mode `-gc $gc_mode`, supported modes are:`')
+ eprintln(' `-gc boehm` ............ default GC-mode (currently `boehm_full_opt`)')
+ eprintln(' `-gc boehm_full` ....... classic full collection')
+ eprintln(' `-gc boehm_incr` ....... incremental collection')
+ eprintln(' `-gc boehm_full_opt` ... optimized classic full collection')
+ eprintln(' `-gc boehm_incr_opt` ... optimized incremental collection')
+ eprintln(' `-gc boehm_leak` ....... leak detection (for debugging)')
+ eprintln(' `-gc none` ............. no garbage collection')
+ exit(1)
+ }
+ }
+ i++
+ }
+ '-g' {
+ res.is_debug = true
+ res.is_vlines = true
+ res.build_options << arg
+ }
+ '-cg' {
+ res.is_debug = true
+ res.is_vlines = false
+ res.build_options << arg
+ }
+ '-debug-tcc' {
+ res.ccompiler = 'tcc'
+ res.build_options << '$arg "$res.ccompiler"'
+ res.retry_compilation = false
+ res.show_cc = true
+ res.show_c_output = true
+ }
+ '-sourcemap' {
+ res.sourcemap = true
+ }
+ '-sourcemap-src-included' {
+ res.sourcemap_src_included = true
+ }
+ '-sourcemap-inline' {
+ res.sourcemap_inline = true
+ }
+ '-repl' {
+ res.is_repl = true
+ }
+ '-live' {
+ res.is_livemain = true
+ }
+ '-sharedlive' {
+ res.is_liveshared = true
+ res.is_shared = true
+ }
+ '-shared' {
+ res.is_shared = true
+ }
+ '--enable-globals' {
+ eprintln('`--enable-globals` flag is deprecated, please use `-enable-globals` instead')
+ res.enable_globals = true
+ }
+ '-enable-globals' {
+ res.enable_globals = true
+ }
+ '-autofree' {
+ res.autofree = true
+ res.build_options << arg
+ }
+ '-manualfree' {
+ res.autofree = false
+ res.build_options << arg
+ }
+ '-skip-unused' {
+ res.skip_unused = true
+ }
+ '-compress' {
+ res.compress = true
+ }
+ '-freestanding' {
+ res.is_bare = true
+ res.build_options << arg
+ }
+ '-no-retry-compilation' {
+ res.retry_compilation = false
+ }
+ '-no-preludes' {
+ res.no_preludes = true
+ res.build_options << arg
+ }
+ '-prof', '-profile' {
+ res.profile_file = cmdline.option(current_args, arg, '-')
+ res.is_prof = true
+ res.build_options << '$arg $res.profile_file'
+ i++
+ }
+ '-profile-no-inline' {
+ res.profile_no_inline = true
+ }
+ '-prod' {
+ res.is_prod = true
+ res.build_options << arg
+ }
+ '-sanitize' {
+ res.sanitize = true
+ res.build_options << arg
+ }
+ '-simulator' {
+ res.is_ios_simulator = true
+ }
+ '-stats' {
+ res.is_stats = true
+ }
+ '-obf', '-obfuscate' {
+ res.obfuscate = true
+ }
+ '-translated' {
+ res.translated = true
+ }
+ '-m32', '-m64' {
+ res.m64 = arg[2] == `6`
+ res.cflags += ' $arg'
+ }
+ '-color' {
+ res.use_color = .always
+ }
+ '-nocolor' {
+ res.use_color = .never
+ }
+ '-showcc' {
+ res.show_cc = true
+ }
+ '-show-c-output' {
+ res.show_c_output = true
+ }
+ '-show-callgraph' {
+ res.show_callgraph = true
+ }
+ '-show-depgraph' {
+ res.show_depgraph = true
+ }
+ '-dump-c-flags' {
+ res.dump_c_flags = cmdline.option(current_args, arg, '-')
+ i++
+ }
+ '-experimental' {
+ res.experimental = true
+ }
+ '-usecache' {
+ res.use_cache = true
+ }
+ '-nocache' {
+ res.use_cache = false
+ }
+ '-prealloc' {
+ res.prealloc = true
+ res.build_options << arg
+ }
+ '-parallel' {
+ res.is_parallel = true
+ }
+ '-native' {
+ res.backend = .native
+ res.build_options << arg
+ }
+ '-W' {
+ res.warns_are_errors = true
+ }
+ '-keepc' {
+ res.reuse_tmpc = true
+ }
+ '-w' {
+ res.skip_warnings = true
+ }
+ '-watch' {
+ eprintln('The -watch option is deprecated. Please use the watch command `v watch file.v` instead.')
+ exit(1)
+ }
+ '-print-v-files' {
+ res.print_v_files = true
+ }
+ '-error-limit' {
+ res.error_limit = cmdline.option(current_args, '-error-limit', '0').int()
+ }
+ '-os' {
+ target_os := cmdline.option(current_args, '-os', '')
+ i++
+ target_os_kind := os_from_string(target_os) or {
+ if target_os == 'cross' {
+ res.output_cross_c = true
+ continue
+ }
+ eprintln('unknown operating system target `$target_os`')
+ exit(1)
+ }
+ res.os = target_os_kind
+ res.build_options << '$arg $target_os'
+ }
+ '-printfn' {
+ res.printfn_list << cmdline.option(current_args, '-printfn', '').split(',')
+ i++
+ }
+ '-cflags' {
+ res.cflags += ' ' + cmdline.option(current_args, '-cflags', '')
+ res.build_options << '$arg "$res.cflags.trim_space()"'
+ i++
+ }
+ '-d', '-define' {
+ if current_args.len > 1 {
+ define := current_args[1]
+ parse_define(mut res, define)
+ }
+ i++
+ }
+ '-cc' {
+ res.ccompiler = cmdline.option(current_args, '-cc', 'cc')
+ res.build_options << '$arg "$res.ccompiler"'
+ i++
+ }
+ '-checker-match-exhaustive-cutoff-limit' {
+ res.checker_match_exhaustive_cutoff_limit = cmdline.option(current_args,
+ arg, '10').int()
+ i++
+ }
+ '-o', '-output' {
+ res.out_name = cmdline.option(current_args, arg, '')
+ if res.out_name.ends_with('.js') {
+ res.backend = .js_node
+ }
+ if !os.is_abs_path(res.out_name) {
+ res.out_name = os.join_path(os.getwd(), res.out_name)
+ }
+ i++
+ }
+ '-b', '-backend' {
+ sbackend := cmdline.option(current_args, arg, 'c')
+ res.build_options << '$arg $sbackend'
+ b := backend_from_string(sbackend) or { continue }
+ if b.is_js() {
+ res.output_cross_c = true
+ }
+ res.backend = b
+ i++
+ }
+ '-path' {
+ path := cmdline.option(current_args, '-path', '')
+ res.build_options << '$arg "$path"'
+ res.lookup_path = path.replace('|', os.path_delimiter).split(os.path_delimiter)
+ i++
+ }
+ '-bare-builtin-dir' {
+ bare_builtin_dir := cmdline.option(current_args, arg, '')
+ res.build_options << '$arg "$bare_builtin_dir"'
+ res.bare_builtin_dir = bare_builtin_dir
+ i++
+ }
+ '-custom-prelude' {
+ path := cmdline.option(current_args, '-custom-prelude', '')
+ res.build_options << '$arg $path'
+ prelude := os.read_file(path) or {
+ eprintln('cannot open custom prelude file: $err')
+ exit(1)
+ }
+ res.custom_prelude = prelude
+ i++
+ }
+ else {
+ if command == 'build' && is_source_file(arg) {
+ eprintln('Use `v $arg` instead.')
+ exit(1)
+ }
+ if arg[0] == `-` {
+ if arg[1..] in pref.list_of_flags_with_param {
+ // skip parameter
+ i++
+ continue
+ }
+ } else {
+ if command == '' {
+ command = arg
+ command_pos = i
+ if command == 'run' {
+ break
+ }
+ } else if is_source_file(command) && is_source_file(arg)
+ && command !in known_external_commands {
+ eprintln('Too many targets. Specify just one target: <target.v|target_directory>.')
+ exit(1)
+ }
+ continue
+ }
+ if arg in ['-V', '-version', '--version'] {
+ command = 'version'
+ command_pos = i
+ continue
+ }
+ if command != '' && command != 'build-module' {
+ // arguments for e.g. fmt should be checked elsewhere
+ continue
+ }
+ extension := if command.len == 0 { '' } else { ' for command `$command`' }
+ eprintln('Unknown argument `$arg`$extension')
+ exit(1)
+ }
+ }
+ }
+ if res.is_debug {
+ parse_define(mut res, 'debug')
+ }
+
+ // res.use_cache = true
+ if command != 'doc' && res.out_name.ends_with('.v') {
+ eprintln('Cannot save output binary in a .v file.')
+ exit(1)
+ }
+ if command == 'run' {
+ res.is_run = true
+ if command_pos + 2 > args.len {
+ eprintln('v run: no v files listed')
+ exit(1)
+ }
+ res.path = args[command_pos + 1]
+ res.run_args = args[command_pos + 2..]
+ if res.path == '-' {
+ tmp_file_path := rand.ulid()
+ mut tmp_exe_file_path := res.out_name
+ mut output_option := ''
+ if tmp_exe_file_path == '' {
+ tmp_exe_file_path = '${tmp_file_path}.exe'
+ output_option = '-o "$tmp_exe_file_path"'
+ }
+ tmp_v_file_path := '${tmp_file_path}.v'
+ contents := os.get_raw_lines_joined()
+ os.write_file(tmp_v_file_path, contents) or {
+ panic('Failed to create temporary file $tmp_v_file_path')
+ }
+ run_options := cmdline.options_before(args, ['run']).join(' ')
+ command_options := cmdline.options_after(args, ['run'])[1..].join(' ')
+ vexe := vexe_path()
+ tmp_cmd := '"$vexe" $output_option $run_options run "$tmp_v_file_path" $command_options'
+ //
+ res.vrun_elog('tmp_cmd: $tmp_cmd')
+ tmp_result := os.system(tmp_cmd)
+ res.vrun_elog('exit code: $tmp_result')
+ //
+ if output_option.len != 0 {
+ res.vrun_elog('remove tmp exe file: $tmp_exe_file_path')
+ os.rm(tmp_exe_file_path) or {}
+ }
+ res.vrun_elog('remove tmp v file: $tmp_v_file_path')
+ os.rm(tmp_v_file_path) or { panic(err) }
+ exit(tmp_result)
+ }
+ must_exist(res.path)
+ if !res.path.ends_with('.v') && os.is_executable(res.path) && os.is_file(res.path)
+ && os.is_file(res.path + '.v') {
+ eprintln('It looks like you wanted to run "${res.path}.v", so we went ahead and did that since "$res.path" is an executable.')
+ res.path += '.v'
+ }
+ } else if is_source_file(command) {
+ res.path = command
+ }
+ if !res.is_bare && res.bare_builtin_dir != '' {
+ eprintln('`-bare-builtin-dir` must be used with `-freestanding`')
+ }
+ if command == 'build-module' {
+ res.build_mode = .build_module
+ if command_pos + 1 >= args.len {
+ eprintln('v build-module: no module specified')
+ exit(1)
+ }
+ res.path = args[command_pos + 1]
+ }
+ // keep only the unique res.build_options:
+ mut m := map[string]string{}
+ for x in res.build_options {
+ m[x] = ''
+ }
+ res.build_options = m.keys()
+ // eprintln('>> res.build_options: $res.build_options')
+ res.fill_with_defaults()
+ return res, command
+}
+
+pub fn (pref &Preferences) vrun_elog(s string) {
+ if pref.is_verbose {
+ eprintln('> v run -, $s')
+ }
+}
+
+pub fn (pref &Preferences) should_output_to_stdout() bool {
+ return pref.out_name.ends_with('/-') || pref.out_name.ends_with(r'\-')
+}
+
+pub fn arch_from_string(arch_str string) ?Arch {
+ match arch_str {
+ 'amd64', 'x86_64', 'x64', 'x86' { // amd64 recommended
+
+ return Arch.amd64
+ }
+ 'aarch64', 'arm64' { // arm64 recommended
+
+ return Arch.arm64
+ }
+ 'aarch32', 'arm32', 'arm' { // arm32 recommended
+
+ return Arch.arm32
+ }
+ 'rv64', 'riscv64', 'risc-v64', 'riscv', 'risc-v' { // rv64 recommended
+
+ return Arch.rv64
+ }
+ 'rv32', 'riscv32' { // rv32 recommended
+
+ return Arch.rv32
+ }
+ 'x86_32', 'x32', 'i386', 'IA-32', 'ia-32', 'ia32' { // i386 recommended
+
+ return Arch.i386
+ }
+ '' {
+ return ._auto
+ }
+ else {
+ return error('invalid arch: $arch_str')
+ }
+ }
+}
+
+fn must_exist(path string) {
+ if !os.exists(path) {
+ eprintln('v expects that `$path` exists, but it does not')
+ exit(1)
+ }
+}
+
+[inline]
+fn is_source_file(path string) bool {
+ return path.ends_with('.v') || os.exists(path)
+}
+
+pub fn backend_from_string(s string) ?Backend {
+ match s {
+ 'c' { return .c }
+ 'js' { return .js_node }
+ 'js_node' { return .js_node }
+ 'js_browser' { return .js_browser }
+ 'js_freestanding' { return .js_freestanding }
+ 'native' { return .native }
+ else { return error('Unknown backend type $s') }
+ }
+}
+
+// Helper function to convert string names to CC enum
+pub fn cc_from_string(cc_str string) CompilerType {
+ if cc_str.len == 0 {
+ return .gcc
+ }
+ // TODO
+ normalized_cc := cc_str.replace('\\', '/')
+ normalized_cc_array := normalized_cc.split('/')
+ last_elem := normalized_cc_array.last()
+ cc := last_elem.all_before('.')
+ if cc.contains('++') {
+ return .cplusplus
+ }
+ if cc.contains('tcc') || cc.contains('tinyc') {
+ return .tinyc
+ }
+ if cc.contains('clang') {
+ return .clang
+ }
+ if cc.contains('mingw') {
+ return .mingw
+ }
+ if cc.contains('msvc') {
+ return .msvc
+ }
+ return .gcc
+}
+
+pub fn get_host_arch() Arch {
+ // NB: we can not use `$if arch` here, because V skips cgen for the non
+ // current comptime branches by default, so there is a bootstrapping
+ // problem => the __V_architecture macro is used to resolve it.
+ // TODO: think about how to solve it for non C backends, perhaps we
+ // need a comptime `$if native {` too, and/or a mechanism to always
+ // generate all branches for specific functions?
+ if C.__V_architecture <= int(Arch._auto) || C.__V_architecture >= int(Arch._max) {
+ return Arch.amd64
+ }
+ return Arch(C.__V_architecture)
+}
+
+fn parse_define(mut prefs Preferences, define string) {
+ define_parts := define.split('=')
+ prefs.build_options << '-d $define'
+ if define_parts.len == 1 {
+ prefs.compile_defines << define
+ prefs.compile_defines_all << define
+ return
+ }
+ if define_parts.len == 2 {
+ prefs.compile_defines_all << define_parts[0]
+ match define_parts[1] {
+ '0' {}
+ '1' {
+ prefs.compile_defines << define_parts[0]
+ }
+ else {
+ println(
+ 'V error: Unknown define argument value `${define_parts[1]}` for ${define_parts[0]}.' +
+ ' Expected `0` or `1`.')
+ exit(1)
+ }
+ }
+ return
+ }
+ println('V error: Unknown define argument: ${define}. Expected at most one `=`.')
+ exit(1)
+}
diff --git a/v_windows/v/old/vlib/v/pref/should_compile.v b/v_windows/v/old/vlib/v/pref/should_compile.v
new file mode 100644
index 0000000..5f69fa4
--- /dev/null
+++ b/v_windows/v/old/vlib/v/pref/should_compile.v
@@ -0,0 +1,217 @@
+module pref
+
+import os
+
+pub fn (prefs &Preferences) should_compile_filtered_files(dir string, files_ []string) []string {
+ mut res := []string{}
+ mut files := files_.clone()
+ files.sort()
+ mut all_v_files := []string{}
+ for file in files {
+ if !file.ends_with('.v') && !file.ends_with('.vh') {
+ continue
+ }
+ if file.ends_with('_test.v')
+ || file.all_before_last('.v').all_before_last('.').ends_with('_test') {
+ continue
+ }
+ if prefs.backend == .c && !prefs.should_compile_c(file) {
+ continue
+ }
+ if prefs.backend.is_js() && !prefs.should_compile_js(file) {
+ continue
+ }
+ if prefs.backend == .native && !prefs.should_compile_native(file) {
+ continue
+ }
+ if !prefs.backend.is_js() && !prefs.should_compile_asm(file) {
+ continue
+ }
+ if file.starts_with('.#') {
+ continue
+ }
+ if file.contains('_d_') {
+ if prefs.compile_defines_all.len == 0 {
+ continue
+ }
+ mut allowed := false
+ for cdefine in prefs.compile_defines {
+ file_postfix := '_d_${cdefine}.v'
+ if file.ends_with(file_postfix) {
+ allowed = true
+ break
+ }
+ }
+ if !allowed {
+ continue
+ }
+ }
+ if file.contains('_notd_') {
+ mut allowed := true
+ for cdefine in prefs.compile_defines {
+ file_postfix := '_notd_${cdefine}.v'
+ if file.ends_with(file_postfix) {
+ allowed = false
+ break
+ }
+ }
+ if !allowed {
+ continue
+ }
+ }
+ all_v_files << os.join_path(dir, file)
+ }
+ //
+ mut defaults := []string{}
+ mut fnames_no_postfixes := map[string][]string{}
+ for file in all_v_files {
+ if file.contains('default.c.v') {
+ defaults << file
+ } else {
+ res << file
+ no_postfix_key := fname_without_platform_postfix(file)
+ mut candidates := fnames_no_postfixes[no_postfix_key]
+ candidates << file
+ fnames_no_postfixes[no_postfix_key] = candidates
+ }
+ }
+ for file in defaults {
+ no_postfix_key := fname_without_platform_postfix(file)
+ if no_postfix_key in fnames_no_postfixes {
+ if prefs.is_verbose {
+ println('>>> should_compile_filtered_files: skipping _default.c.v file $file ; the specialized versions are: ${fnames_no_postfixes[no_postfix_key]}')
+ }
+ continue
+ }
+ res << file
+ }
+ if prefs.is_verbose {
+ // println('>>> prefs: $prefs')
+ println('>>> should_compile_filtered_files: res: $res')
+ }
+ return res
+}
+
+fn fname_without_platform_postfix(file string) string {
+ res := file.replace_each([
+ 'default.c.v',
+ '_',
+ 'nix.c.v',
+ '_',
+ 'windows.c.v',
+ '_',
+ 'linux.c.v',
+ '_',
+ 'darwin.c.v',
+ '_',
+ 'macos.c.v',
+ '_',
+ 'android.c.v',
+ '_',
+ 'freebsd.c.v',
+ '_',
+ 'netbsd.c.v',
+ '_',
+ 'dragonfly.c.v',
+ '_',
+ 'solaris.c.v',
+ '_',
+ 'native.v',
+ '_',
+ ])
+ return res
+}
+
+pub fn (prefs &Preferences) should_compile_native(file string) bool {
+ // allow custom filtering for native backends,
+ // but if there are no other rules, default to the c backend rules
+ return prefs.should_compile_c(file)
+}
+
+pub fn (prefs &Preferences) should_compile_c(file string) bool {
+ if file.ends_with('.js.v') {
+ // Probably something like `a.js.v`.
+ return false
+ }
+ if prefs.is_bare && file.ends_with('.freestanding.v') {
+ return true
+ }
+ if prefs.os == .all {
+ return true
+ }
+ if prefs.backend != .native && file.ends_with('_native.v') {
+ return false
+ }
+ if prefs.os != .windows && (file.ends_with('_windows.c.v') || file.ends_with('_windows.v')) {
+ return false
+ }
+ if prefs.os != .linux && (file.ends_with('_linux.c.v') || file.ends_with('_linux.v')) {
+ return false
+ }
+ if prefs.os != .macos && (file.ends_with('_darwin.c.v') || file.ends_with('_darwin.v')) {
+ return false
+ }
+ if (file.ends_with('_ios.c.v') || file.ends_with('_ios.v')) && prefs.os != .ios {
+ return false
+ }
+ if file.ends_with('_nix.c.v') && prefs.os == .windows {
+ return false
+ }
+ if prefs.os != .macos && (file.ends_with('_macos.c.v') || file.ends_with('_macos.v')) {
+ return false
+ }
+ if prefs.os == .windows && file.ends_with('_nix.c.v') {
+ return false
+ }
+ if prefs.os != .android && file.ends_with('_android.c.v') {
+ return false
+ }
+ if prefs.os != .freebsd && file.ends_with('_freebsd.c.v') {
+ return false
+ }
+ if prefs.os != .openbsd && file.ends_with('_openbsd.c.v') {
+ return false
+ }
+ if prefs.os != .netbsd && file.ends_with('_netbsd.c.v') {
+ return false
+ }
+ if prefs.os != .dragonfly && file.ends_with('_dragonfly.c.v') {
+ return false
+ }
+ if prefs.os != .solaris && file.ends_with('_solaris.c.v') {
+ return false
+ }
+ if prefs.os != .serenity && file.ends_with('_serenity.c.v') {
+ return false
+ }
+ if prefs.os != .vinix && file.ends_with('_vinix.c.v') {
+ return false
+ }
+ return true
+}
+
+pub fn (prefs &Preferences) should_compile_asm(path string) bool {
+ if path.count('.') != 2 || path.ends_with('c.v') || path.ends_with('js.v') {
+ return true
+ }
+ file := path.all_before_last('.v')
+ arch := arch_from_string(file.all_after_last('.')) or { Arch._auto }
+
+ if arch != prefs.arch && prefs.arch != ._auto && arch != ._auto {
+ return false
+ }
+ os := os_from_string(file.all_after_last('_').all_before('.')) or { OS._auto }
+
+ if os != prefs.os && prefs.os != ._auto && os != ._auto {
+ return false
+ }
+ return true
+}
+
+pub fn (prefs &Preferences) should_compile_js(file string) bool {
+ if !file.ends_with('.js.v') && file.split('.').len > 2 {
+ // Probably something like `a.c.v`.
+ return false
+ }
+ return true
+}