mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
move v.v to cmd/v
This commit is contained in:
67
cmd/v/compile.v
Normal file
67
cmd/v/compile.v
Normal file
@@ -0,0 +1,67 @@
|
||||
// Copyright (c) 2019-2020 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 main
|
||||
|
||||
import (
|
||||
benchmark
|
||||
os
|
||||
os.cmdline
|
||||
)
|
||||
|
||||
fn compile(command string, args []string) {
|
||||
// Construct the V object from command line arguments
|
||||
mut v := new_v(args)
|
||||
if v.pref.is_verbose {
|
||||
println(args)
|
||||
}
|
||||
if command == 'run' {
|
||||
// always recompile for now, too error prone to skip recompilation otherwise
|
||||
// for example for -repl usage, especially when piping lines to v
|
||||
v.compile()
|
||||
run_compiled_executable_and_exit(v, args)
|
||||
}
|
||||
mut tmark := benchmark.new_benchmark()
|
||||
if v.pref.x64 {
|
||||
v.compile_x64()
|
||||
}
|
||||
else if v.pref.v2 {
|
||||
v.compile2()
|
||||
}
|
||||
else {
|
||||
v.compile()
|
||||
}
|
||||
if v.pref.is_stats {
|
||||
tmark.stop()
|
||||
println('compilation took: ' + tmark.total_duration().str() + 'ms')
|
||||
}
|
||||
if v.pref.is_test {
|
||||
run_compiled_executable_and_exit(v, args)
|
||||
}
|
||||
v.finalize_compilation()
|
||||
}
|
||||
|
||||
pub fn run_compiled_executable_and_exit(v &compiler.V, args []string) {
|
||||
if v.pref.is_verbose {
|
||||
println('============ running $v.pref.out_name ============')
|
||||
}
|
||||
mut cmd := '"${v.pref.out_name}"'
|
||||
args_after_no_options := cmdline.only_non_options( cmdline.after(args,['run','test']) )
|
||||
if args_after_no_options.len > 1 {
|
||||
cmd += ' ' + args_after_no_options[1..].join(' ')
|
||||
}
|
||||
if v.pref.is_test {
|
||||
ret := os.system(cmd)
|
||||
if ret != 0 {
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
if v.pref.is_run {
|
||||
ret := os.system(cmd)
|
||||
// TODO: make the runner wrapping as transparent as possible
|
||||
// (i.e. use execve when implemented). For now though, the runner
|
||||
// just returns the same exit code as the child process.
|
||||
exit(ret)
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
229
cmd/v/compile_options.v
Normal file
229
cmd/v/compile_options.v
Normal file
@@ -0,0 +1,229 @@
|
||||
// Copyright (c) 2019-2020 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 main
|
||||
|
||||
import (
|
||||
compiler
|
||||
filepath
|
||||
os
|
||||
os.cmdline
|
||||
v.pref
|
||||
)
|
||||
|
||||
//TODO Cleanup this file. This file ended up like a dump for functions that do not belong in `compiler`.
|
||||
//Maybe restructure the functions below into different V files
|
||||
|
||||
pub fn new_v(args []string) &compiler.V {
|
||||
// Create modules dirs if they are missing
|
||||
if !os.is_dir(compiler.v_modules_path) {
|
||||
os.mkdir(compiler.v_modules_path)or{
|
||||
panic(err)
|
||||
}
|
||||
os.mkdir('$compiler.v_modules_path${os.path_separator}cache')or{
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
vroot := filepath.dir(vexe_path())
|
||||
// optional, custom modules search path
|
||||
user_mod_path := cmdline.option(args, '-user_mod_path', '')
|
||||
vlib_path := cmdline.option(args, '-vlib-path', '')
|
||||
vpath := cmdline.option(args, '-vpath', '')
|
||||
target_os := cmdline.option(args, '-os', '')
|
||||
if target_os == 'msvc' {
|
||||
// notice that `-os msvc` became `-cc msvc`
|
||||
println('V error: use the flag `-cc msvc` to build using msvc')
|
||||
os.flush_stdout()
|
||||
exit(1)
|
||||
}
|
||||
mut out_name := cmdline.option(args, '-o', '')
|
||||
mut dir := args.last()
|
||||
if 'run' in args {
|
||||
args_after_run := cmdline.only_non_options( cmdline.after(args,['run']) )
|
||||
dir = if args_after_run.len>0 { args_after_run[0] } else { '' }
|
||||
}
|
||||
if dir == 'v.v' {
|
||||
println('looks like you are trying to build V with an old command')
|
||||
println('use `v -o v cmd/v` instead of `v -o v v.v`')
|
||||
exit(1)
|
||||
}
|
||||
if dir.ends_with(os.path_separator) {
|
||||
dir = dir.all_before_last(os.path_separator)
|
||||
}
|
||||
if dir.starts_with('.$os.path_separator') {
|
||||
dir = dir[2..]
|
||||
}
|
||||
if args.len < 2 {
|
||||
dir = ''
|
||||
}
|
||||
|
||||
// build mode
|
||||
mut build_mode := pref.BuildMode.default_mode
|
||||
mut mod := ''
|
||||
joined_args := args.join(' ')
|
||||
if joined_args.contains('build module ') {
|
||||
build_mode = .build_module
|
||||
os.chdir(vroot)
|
||||
// v build module ~/v/os => os.o
|
||||
mod_path := if dir.contains('vlib') { dir.all_after('vlib' + os.path_separator) } else if dir.starts_with('.\\') || dir.starts_with('./') { dir[2..] } else if dir.starts_with(os.path_separator) { dir.all_after(os.path_separator) } else { dir }
|
||||
mod = mod_path.replace(os.path_separator, '.')
|
||||
println('Building module "${mod}" (dir="$dir")...')
|
||||
// out_name = '$TmpPath/vlib/${base}.o'
|
||||
if !out_name.ends_with('.c') {
|
||||
out_name = mod
|
||||
}
|
||||
// Cross compiling? Use separate dirs for each os
|
||||
/*
|
||||
if target_os != os.user_os() {
|
||||
os.mkdir('$TmpPath/vlib/$target_os') or { panic(err) }
|
||||
out_name = '$TmpPath/vlib/$target_os/${base}.o'
|
||||
println('target_os=$target_os user_os=${os.user_os()}')
|
||||
println('!Cross compiling $out_name')
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
// `v -o dir/exec`, create "dir/" if it doesn't exist
|
||||
if out_name.contains(os.path_separator) {
|
||||
d := out_name.all_before_last(os.path_separator)
|
||||
if !os.is_dir(d) {
|
||||
println('creating a new directory "$d"')
|
||||
os.mkdir(d)or{
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// println('VROOT=$vroot')
|
||||
cflags := cmdline.many_values(args, '-cflags').join(' ')
|
||||
|
||||
defines := cmdline.many_values(args, '-d')
|
||||
compile_defines, compile_defines_all := parse_defines( defines )
|
||||
|
||||
rdir := os.realpath(dir)
|
||||
rdir_name := filepath.filename(rdir)
|
||||
if '-bare' in args {
|
||||
println('V error: use -freestanding instead of -bare')
|
||||
os.flush_stdout()
|
||||
exit(1)
|
||||
}
|
||||
is_repl := '-repl' in args
|
||||
ccompiler := cmdline.option(args, '-cc', '')
|
||||
mut pref := &pref.Preferences{
|
||||
os: pref.os_from_string(target_os)
|
||||
is_so: '-shared' in args
|
||||
is_solive: '-solive' in args
|
||||
is_prod: '-prod' in args
|
||||
is_verbose: '-verbose' in args || '--verbose' in args
|
||||
is_debug: '-g' in args || '-cg' in args
|
||||
is_vlines: '-g' in args && !('-cg' in args)
|
||||
is_keep_c: '-keep_c' in args
|
||||
is_pretty_c: '-pretty_c' in args
|
||||
is_cache: '-cache' in args
|
||||
is_stats: '-stats' in args
|
||||
obfuscate: '-obf' in args
|
||||
is_prof: '-prof' in args
|
||||
is_live: '-live' in args
|
||||
sanitize: '-sanitize' in args
|
||||
// nofmt: '-nofmt' in args
|
||||
|
||||
show_c_cmd: '-show_c_cmd' in args
|
||||
translated: 'translated' in args
|
||||
is_run: 'run' in args
|
||||
autofree: '-autofree' in args
|
||||
compress: '-compress' in args
|
||||
enable_globals: '--enable-globals' in args
|
||||
fast: '-fast' in args
|
||||
is_bare: '-freestanding' in args
|
||||
x64: '-x64' in args
|
||||
output_cross_c: '-output-cross-platform-c' in args
|
||||
prealloc: '-prealloc' in args
|
||||
is_repl: is_repl
|
||||
build_mode: build_mode
|
||||
cflags: cflags
|
||||
ccompiler: ccompiler
|
||||
building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || rdir_name == 'vfmt.v' || rdir_name == 'cmd/v' || dir.contains('vlib'))
|
||||
// is_fmt: comptime_define == 'vfmt'
|
||||
|
||||
user_mod_path: user_mod_path
|
||||
vlib_path: vlib_path
|
||||
vpath: vpath
|
||||
v2: '-v2' in args
|
||||
vroot: vroot
|
||||
out_name: out_name
|
||||
path: dir
|
||||
compile_defines: compile_defines
|
||||
compile_defines_all: compile_defines_all
|
||||
mod: mod
|
||||
}
|
||||
if pref.is_verbose || pref.is_debug {
|
||||
println('C compiler=$pref.ccompiler')
|
||||
}
|
||||
$if !linux {
|
||||
if pref.is_bare && !out_name.ends_with('.c') {
|
||||
println('V error: -freestanding only works on Linux for now')
|
||||
os.flush_stdout()
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
pref.fill_with_defaults()
|
||||
|
||||
// v.exe's parent directory should contain vlib
|
||||
if !os.is_dir(pref.vlib_path) || !os.is_dir(pref.vlib_path + os.path_separator + 'builtin') {
|
||||
// println('vlib not found, downloading it...')
|
||||
/*
|
||||
ret := os.system('git clone --depth=1 https://github.com/vlang/v .')
|
||||
if ret != 0 {
|
||||
println('failed to `git clone` vlib')
|
||||
println('make sure you are online and have git installed')
|
||||
exit(1)
|
||||
}
|
||||
*/
|
||||
println('vlib not found. It should be next to the V executable.')
|
||||
println('Go to https://vlang.io to install V.')
|
||||
println('(os.executable=${os.executable()} vlib_path=$pref.vlib_path vexe_path=${vexe_path()}')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
if pref.is_script && !os.exists(dir) {
|
||||
println('`$dir` does not exist')
|
||||
exit(1)
|
||||
}
|
||||
|
||||
return compiler.new_v(pref)
|
||||
}
|
||||
|
||||
fn find_c_compiler_thirdparty_options(args []string) string {
|
||||
mut cflags := cmdline.many_values(args,'-cflags')
|
||||
$if !windows {
|
||||
cflags << '-fPIC'
|
||||
}
|
||||
if '-m32' in args {
|
||||
cflags << '-m32'
|
||||
}
|
||||
return cflags.join(' ')
|
||||
}
|
||||
|
||||
fn parse_defines(defines []string) ([]string,[]string) {
|
||||
// '-d abc -d xyz=1 -d qwe=0' should produce:
|
||||
// compile_defines: ['abc','xyz']
|
||||
// compile_defines_all ['abc','xyz','qwe']
|
||||
mut compile_defines := []string
|
||||
mut compile_defines_all := []string
|
||||
for dfn in defines {
|
||||
dfn_parts := dfn.split('=')
|
||||
if dfn_parts.len == 1 {
|
||||
compile_defines << dfn
|
||||
compile_defines_all << dfn
|
||||
continue
|
||||
}
|
||||
if dfn_parts.len == 2 {
|
||||
compile_defines_all << dfn_parts[0]
|
||||
if dfn_parts[1] == '1' {
|
||||
compile_defines << dfn_parts[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
return compile_defines, compile_defines_all
|
||||
}
|
||||
|
||||
78
cmd/v/flag.v
Normal file
78
cmd/v/flag.v
Normal file
@@ -0,0 +1,78 @@
|
||||
// Copyright (c) 2019-2020 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 main
|
||||
|
||||
import os
|
||||
|
||||
const (
|
||||
//list_of_flags contains a list of flags where an argument is expected past it.
|
||||
list_of_flags = [
|
||||
'-o', '-os', '-cc', '-cflags', '-d'
|
||||
]
|
||||
)
|
||||
|
||||
fn get_basic_command_and_option(args []string) (string, []string) {
|
||||
mut option := []string
|
||||
for i, arg in args {
|
||||
if i == 0 {
|
||||
//Skip executable
|
||||
continue
|
||||
}
|
||||
if arg == '--' {
|
||||
//End of list of options. The next one is the command.
|
||||
if i+1 < os.args.len {
|
||||
return os.args[i+1], option
|
||||
}
|
||||
//There's no option past this
|
||||
return '', option
|
||||
}
|
||||
if arg in list_of_flags {
|
||||
i++
|
||||
continue
|
||||
}
|
||||
if arg[0] == `-` {
|
||||
option << arg
|
||||
continue
|
||||
}
|
||||
//It's not a flag. We did not skip it. It's a command.
|
||||
return arg, option
|
||||
}
|
||||
|
||||
//There's no arguments that were not part of a flag.
|
||||
return '', option
|
||||
}
|
||||
|
||||
fn non_empty(arg []string) []string {
|
||||
return arg.filter(it != '')
|
||||
}
|
||||
|
||||
fn join_flags_and_argument() []string {
|
||||
vosargs := os.getenv('VOSARGS')
|
||||
if vosargs != '' {
|
||||
return non_empty(vosargs.split(' '))
|
||||
}
|
||||
|
||||
mut args := []string
|
||||
vflags := os.getenv('VFLAGS')
|
||||
if vflags != '' {
|
||||
args << os.args[0]
|
||||
args << vflags.split(' ')
|
||||
if os.args.len > 1 {
|
||||
args << os.args[1..]
|
||||
}
|
||||
return non_empty(args)
|
||||
}
|
||||
|
||||
return non_empty(os.args)
|
||||
}
|
||||
|
||||
fn vexe_path() string {
|
||||
vexe := os.getenv('VEXE')
|
||||
if vexe != '' {
|
||||
return vexe
|
||||
}
|
||||
real_vexe_path := os.realpath(os.executable())
|
||||
os.setenv('VEXE', real_vexe_path, true)
|
||||
return real_vexe_path
|
||||
}
|
||||
101
cmd/v/help.v
Normal file
101
cmd/v/help.v
Normal file
@@ -0,0 +1,101 @@
|
||||
module main
|
||||
|
||||
const (
|
||||
help_text = 'Usage: v [options/commands] [file.v | directory]
|
||||
|
||||
To run V in REPL mode, run V without any arguments.
|
||||
To compile a directory/file, pass it as the only argument.
|
||||
|
||||
To run a directory/file, use `v run [file.v | directory]`. V will compile and run it for you.
|
||||
|
||||
This help message is only intended to be a quick start guide. For a comprehensive help message, use `v help --verbose`.'
|
||||
verbose_help_text = 'Usage: v [options/commands] [file.v | directory]
|
||||
|
||||
When V is run without any arguments, it is run in REPL mode.
|
||||
|
||||
When given a .v file, it will be compiled. The executable will have the
|
||||
same name as the input .v file: `v foo.v` produces `./foo` on *nix systems,
|
||||
`foo.exe` on Windows.
|
||||
|
||||
You can use -o to specify a different output executable\'s name.
|
||||
|
||||
When given a directory, all .v files contained in it will be compiled as
|
||||
part of a single main module.
|
||||
|
||||
By default the executable will have the same name as the directory.
|
||||
|
||||
To compile all V files in current directory, run `v .`
|
||||
|
||||
Any file ending in _test.v, will be treated as a test.
|
||||
It will be compiled and run, evaluating the assert statements in every
|
||||
function named test_xxx.
|
||||
|
||||
You can put common options inside an environment variable named VFLAGS, so that
|
||||
you don\'t have to repeat them.
|
||||
|
||||
You can set it like this: `export VFLAGS="-cc clang -debug"` on *nix,
|
||||
`set VFLAGS=-cc msvc` on Windows.
|
||||
|
||||
V respects the TMPDIR environment variable, and will put .tmp.c files in TMPDIR/v/ .
|
||||
If you have not set it, a suitable platform specific folder (like /tmp) will be used.
|
||||
|
||||
Options/commands:
|
||||
-h, help Display this information.
|
||||
-o <file> Write output to <file>.
|
||||
-o <file>.c Produce C source without compiling it.
|
||||
-o <file>.js Produce JavaScript source.
|
||||
-prod Build an optimized executable.
|
||||
-v, version Display compiler version and git hash of the compiler source.
|
||||
-verbose Produce a verbose log about what the compiler is doing, where it seeks for files and so on.
|
||||
-live Enable hot code reloading (required by functions marked with [live]).
|
||||
-os <OS> Produce an executable for the selected OS.
|
||||
OS can be linux, mac, windows, msvc.
|
||||
Use msvc if you want to use the MSVC compiler on Windows.
|
||||
-shared Build a shared library.
|
||||
-stats Show additional stats when compiling/running tests. Try `v -stats test .`
|
||||
|
||||
-cache Turn on usage of the precompiled module cache.
|
||||
It very significantly speeds up secondary compilations.
|
||||
|
||||
-obf Obfuscate the resulting binary.
|
||||
-compress Compress the resulting binary.
|
||||
- Shorthand for `v repl`.
|
||||
|
||||
Options for debugging/troubleshooting v programs:
|
||||
-g Generate debugging information in the backtraces. Add *V* line numbers to the generated executable.
|
||||
-cg Same as -g, but add *C* line numbers to the generated executable instead of *V* line numbers.
|
||||
-keep_c Do NOT remove the generated .tmp.c files after compilation.
|
||||
It is useful when using debuggers like gdb/visual studio, when given after `-g` / `-cg`.
|
||||
-pretty_c Run clang-format over the generated C file, so that it looks nicer. Requires you to have clang-format.
|
||||
-show_c_cmd Print the full C compilation command and how much time it took. See also `-verbose`.
|
||||
-cc <ccompiler> Specify which C compiler you want to use as a C backend.
|
||||
The C backend compiler should be able to handle C99 compatible C code.
|
||||
Common C compilers are gcc, clang, tcc, icc, cl...
|
||||
-cflags <flags> Pass additional C flags to the C backend compiler.
|
||||
Example: -cflags `sdl2-config --cflags`
|
||||
|
||||
Commands:
|
||||
up Update V. Run `v up` at least once per day, since V development is rapid and features/bugfixes are added constantly.
|
||||
run <file.v> Build and execute the V program in file.v. You can add arguments for the V program *after* the file name.
|
||||
build <module> Compile a module into an object file.
|
||||
repl Run the V REPL. If V is running in a tty terminal, the REPL is interactive, otherwise it just reads from stdin.
|
||||
symlink Useful on Unix systems. Symlinks the current V executable to /usr/local/bin/v, so that V is globally available.
|
||||
test-compiler Run all V test files, and compile all V examples.
|
||||
test folder/ Run all V test files located in the folder and its subfolders. You can also pass individual _test.v files too.
|
||||
fmt Run vfmt to format the source code. [wip]
|
||||
doc Run vdoc over the source code and produce documentation.
|
||||
translate Translates C to V. [wip, will be available in V 0.3]
|
||||
create Create a new v project interactively. Answer the questions, and run it with `v run projectname`
|
||||
|
||||
V package management commands:
|
||||
search keywords Search the https://vpm.vlang.io/ module repository for matching modules and shows their details.
|
||||
install <module> Install a user module from https://vpm.vlang.io/.
|
||||
update [module] Updates an already installed module, or ALL installed modules at once, when no module name is given.
|
||||
remove [module] Removes an installed module, or ALL installed modules at once, when no module name is given.
|
||||
'
|
||||
)
|
||||
/*
|
||||
- To disable automatic formatting:
|
||||
v -nofmt file.v
|
||||
*/
|
||||
|
||||
70
cmd/v/simple_tool.v
Normal file
70
cmd/v/simple_tool.v
Normal file
@@ -0,0 +1,70 @@
|
||||
// Copyright (c) 2019-2020 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 main
|
||||
|
||||
import (
|
||||
compiler
|
||||
filepath
|
||||
os
|
||||
)
|
||||
|
||||
fn launch_tool(is_verbose bool, tname string, cmdname string) {
|
||||
vexe := vexe_path()
|
||||
vroot := filepath.dir(vexe)
|
||||
compiler.set_vroot_folder(vroot)
|
||||
|
||||
mut tname_index := os.args.index(cmdname)
|
||||
if tname_index == -1 {
|
||||
tname_index = os.args.len
|
||||
}
|
||||
mut compilation_options := os.args[1..tname_index].clone()
|
||||
tool_args := os.args[1..].join(' ')
|
||||
tool_exe := os.realpath('$vroot/cmd/tools/$tname')
|
||||
tool_source := os.realpath('$vroot/cmd/tools/${tname}.v')
|
||||
tool_command := '"$tool_exe" $tool_args'
|
||||
if is_verbose {
|
||||
eprintln('launch_tool vexe : $vroot')
|
||||
eprintln('launch_tool vroot : $vroot')
|
||||
eprintln('launch_tool tool_args : $tool_args')
|
||||
eprintln('launch_tool tool_command: $tool_command')
|
||||
}
|
||||
|
||||
mut should_compile := false
|
||||
if !os.exists(tool_exe) {
|
||||
should_compile = true
|
||||
} else {
|
||||
if os.file_last_mod_unix(tool_exe) <= os.file_last_mod_unix(vexe) {
|
||||
// v was recompiled, maybe after v up ...
|
||||
// rebuild the tool too just in case
|
||||
should_compile = true
|
||||
}
|
||||
if os.file_last_mod_unix(tool_exe) <= os.file_last_mod_unix(tool_source) {
|
||||
// the user changed the source code of the tool
|
||||
should_compile = true
|
||||
}
|
||||
}
|
||||
if is_verbose {
|
||||
eprintln('launch_tool should_compile: $should_compile')
|
||||
}
|
||||
|
||||
if should_compile {
|
||||
if tname == 'vfmt' {
|
||||
compilation_options << ['-d', 'vfmt']
|
||||
}
|
||||
compilation_args := compilation_options.join(' ')
|
||||
compilation_command := '"$vexe" $compilation_args "$tool_source"'
|
||||
if is_verbose {
|
||||
eprintln('Compiling $tname with: "$compilation_command"')
|
||||
}
|
||||
tool_compilation := os.exec(compilation_command) or { panic(err) }
|
||||
if tool_compilation.exit_code != 0 {
|
||||
panic('V tool "$tool_source" could not be compiled\n' + tool_compilation.output)
|
||||
}
|
||||
}
|
||||
if is_verbose {
|
||||
eprintln('launch_tool running tool command: $tool_command ...')
|
||||
}
|
||||
|
||||
exit(os.system(tool_command))
|
||||
}
|
||||
31
cmd/v/symlink.v
Normal file
31
cmd/v/symlink.v
Normal file
@@ -0,0 +1,31 @@
|
||||
// Copyright (c) 2019-2020 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 main
|
||||
|
||||
import os
|
||||
|
||||
fn create_symlink() {
|
||||
$if windows {
|
||||
return
|
||||
}
|
||||
vexe := vexe_path()
|
||||
mut link_path := '/usr/local/bin/v'
|
||||
mut ret := os.exec('ln -sf $vexe $link_path') or { panic(err) }
|
||||
if ret.exit_code == 0 {
|
||||
println('Symlink "$link_path" has been created')
|
||||
}
|
||||
else if os.system('uname -o | grep -q \'[A/a]ndroid\'') == 0 {
|
||||
println('Failed to create symlink "$link_path". Trying again with Termux path for Android.')
|
||||
link_path = '/data/data/com.termux/files/usr/bin/v'
|
||||
ret = os.exec('ln -sf $vexe $link_path') or { panic(err) }
|
||||
if ret.exit_code == 0 {
|
||||
println('Symlink "$link_path" has been created')
|
||||
} else {
|
||||
println('Failed to create symlink "$link_path". Try again with sudo.')
|
||||
}
|
||||
} else {
|
||||
println('Failed to create symlink "$link_path". Try again with sudo.')
|
||||
}
|
||||
}
|
||||
|
||||
88
cmd/v/v.v
Normal file
88
cmd/v/v.v
Normal file
@@ -0,0 +1,88 @@
|
||||
// Copyright (c) 2019-2020 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 main
|
||||
|
||||
import (
|
||||
compiler
|
||||
os
|
||||
)
|
||||
|
||||
const (
|
||||
simple_cmd = [
|
||||
'fmt',
|
||||
'up',
|
||||
'create',
|
||||
'test', 'test-fmt', 'test-compiler',
|
||||
'bin2v',
|
||||
'repl',
|
||||
'build-tools', 'build-examples', 'build-vbinaries'
|
||||
]
|
||||
)
|
||||
|
||||
fn main() {
|
||||
arg := join_flags_and_argument()
|
||||
command, option := get_basic_command_and_option(arg)
|
||||
|
||||
is_verbose := '-verbose' in arg || '--verbose' in arg
|
||||
|
||||
if '-v' in option || '--version' in option || command == 'version' {
|
||||
// Print the version and exit.
|
||||
version_hash := compiler.vhash()
|
||||
println('V $compiler.Version $version_hash')
|
||||
return
|
||||
}
|
||||
if '-h' in option || '--help' in option || command == 'help' {
|
||||
if is_verbose {
|
||||
println(verbose_help_text)
|
||||
} else {
|
||||
println(help_text)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
if is_verbose {
|
||||
eprintln('v args: $arg')
|
||||
eprintln('v command: $command')
|
||||
eprintln('v options: $option')
|
||||
}
|
||||
|
||||
if command in simple_cmd {
|
||||
//External tools
|
||||
launch_tool(is_verbose, 'v' + command, command)
|
||||
return
|
||||
}
|
||||
|
||||
if command == 'run' || command == 'build' || command.ends_with('.v') || os.exists(command) {
|
||||
compile(command, arg)
|
||||
return
|
||||
}
|
||||
|
||||
match command {
|
||||
'', '-' {
|
||||
if arg.len == 1 {
|
||||
println('Running REPL as no arguments are provided. For usage information, use `v help`.')
|
||||
}
|
||||
launch_tool(is_verbose, 'vrepl', '')
|
||||
}
|
||||
'translate' {
|
||||
println('Translating C to V will be available in V 0.3 (January)')
|
||||
}
|
||||
'search', 'install', 'update', 'remove' {
|
||||
launch_tool(is_verbose, 'vpm', command)
|
||||
}
|
||||
'get' {
|
||||
println('Use `v install` to install modules from vpm.vlang.io.')
|
||||
}
|
||||
'symlink' {
|
||||
create_symlink()
|
||||
}
|
||||
'doc' {
|
||||
println('Currently unimplemented')
|
||||
}
|
||||
else {
|
||||
eprintln('v $command: unknown command\nRun "v help" for usage.')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user