move v.v to cmd/v
parent
3f5e4c55b2
commit
9332a83ce6
|
@ -12,8 +12,8 @@ jobs:
|
|||
echo "Changed files compared to origin/master are:" && git diff --name-status origin/master HEAD -- '*.v'
|
||||
- name: Build v (there is no need for dependencies for fmt)
|
||||
run: make -j4
|
||||
- name: Build a production tools/vfmt
|
||||
run: ./v -prod -d vfmt tools/vfmt.v
|
||||
- name: Build a production cmd/tools/vfmt
|
||||
run: ./v -prod -d vfmt cmd/tools/vfmt.v
|
||||
- name: Run v fmt -diff on only the changed files. Does NOT fail for now.
|
||||
run: git diff --name-status origin/master HEAD -- '*.v' |grep -v '^D'|rev|cut -f1|rev| xargs ./v fmt -noerror -diff
|
||||
- name: Run v test-fmt
|
||||
|
@ -28,12 +28,12 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list; sudo apt-get update; sudo apt-get install --quiet -y libglfw3 libglfw3-dev libfreetype6-dev libssl-dev sqlite3 libsqlite3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev
|
||||
- name: Build v
|
||||
run: echo $VFLAGS && make -j4 && ./v -cg -o v v.v
|
||||
run: echo $VFLAGS && make -j4 && ./v -cg -o v cmd/v
|
||||
- name: Test v->c
|
||||
run: |
|
||||
sudo ln -s /var/tmp/tcc/bin/tcc /usr/local/bin/tcc
|
||||
tcc -version
|
||||
./v -o v2 v.v # Make sure vtcc can build itself
|
||||
./v -o v2 cmd/v # Make sure vtcc can build itself
|
||||
./v -silent test-compiler
|
||||
- name: Test v binaries
|
||||
run: ./v -silent build-vbinaries
|
||||
|
@ -71,9 +71,9 @@ jobs:
|
|||
brew install freetype glfw openssl postgres sdl2 sdl2_ttf sdl2_mixer sdl2_image
|
||||
export LIBRARY_PATH="$LIBRARY_PATH:/usr/local/opt/openssl/lib/"
|
||||
- name: Build V
|
||||
run: make -j4 && ./v -cg -o v v.v
|
||||
run: make -j4 && ./v -cg -o v cmd/v
|
||||
- name: Build V using V
|
||||
run: ./v -o v2 v.v && ./v2 -o v3 v.v
|
||||
run: ./v -o v2 cmd/v && ./v2 -o v3 cmd/v
|
||||
- name: Test symlink
|
||||
run: sudo ./v symlink
|
||||
- name: Set up pg database
|
||||
|
@ -89,7 +89,7 @@ jobs:
|
|||
# - name: Test v->js
|
||||
# run: ./v -o hi.js examples/hello_v_js.v && node hi.js
|
||||
- name: Test symlink
|
||||
run: ./v symlink && v -o v2 v.v
|
||||
run: ./v symlink && v -o v2 cmd/v
|
||||
- name: Test vsh
|
||||
run: ./v examples/v_script.vsh
|
||||
- name: Test vid
|
||||
|
@ -107,7 +107,7 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list; sudo apt-get update; sudo apt-get install --quiet -y postgresql libpq-dev libglfw3 libglfw3-dev libfreetype6-dev libssl-dev sqlite3 libsqlite3-dev libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev
|
||||
- name: Build V
|
||||
run: make -j4 && ./v -cc gcc -o v v.v
|
||||
run: make -j4 && ./v -cc gcc -o v cmd/v
|
||||
- name: Test V
|
||||
run: ./v -silent test-compiler
|
||||
- name: Test v binaries
|
||||
|
@ -122,13 +122,13 @@ jobs:
|
|||
run: ./v -freestanding -o bare vlib/os/bare/bare_example_linux.v
|
||||
- name: x64 machine code generation
|
||||
run: |
|
||||
./v -o vprod -prod v.v
|
||||
cd tools
|
||||
./v -o vprod -prod cmd/v
|
||||
cd cmd/tools
|
||||
echo "Generating a 1m line V file..."
|
||||
../vprod gen1m.v
|
||||
../../vprod gen1m.v
|
||||
./gen1m > 1m.v
|
||||
echo "Building it..."
|
||||
../vprod -x64 -o 1m 1m.v
|
||||
../../vprod -x64 -o 1m 1m.v
|
||||
echo "Running it..."
|
||||
ls
|
||||
# ./1m
|
||||
|
@ -191,7 +191,7 @@ jobs:
|
|||
- name: Install dependencies
|
||||
run: sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list; sudo apt-get update; sudo apt-get install --quiet -y musl musl-tools libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev
|
||||
- name: Build v
|
||||
run: echo $VFLAGS && make -j4 && ./v -cg -o v v.v
|
||||
run: echo $VFLAGS && make -j4 && ./v -cg -o v cmd/v
|
||||
- name: Test v binaries
|
||||
run: ./v -silent build-vbinaries
|
||||
# - name: Test v->js
|
||||
|
|
|
@ -4,7 +4,7 @@ on:
|
|||
schedule:
|
||||
- cron: '31 1,12 * * *'
|
||||
|
||||
jobs:
|
||||
jobs:
|
||||
network-tests-ubuntu-tcc:
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
|
@ -15,16 +15,16 @@ jobs:
|
|||
run: |
|
||||
sudo rm -f /etc/apt/sources.list.d/dotnetdev.list /etc/apt/sources.list.d/microsoft-prod.list
|
||||
sudo apt-get update
|
||||
sudo apt-get install --quiet -y libglfw3 libglfw3-dev libfreetype6-dev libssl-dev
|
||||
sudo apt-get install --quiet -y sqlite3 libsqlite3-dev
|
||||
sudo apt-get install --quiet -y libglfw3 libglfw3-dev libfreetype6-dev libssl-dev
|
||||
sudo apt-get install --quiet -y sqlite3 libsqlite3-dev
|
||||
sudo apt-get install --quiet -y libsdl2-dev libsdl2-ttf-dev libsdl2-mixer-dev libsdl2-image-dev
|
||||
- name: Build v
|
||||
run: echo $VFLAGS && make -j4 && ./v -cg -o v v.v
|
||||
run: echo $VFLAGS && make -j4 && ./v -cg -o v cmd/v
|
||||
- name: Test v->c
|
||||
run: |
|
||||
sudo ln -s /var/tmp/tcc/bin/tcc /usr/local/bin/tcc
|
||||
tcc -version
|
||||
./v -o v2 v.v # Make sure vtcc can build itself
|
||||
./v -o v2 cmd/v # Make sure vtcc can build itself
|
||||
- name: Run network tests
|
||||
run: ./v -d network test vlib/
|
||||
|
||||
|
|
|
@ -7,20 +7,20 @@ fns.txt
|
|||
/v.c
|
||||
/v.*.c
|
||||
/v.c.out
|
||||
/tools/performance_compare
|
||||
/tools/oldv
|
||||
/tools/vrepl
|
||||
/tools/vtest
|
||||
/tools/vtest-compiler
|
||||
/tools/vtest-fmt
|
||||
/tools/vfmt
|
||||
/tools/vbin2v
|
||||
/tools/vup
|
||||
/tools/vpm
|
||||
/tools/vcreate
|
||||
/tools/vbuild-examples
|
||||
/tools/vbuild-tools
|
||||
/tools/vbuild-vbinaries
|
||||
/cmd/tools/performance_compare
|
||||
/cmd/tools/oldv
|
||||
/cmd/tools/vrepl
|
||||
/cmd/tools/vtest
|
||||
/cmd/tools/vtest-compiler
|
||||
/cmd/tools/vtest-fmt
|
||||
/cmd/tools/vfmt
|
||||
/cmd/tools/vbin2v
|
||||
/cmd/tools/vup
|
||||
/cmd/tools/vpm
|
||||
/cmd/tools/vcreate
|
||||
/cmd/tools/vbuild-examples
|
||||
/cmd/tools/vbuild-tools
|
||||
/cmd/tools/vbuild-vbinaries
|
||||
/v_g
|
||||
/v_cg
|
||||
/v_prod
|
||||
|
|
|
@ -3,7 +3,7 @@ FROM mstorsjo/llvm-mingw
|
|||
LABEL maintainer="Vitaly Takmazov <vitalyster@gmail.com>"
|
||||
COPY . .
|
||||
RUN make
|
||||
RUN ./v -os windows -o v.c v.v
|
||||
RUN ./v -os windows -o v.c cmd/v
|
||||
RUN x86_64-w64-mingw32-gcc v.c -std=c99 -w -municode -o v.exe
|
||||
RUN file v.exe
|
||||
|
||||
|
|
8
Makefile
8
Makefile
|
@ -42,8 +42,8 @@ endif
|
|||
all: latest_vc latest_tcc
|
||||
ifdef WIN32
|
||||
$(CC) $(CFLAGS) -std=c99 -municode -w -o v2.exe $(TMPVC)/$(VCFILE) $(LDFLAGS)
|
||||
./v2.exe -o v3.exe v.v
|
||||
./v3.exe -o v.exe -prod v.v
|
||||
./v2.exe -o v3.exe cmd/v
|
||||
./v3.exe -o v.exe -prod cmd/v
|
||||
rm -f v2.exe v3.exe
|
||||
else
|
||||
$(CC) $(CFLAGS) -std=gnu11 -w -o v $(TMPVC)/$(VCFILE) $(LDFLAGS) -lm
|
||||
|
@ -92,10 +92,10 @@ $(TMPVC)/.git/config:
|
|||
$(MAKE) fresh_vc
|
||||
|
||||
selfcompile:
|
||||
./v -cg -o v v.v
|
||||
./v -cg -o v cmd/v
|
||||
|
||||
selfcompile-static:
|
||||
./v -cg -cflags '--static' -o v-static v.v
|
||||
./v -cg -cflags '--static' -o v-static cmd/v
|
||||
|
||||
modules: module_builtin module_strings module_strconv
|
||||
module_builtin:
|
||||
|
|
|
@ -11,9 +11,9 @@ import (
|
|||
fn main() {
|
||||
exe := os.executable()
|
||||
dir := filepath.dir(exe)
|
||||
vdir := filepath.dir(filepath.dir(dir))
|
||||
vdir := filepath.dir(filepath.dir(filepath.dir(dir)))
|
||||
if !os.exists('$vdir/v') && !os.is_dir('$vdir/vlib') {
|
||||
println('fast.html generator needs to be located in `v/tools/fast/`')
|
||||
println('fast.html generator needs to be located in `v/cmd/tools/fast`')
|
||||
}
|
||||
println('fast.html generator\n')
|
||||
// Fetch the last commit's hash
|
||||
|
@ -36,11 +36,11 @@ fn main() {
|
|||
}
|
||||
// Build an optimized V
|
||||
println('Building vprod...')
|
||||
exec('v -o $vdir/vprod -prod $vdir/v.v')
|
||||
exec('v -o $vdir/vprod -prod $vdir/cmd/v')
|
||||
println('Measuring...')
|
||||
diff1 := measure('$vdir/vprod -cc clang -o v.c $vdir/v.v')
|
||||
diff2 := measure('$vdir/vprod -cc clang -o v2 $vdir/v.v')
|
||||
diff3 := measure('$vdir/vprod -x64 $vdir/tools/1mil.v')
|
||||
diff1 := measure('$vdir/vprod -cc clang -o v.c $vdir/cmd/v')
|
||||
diff2 := measure('$vdir/vprod -cc clang -o v2 $vdir/cmd/v')
|
||||
diff3 := measure('$vdir/vprod -x64 $vdir/cmd/tools/1mil.v')
|
||||
diff4 := measure('$vdir/vprod -cc clang $vdir/examples/hello_world.v')
|
||||
//println('Building V took ${diff}ms')
|
||||
commit_date := exec('git log -n1 --pretty="format:%at"')
|
|
@ -38,7 +38,7 @@ td {
|
|||
<h2>Is V still fast?</h2>
|
||||
|
||||
Monitoring compilation speed for each commit. <br><br>
|
||||
Source code: <a target=blank href='https://github.com/vlang/v/blob/master/tools/fast/fast.v'>fast.v</a> <br><br>
|
||||
Source code: <a target=blank href='https://github.com/vlang/v/blob/master/cmd/tools/fast/fast.v'>fast.v</a> <br><br>
|
||||
|
||||
<table>
|
||||
<tr>
|
|
@ -291,7 +291,7 @@ fn (gen_vc mut GenVC) generate() {
|
|||
v_flags := if os_name == 'nix' { '-output-cross-platform-c' } else { '-os $os_name' }
|
||||
c_file := 'v${vc_suffix}.c'
|
||||
// try generate .c file
|
||||
gen_vc.cmd_exec('$v_exec $v_flags -o $c_file $git_repo_dir_v/v.v')
|
||||
gen_vc.cmd_exec('$v_exec $v_flags -o $c_file $git_repo_dir_v/cmd/v')
|
||||
// check if the c file seems ok
|
||||
gen_vc.assert_file_exists_and_is_not_too_short(c_file, err_msg_gen_c)
|
||||
// embed the latest v commit hash into the c file
|
|
@ -39,7 +39,7 @@ pub fn new_test_session(vargs string) TestSession {
|
|||
pub fn vexe_path() string {
|
||||
// NB: tools extracted from v require that the VEXE
|
||||
// environment variable contains the path to the v executable location.
|
||||
// They are usually launched by vlib/compiler/vtools.v,
|
||||
// They are usually launched by cmd/v/simple_tool.v,
|
||||
// launch_tool/1 , which provides it.
|
||||
return os.getenv('VEXE')
|
||||
}
|
||||
|
@ -238,11 +238,11 @@ pub fn building_any_v_binaries_failed() bool {
|
|||
testing.vlib_should_be_present(parent_dir)
|
||||
os.chdir(parent_dir)
|
||||
mut failed := false
|
||||
v_build_commands := ['$vexe -o v_g -g v.v',
|
||||
'$vexe -o v_prod_g -prod -g v.v',
|
||||
'$vexe -o v_cg -cg v.v',
|
||||
'$vexe -o v_prod_cg -prod -cg v.v',
|
||||
'$vexe -o v_prod -prod v.v',
|
||||
v_build_commands := ['$vexe -o v_g -g cmd/v',
|
||||
'$vexe -o v_prod_g -prod -g cmd/v',
|
||||
'$vexe -o v_cg -cg cmd/v',
|
||||
'$vexe -o v_prod_cg -prod -cg cmd/v',
|
||||
'$vexe -o v_prod -prod cmd/v',
|
||||
]
|
||||
mut bmark := benchmark.new_benchmark()
|
||||
for cmd in v_build_commands {
|
|
@ -92,7 +92,7 @@ pub mut:
|
|||
commit_vc_hash string // the git commit of the vc repo, corresponding to commit_v__hash
|
||||
vexename string // v or v.exe
|
||||
vexepath string // the full absolute path to the prepared v/v.exe
|
||||
vvlocation string // v.v or compiler/ , depending on v version
|
||||
vvlocation string // v.v or compiler/ or cmd/v, depending on v version
|
||||
}
|
||||
|
||||
pub fn (vgit_context mut VGitContext) compile_oldv_if_needed() {
|
||||
|
@ -117,7 +117,11 @@ pub fn (vgit_context mut VGitContext) compile_oldv_if_needed() {
|
|||
v_commithash,vccommit_before := vgit.prepare_vc_source(vgit_context.path_vc, vgit_context.path_v, vgit_context.commit_v)
|
||||
vgit_context.commit_v__hash = v_commithash
|
||||
vgit_context.commit_vc_hash = vccommit_before
|
||||
vgit_context.vvlocation = if os.exists('v.v') { 'v.v' } else { 'compiler' }
|
||||
if os.exists('cmd/v') {
|
||||
vgit_context.vvlocation = 'cmd/v'
|
||||
} else {
|
||||
vgit_context.vvlocation = if os.exists('v.v') { 'v.v' } else { 'compiler' }
|
||||
}
|
||||
if os.is_dir(vgit_context.path_v) && os.exists(vgit_context.vexepath) {
|
||||
// already compiled, so no need to compile v again
|
||||
return
|
|
@ -19,7 +19,7 @@ const (
|
|||
git checkout known_good_commit
|
||||
git bisect good
|
||||
## Now git will automatically checkout a middle commit between the bad and the good
|
||||
tools/oldv HEAD --command="run commands in oldv folder, to verify if the commit is good or bad"
|
||||
cmd/tools/oldv HEAD --command="run commands in oldv folder, to verify if the commit is good or bad"
|
||||
## See what the result is, and either do: ...
|
||||
git bisect good
|
||||
## ... or do:
|
|
@ -126,7 +126,9 @@ fn (c &Context) prepare_v(cdir string, commit string) {
|
|||
vversion := scripting.run('$cdir/v --version')
|
||||
vcommit := scripting.run('git rev-parse --short --verify HEAD')
|
||||
println('V version is: ${vversion} , local source commit: ${vcommit}')
|
||||
if vgit_context.vvlocation == 'v.v' {
|
||||
if vgit_context.vvlocation == 'cmd/v' {
|
||||
println('Source lines of the compiler: ' + scripting.run('wc cmd/v/*.v vlib/compiler/*.v | tail -n -1'))
|
||||
} else if vgit_context.vvlocation == 'v.v' {
|
||||
println('Source lines of the compiler: ' + scripting.run('wc v.v vlib/compiler/*.v | tail -n -1'))
|
||||
}else{
|
||||
println('Source lines of the compiler: ' + scripting.run('wc compiler/*.v | tail -n -1'))
|
||||
|
@ -136,8 +138,18 @@ fn (c &Context) prepare_v(cdir string, commit string) {
|
|||
fn (c Context) compare_v_performance(label string, commands []string) string {
|
||||
println('---------------------------------------------------------------------------------')
|
||||
println('Compare v performance when doing the following commands ($label):')
|
||||
source_location_a := if os.exists('$c.a/v.v') { 'v.v ' } else { 'compiler/ ' }
|
||||
source_location_b := if os.exists('$c.b/v.v') { 'v.v ' } else { 'compiler/ ' }
|
||||
mut source_location_a := ''
|
||||
mut source_location_b := ''
|
||||
if os.exists('$c.a/cmd/v') {
|
||||
source_location_a = 'cmd/v'
|
||||
} else {
|
||||
source_location_a = if os.exists('$c.a/v.v') { 'v.v ' } else { 'compiler/ ' }
|
||||
}
|
||||
if os.exists('$c.b/cmd/v') {
|
||||
source_location_b = 'cmd/v'
|
||||
} else {
|
||||
source_location_b = if os.exists('$c.b/v.v') { 'v.v ' } else { 'compiler/ ' }
|
||||
}
|
||||
timestamp_a,_ := vgit.line_to_timestamp_and_commit(scripting.run('cd $c.a/ ; git rev-list -n1 --timestamp HEAD'))
|
||||
timestamp_b,_ := vgit.line_to_timestamp_and_commit(scripting.run('cd $c.b/ ; git rev-list -n1 --timestamp HEAD'))
|
||||
debug_option_a := if timestamp_a > 1570877641 { '-g ' } else { '-debug ' }
|
|
@ -1,28 +1,28 @@
|
|||
# V preludes:
|
||||
|
||||
The tools/preludes/ contains small v code snippets, that V uses when
|
||||
The cmd/tools/preludes/ contains small v code snippets, that V uses when
|
||||
compiling certain v programs. V adds the files below automatically itself.
|
||||
Each file is used in different situations (see below).
|
||||
|
||||
NB: preludes are *NOT* intended to be used by user programs/modules.
|
||||
The folder tools/preludes/ is *NOT* a v module.
|
||||
The folder cmd/tools/preludes/ is *NOT* a v module.
|
||||
|
||||
## Details:
|
||||
|
||||
### tools/preludes/live_main.v
|
||||
### cmd/tools/preludes/live_main.v
|
||||
Used when compiling live programs. This file is used by the main executable
|
||||
live program, that starts the file change monitoring thread. Each live program
|
||||
needs module `os` and module `time`, in order for the background file change
|
||||
monitoring thread to work properly.
|
||||
|
||||
### tools/preludes/live_shared.v
|
||||
### cmd/tools/preludes/live_shared.v
|
||||
Used when compiling live programs, for the shared library portion of the live
|
||||
programs, that is reloaded each time the code is changed.
|
||||
|
||||
### tools/preludes/tests_assertions.v
|
||||
### cmd/tools/preludes/tests_assertions.v
|
||||
Used when compiling `_test.v` programs.
|
||||
It specifies how failed assertions will look.
|
||||
|
||||
### tools/preludes/tests_with_stats.v
|
||||
### cmd/tools/preludes/tests_with_stats.v
|
||||
Used when compiling `_test.v` programs with -stats option.
|
||||
It specifies how the result will appear ('assert' vs 'asserts' and so on).
|
|
@ -8,7 +8,7 @@ import (
|
|||
fn main() {
|
||||
args := os.args
|
||||
args_string := args[1..].join(' ')
|
||||
if testing.v_build_failing(args_string.all_before('build-tools'), 'tools') {
|
||||
if testing.v_build_failing(args_string.all_before('build-tools'), 'cmd/tools') {
|
||||
exit(1)
|
||||
}
|
||||
}
|
|
@ -8,6 +8,7 @@ import (
|
|||
os.cmdline
|
||||
filepath
|
||||
compiler
|
||||
v.pref
|
||||
)
|
||||
|
||||
struct FormatOptions {
|
||||
|
@ -35,8 +36,8 @@ const (
|
|||
|
||||
fn main() {
|
||||
toolexe := os.executable()
|
||||
compiler.set_vroot_folder(filepath.dir(filepath.dir(toolexe)))
|
||||
args := compiler.env_vflags_and_os_args()
|
||||
compiler.set_vroot_folder(filepath.dir(filepath.dir(filepath.dir(toolexe))))
|
||||
args := join_flags_and_argument()
|
||||
foptions := FormatOptions{
|
||||
is_c: '-c' in args
|
||||
is_l: '-l' in args
|
||||
|
@ -134,10 +135,10 @@ fn main() {
|
|||
|
||||
fn (foptions &FormatOptions) format_file(file string) {
|
||||
tmpfolder := os.tmpdir()
|
||||
mut compiler_params := []string
|
||||
mut compiler_params := &pref.Preferences{}
|
||||
target_os := file_to_target_os(file)
|
||||
if target_os != '' {
|
||||
compiler_params << ['-os', target_os]
|
||||
compiler_params.os = pref.os_from_string(target_os)
|
||||
}
|
||||
mut cfile := file
|
||||
mut mod_folder_parent := tmpfolder
|
||||
|
@ -158,7 +159,7 @@ fn (foptions &FormatOptions) format_file(file string) {
|
|||
}
|
||||
os.write_file(main_program_file, main_program_content)
|
||||
cfile = main_program_file
|
||||
compiler_params << ['-user_mod_path', mod_folder_parent]
|
||||
compiler_params.user_mod_path = mod_folder_parent
|
||||
}
|
||||
if !is_test_file && mod_name == 'main' {
|
||||
// NB: here, file is guaranted to be a main. We do not know however
|
||||
|
@ -166,7 +167,10 @@ fn (foptions &FormatOptions) format_file(file string) {
|
|||
// project, like vorum or vid.
|
||||
cfile = get_compile_name_of_potential_v_project(cfile)
|
||||
}
|
||||
compiler_params << cfile
|
||||
compiler_params.path = cfile
|
||||
compiler_params.mod = mod_name
|
||||
compiler_params.is_test = is_test_file
|
||||
compiler_params.is_script = file.ends_with('.v') || file.ends_with('.vsh')
|
||||
if foptions.is_verbose {
|
||||
eprintln('vfmt format_file: file: $file')
|
||||
eprintln('vfmt format_file: cfile: $cfile')
|
||||
|
@ -176,9 +180,15 @@ fn (foptions &FormatOptions) format_file(file string) {
|
|||
eprintln('vfmt format_file: mod_folder: $mod_folder')
|
||||
eprintln('vfmt format_file: mod_folder_parent: $mod_folder_parent')
|
||||
eprintln('vfmt format_file: use_tmp_main_program: $use_tmp_main_program')
|
||||
eprintln('vfmt format_file: compiler_params: $compiler_params')
|
||||
eprintln('vfmt format_file: compiler_params: ')
|
||||
print_compiler_options( compiler_params )
|
||||
eprintln('-------------------------------------------')
|
||||
}
|
||||
compiler_params.fill_with_defaults()
|
||||
if foptions.is_verbose {
|
||||
eprintln('vfmt format_file: compiler_params: AFTER fill_with_defaults() ')
|
||||
print_compiler_options( compiler_params )
|
||||
}
|
||||
formatted_file_path := foptions.compile_file(file, compiler_params)
|
||||
if use_tmp_main_program {
|
||||
if !foptions.is_debug {
|
||||
|
@ -188,6 +198,22 @@ fn (foptions &FormatOptions) format_file(file string) {
|
|||
eprintln('${FORMATTED_FILE_TOKEN}${formatted_file_path}')
|
||||
}
|
||||
|
||||
fn print_compiler_options( compiler_params &pref.Preferences ) {
|
||||
eprintln(' os: ' + compiler_params.os.str() )
|
||||
eprintln(' ccompiler: $compiler_params.ccompiler' )
|
||||
eprintln(' mod: $compiler_params.mod ')
|
||||
eprintln(' path: $compiler_params.path ')
|
||||
eprintln(' out_name: $compiler_params.out_name ')
|
||||
eprintln(' vroot: $compiler_params.vroot ')
|
||||
eprintln(' vpath: $compiler_params.vpath ')
|
||||
eprintln(' vlib_path: $compiler_params.vlib_path ')
|
||||
eprintln(' out_name: $compiler_params.out_name ')
|
||||
eprintln(' umpath: $compiler_params.user_mod_path ')
|
||||
eprintln(' cflags: $compiler_params.cflags ')
|
||||
eprintln(' is_test: $compiler_params.is_test ')
|
||||
eprintln(' is_script: $compiler_params.is_script ')
|
||||
}
|
||||
|
||||
fn (foptions &FormatOptions) post_process_file(file string, formatted_file_path string) {
|
||||
if formatted_file_path.len == 0 {
|
||||
return
|
||||
|
@ -238,7 +264,7 @@ fn (foptions &FormatOptions) post_process_file(file string, formatted_file_path
|
|||
}
|
||||
|
||||
fn usage() {
|
||||
print('Usage: tools/vfmt [flags] fmt path_to_source.v [path_to_other_source.v]
|
||||
print('Usage: cmd/tools/vfmt [flags] fmt path_to_source.v [path_to_other_source.v]
|
||||
Formats the given V source files, and prints their formatted source to stdout.
|
||||
Options:
|
||||
-c check if file is already formatted.
|
||||
|
@ -261,12 +287,13 @@ fn find_working_diff_command() ?string {
|
|||
return error('no working diff command found')
|
||||
}
|
||||
|
||||
fn (foptions &FormatOptions) compile_file(file string, compiler_params []string) string {
|
||||
fn (foptions &FormatOptions) compile_file(file string, compiler_params &pref.Preferences) string {
|
||||
if foptions.is_verbose {
|
||||
eprintln('> new_v_compiler_with_args file: ' + file)
|
||||
eprintln('> new_v_compiler_with_args compiler_params: ' + compiler_params.join(' '))
|
||||
eprintln('> new_v_compiler_with_args file: $file')
|
||||
eprintln('> new_v_compiler_with_args compiler_params:')
|
||||
print_compiler_options( compiler_params )
|
||||
}
|
||||
mut v := compiler.new_v_compiler_with_args(compiler_params)
|
||||
mut v := compiler.new_v(compiler_params)
|
||||
v.v_fmt_file = file
|
||||
if foptions.is_all {
|
||||
v.v_fmt_all = true
|
||||
|
@ -360,3 +387,28 @@ fn get_compile_name_of_potential_v_project(file string) string {
|
|||
}
|
||||
return pfolder
|
||||
}
|
||||
|
||||
//TODO Move join_flags_and_argument() and non_empty() into `cmd/internal` when v.mod work correctly
|
||||
//to prevent code duplication with `cmd/v` (cmd/v/flag.v)
|
||||
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 non_empty(arg []string) []string {
|
||||
return arg.filter(it != '')
|
||||
}
|
|
@ -6,6 +6,7 @@ import (
|
|||
strings
|
||||
filepath
|
||||
compiler
|
||||
v.pref
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -32,7 +33,11 @@ fn analyze_v_file(file string) {
|
|||
println('$hash $file $hash')
|
||||
|
||||
// main work:
|
||||
mut v := compiler.new_v_compiler_with_args([file])
|
||||
mut pref := &pref.Preferences{
|
||||
path: file
|
||||
}
|
||||
pref.fill_with_defaults()
|
||||
mut v := compiler.new_v(pref)
|
||||
v.add_v_files_to_compile()
|
||||
for f in v.files { v.parse(f, .decl) }
|
||||
fi := v.get_file_parser_index( file ) or { panic(err) }
|
||||
|
@ -51,7 +56,7 @@ fn analyze_v_file(file string) {
|
|||
|
||||
fn main(){
|
||||
toolexe := os.executable()
|
||||
compiler.set_vroot_folder( filepath.dir(filepath.dir(toolexe)) )
|
||||
compiler.set_vroot_folder(filepath.dir(filepath.dir(filepath.dir(toolexe))))
|
||||
|
||||
mut fp := flag.new_flag_parser(os.args)
|
||||
fp.application(filepath.filename(toolexe))
|
|
@ -33,8 +33,8 @@ fn v_test_compiler(vargs string) {
|
|||
|
||||
// Make sure v.c can be compiled without warnings
|
||||
$if macos {
|
||||
if os.exists('/v.v') {
|
||||
os.system('$vexe -o v.c v.v')
|
||||
if os.exists('/cmd/v') {
|
||||
os.system('$vexe -o v.c cmd/v')
|
||||
if os.system('cc -Werror v.c') != 0 {
|
||||
eprintln('cc failed to build v.c without warnings')
|
||||
exit(1)
|
||||
|
@ -42,7 +42,7 @@ fn v_test_compiler(vargs string) {
|
|||
eprintln('v.c can be compiled without warnings. This is good :)')
|
||||
}
|
||||
}
|
||||
building_tools_failed := testing.v_build_failing(vargs, 'tools')
|
||||
building_tools_failed := testing.v_build_failing(vargs, 'cmd/tools')
|
||||
eprintln('')
|
||||
testing.eheader('Testing all _test.v files...')
|
||||
mut compiler_test_session := testing.new_test_session(vargs)
|
|
@ -7,14 +7,14 @@ import (
|
|||
|
||||
const (
|
||||
known_failing_exceptions = ['./examples/vweb/vweb_example.v',
|
||||
'./tools/gen_vc.v',
|
||||
'./tools/modules/vgit/vgit.v', // generics
|
||||
'./tools/preludes/live_main.v',
|
||||
'./tools/preludes/live_shared.v',
|
||||
'./tools/preludes/tests_assertions.v',
|
||||
'./tools/preludes/tests_with_stats.v',
|
||||
'./tools/performance_compare.v', // generics
|
||||
'./tools/oldv.v', // generics
|
||||
'./cmd/tools/gen_vc.v',
|
||||
'./cmd/tools/modules/vgit/vgit.v', // generics
|
||||
'./cmd/tools/preludes/live_main.v',
|
||||
'./cmd/tools/preludes/live_shared.v',
|
||||
'./cmd/tools/preludes/tests_assertions.v',
|
||||
'./cmd/tools/preludes/tests_with_stats.v',
|
||||
'./cmd/tools/performance_compare.v', // generics
|
||||
'./cmd/tools/oldv.v', // generics
|
||||
'./tutorials/code/blog/article.v',
|
||||
'./tutorials/code/blog/blog.v',
|
||||
'./vlib/arrays/arrays.v',
|
|
@ -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)
|
||||
}
|
|
@ -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
|
||||
}
|
||||
|
|
@ -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
|
||||
}
|
|
@ -1,8 +1,16 @@
|
|||
module compiler
|
||||
module main
|
||||
|
||||
pub const (
|
||||
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
|
|
@ -1,52 +1,57 @@
|
|||
module compiler
|
||||
// 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
|
||||
compiler
|
||||
filepath
|
||||
os
|
||||
)
|
||||
|
||||
pub fn launch_tool(tname string, cmdname string) {
|
||||
is_verbose := '-verbose' in os.args || '--verbose' in os.args
|
||||
fn launch_tool(is_verbose bool, tname string, cmdname string) {
|
||||
vexe := vexe_path()
|
||||
vroot := filepath.dir(vexe)
|
||||
set_vroot_folder( vroot ) // needed by tools to find back v
|
||||
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/tools/$tname')
|
||||
tool_source := os.realpath('$vroot/tools/${tname}.v')
|
||||
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 {
|
||||
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 tool_should_be_recompiled := false
|
||||
}
|
||||
|
||||
mut should_compile := false
|
||||
if !os.exists(tool_exe) {
|
||||
// fresh checkout
|
||||
tool_should_be_recompiled = true
|
||||
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
|
||||
tool_should_be_recompiled = true
|
||||
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
|
||||
tool_should_be_recompiled = true
|
||||
should_compile = true
|
||||
}
|
||||
}
|
||||
|
||||
if is_verbose {
|
||||
eprintln('launch_tool tool_should_be_recompiled: $tool_should_be_recompiled')
|
||||
eprintln('launch_tool should_compile: $should_compile')
|
||||
}
|
||||
|
||||
if tool_should_be_recompiled {
|
||||
if tname == 'vfmt' { compilation_options << ['-d', 'vfmt'] }
|
||||
|
||||
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 {
|
||||
|
@ -61,5 +66,5 @@ pub fn launch_tool(tname string, cmdname string) {
|
|||
eprintln('launch_tool running tool command: $tool_command ...')
|
||||
}
|
||||
|
||||
exit( os.system(tool_command) )
|
||||
exit(os.system(tool_command))
|
||||
}
|
|
@ -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.')
|
||||
}
|
||||
}
|
||||
|
|
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
8
make.bat
8
make.bat
|
@ -35,8 +35,8 @@ if %ERRORLEVEL% NEQ 0 (
|
|||
)
|
||||
|
||||
echo Now using V to build V...
|
||||
v2.exe -o v3.exe v.v
|
||||
v3.exe -o v.exe -prod v.v
|
||||
v2.exe -o v3.exe cmd/v
|
||||
v3.exe -o v.exe -prod cmd/v
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
echo v.exe failed to compile itself - Create an issue at 'https://github.com/vlang'
|
||||
exit /b 1
|
||||
|
@ -77,8 +77,8 @@ if %ERRORLEVEL% NEQ 0 (
|
|||
)
|
||||
|
||||
echo rebuild from source (twice, in case of C definitions changes)
|
||||
v2.exe -cc msvc -o v3.exe v.v
|
||||
v3.exe -cc msvc -o v -prod v.v
|
||||
v2.exe -cc msvc -o v3.exe cmd/v
|
||||
v3.exe -cc msvc -o v -prod cmd/v
|
||||
if %ERRORLEVEL% NEQ 0 (
|
||||
echo V failed to build itself with error %ERRORLEVEL%
|
||||
goto :compileerror
|
||||
|
|
140
v.v
140
v.v
|
@ -1,140 +0,0 @@
|
|||
// 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
|
||||
benchmark
|
||||
os
|
||||
filepath
|
||||
// v.types
|
||||
// time
|
||||
)
|
||||
|
||||
const (
|
||||
known_commands = ['run', 'build', 'version', 'doc']
|
||||
simple_tools = ['fmt',
|
||||
'up',
|
||||
'create',
|
||||
'test', 'test-fmt', 'test-compiler',
|
||||
'bin2v',
|
||||
'repl',
|
||||
'build-tools', 'build-examples', 'build-vbinaries']
|
||||
)
|
||||
|
||||
fn main() {
|
||||
is_verbose := '-verbose' in os.args || '--verbose' in os.args
|
||||
// t := time.ticks()
|
||||
// defer { println(time.ticks() - t) }
|
||||
args := compiler.env_vflags_and_os_args()
|
||||
options,command := compiler.get_v_options_and_main_command(args)
|
||||
if is_verbose {
|
||||
eprintln('v args: $args')
|
||||
eprintln('v command: $command')
|
||||
eprintln('v options: $options')
|
||||
}
|
||||
// external tool
|
||||
if command in simple_tools {
|
||||
compiler.launch_tool('v' + command, command)
|
||||
return
|
||||
}
|
||||
// v run, v doc, etc
|
||||
if !command.starts_with('-') && !command.ends_with('.v') && !os.exists(command) {
|
||||
v_command(command, args)
|
||||
}
|
||||
// Print the version and exit.
|
||||
if '-v' in options || '--version' in options {
|
||||
version_hash := compiler.vhash()
|
||||
println('V $compiler.Version $version_hash')
|
||||
return
|
||||
}
|
||||
else if '-h' in options || '--help' in options {
|
||||
println(compiler.help_text)
|
||||
return
|
||||
}
|
||||
// No args? REPL
|
||||
else if command == '' || (args.len == 2 && args[1] == '-') {
|
||||
compiler.launch_tool('vrepl', '')
|
||||
return
|
||||
}
|
||||
// Construct the V object from command line arguments
|
||||
mut v := compiler.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()
|
||||
v.run_compiled_executable_and_exit()
|
||||
}
|
||||
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 {
|
||||
v.run_compiled_executable_and_exit()
|
||||
}
|
||||
v.finalize_compilation()
|
||||
}
|
||||
|
||||
fn v_command(command string, args []string) {
|
||||
match command {
|
||||
'', '.', 'run', 'build' {
|
||||
// handled later in vlib/compiler/main.v
|
||||
return
|
||||
}
|
||||
'version' {
|
||||
println('V $compiler.Version $compiler.vhash()')
|
||||
}
|
||||
'help' {
|
||||
println(compiler.help_text)
|
||||
}
|
||||
'translate' {
|
||||
println('Translating C to V will be available in V 0.3 (January)')
|
||||
}
|
||||
'search', 'install', 'update', 'remove' {
|
||||
compiler.launch_tool('vpm', command)
|
||||
}
|
||||
'get' {
|
||||
println('use `v install` to install modules from vpm.vlang.io ')
|
||||
}
|
||||
'symlink' {
|
||||
compiler.create_symlink()
|
||||
}
|
||||
'runrepl' {
|
||||
// TODO: remove this after 2020/02/01
|
||||
eprintln('`v runrepl` has been deprecated. Please use `v repl` instead.')
|
||||
compiler.launch_tool('vrepl', 'runrepl')
|
||||
}
|
||||
'doc' {
|
||||
vexe := os.executable()
|
||||
vdir := filepath.dir(os.executable())
|
||||
os.chdir(vdir)
|
||||
mod := args.last()
|
||||
os.system('$vexe build module vlib$os.path_separator' + args.last())
|
||||
vhfile := filepath.join(compiler.v_modules_path,'vlib','${mod}.vh')
|
||||
txt := os.read_file(vhfile) or {
|
||||
panic(err)
|
||||
}
|
||||
println(txt)
|
||||
// v.gen_doc_html_for_module(args.last())
|
||||
}
|
||||
else {
|
||||
eprintln('v $command: unknown command\nRun "v help" for usage.')
|
||||
exit(1)
|
||||
}
|
||||
}
|
||||
exit(0)
|
||||
}
|
|
@ -166,8 +166,8 @@ fn (v mut V) new_parser_from_file(path string) Parser {
|
|||
}
|
||||
}
|
||||
|
||||
if v.compile_defines.len > 0 {
|
||||
for cdefine in v.compile_defines {
|
||||
if v.pref.compile_defines.len > 0 {
|
||||
for cdefine in v.pref.compile_defines {
|
||||
custom_path_ending := '_d_${cdefine}.v'
|
||||
if path.ends_with(custom_path_ending){
|
||||
path_platform = custom_path_ending
|
||||
|
@ -215,8 +215,8 @@ fn (v mut V) new_parser(scanner &Scanner) Parser {
|
|||
cgen: v.cgen
|
||||
//x64: v.x64
|
||||
pref: v.pref
|
||||
os: v.os
|
||||
vroot: v.vroot
|
||||
os: v.pref.os
|
||||
vroot: v.pref.vroot
|
||||
local_vars: [Var{
|
||||
}].repeat(MaxLocalVars)
|
||||
import_table: new_import_table()
|
||||
|
@ -443,7 +443,7 @@ fn (p mut Parser) parse(pass Pass) {
|
|||
//
|
||||
p.fgen_nl()
|
||||
p.cgen.nogen = false
|
||||
if p.pref.build_mode == .build_module && p.mod != p.v.mod {
|
||||
if p.pref.build_mode == .build_module && p.mod != p.v.pref.mod {
|
||||
// println('skipping $p.mod (v.mod = $p.v.mod)')
|
||||
p.cgen.nogen = true
|
||||
// defer { p.cgen.nogen = false }
|
||||
|
@ -453,7 +453,7 @@ fn (p mut Parser) parse(pass Pass) {
|
|||
p.can_chash = p.mod in ['gg2', 'ui', 'uiold', 'darwin', 'clipboard', 'webview'] // TODO tmp remove
|
||||
// Import pass - the first and the smallest pass that only analyzes imports
|
||||
// if we are a building module get the full module name from v.mod
|
||||
fq_mod := if p.pref.build_mode == .build_module && p.v.mod.ends_with(p.mod) { p.v.mod }
|
||||
fq_mod := if p.pref.build_mode == .build_module && p.v.pref.mod.ends_with(p.mod) { p.v.pref.mod }
|
||||
// fully qualify the module name, eg base64 to encoding.base64
|
||||
else { p.table.qualify_module(p.mod, p.file_path) }
|
||||
p.table.register_module(fq_mod)
|
||||
|
|
|
@ -5,9 +5,9 @@ module compiler
|
|||
|
||||
import (
|
||||
os
|
||||
os.cmdline
|
||||
time
|
||||
filepath
|
||||
v.pref
|
||||
)
|
||||
|
||||
fn todo() {
|
||||
|
@ -34,8 +34,8 @@ fn (v mut V) cc() {
|
|||
vdir := filepath.dir(vexe)
|
||||
// Just create a C/JavaScript file and exit
|
||||
// for example: `v -o v.c compiler`
|
||||
ends_with_c := v.out_name.ends_with('.c')
|
||||
ends_with_js := v.out_name.ends_with('.js')
|
||||
ends_with_c := v.pref.out_name.ends_with('.c')
|
||||
ends_with_js := v.pref.out_name.ends_with('.js')
|
||||
|
||||
if v.pref.is_pretty_c && !ends_with_js {
|
||||
format_result := os.exec('clang-format -i -style=file "$v.out_name_c"') or {
|
||||
|
@ -59,7 +59,7 @@ fn (v mut V) cc() {
|
|||
println('V.js compiler not found, building...')
|
||||
// Build V.js. Specifying `-os js` makes V include
|
||||
// only _js.v files and ignore _c.v files.
|
||||
ret := os.system('$vexe -o $vjs_path -os js $vdir/v.v')
|
||||
ret := os.system('$vexe -o $vjs_path -os js $vdir/cmd/v')
|
||||
if ret == 0 {
|
||||
println('Done.')
|
||||
}
|
||||
|
@ -68,21 +68,21 @@ fn (v mut V) cc() {
|
|||
exit(1)
|
||||
}
|
||||
}
|
||||
ret := os.system('$vjs_path -o $v.out_name $v.dir')
|
||||
ret := os.system('$vjs_path -o $v.pref.out_name $v.pref.path')
|
||||
if ret == 0 {
|
||||
println('Done. Run it with `node $v.out_name`')
|
||||
println('Done. Run it with `node $v.pref.out_name`')
|
||||
println('JS backend is at a very early stage.')
|
||||
}
|
||||
}
|
||||
}
|
||||
// v.out_name_c may be on a different partition than v.out_name
|
||||
os.mv_by_cp(v.out_name_c, v.out_name)or{
|
||||
os.mv_by_cp(v.out_name_c, v.pref.out_name)or{
|
||||
panic(err)
|
||||
}
|
||||
exit(0)
|
||||
}
|
||||
// Cross compiling for Windows
|
||||
if v.os == .windows {
|
||||
if v.pref.os == .windows {
|
||||
$if !windows {
|
||||
v.cc_windows_cross()
|
||||
return
|
||||
|
@ -136,29 +136,29 @@ fn (v mut V) cc() {
|
|||
if !v.pref.is_so
|
||||
&& v.pref.build_mode != .build_module
|
||||
&& os.user_os() == 'windows'
|
||||
&& !v.out_name.ends_with('.exe')
|
||||
&& !v.pref.out_name.ends_with('.exe')
|
||||
{
|
||||
v.out_name += '.exe'
|
||||
v.pref.out_name += '.exe'
|
||||
}
|
||||
|
||||
// linux_host := os.user_os() == 'linux'
|
||||
v.log('cc() isprod=$v.pref.is_prod outname=$v.out_name')
|
||||
v.log('cc() isprod=$v.pref.is_prod outname=$v.pref.out_name')
|
||||
if v.pref.is_so {
|
||||
a << '-shared -fPIC ' // -Wl,-z,defs'
|
||||
v.out_name = v.out_name + '.so'
|
||||
v.pref.out_name += '.so'
|
||||
}
|
||||
if v.pref.is_bare {
|
||||
a << '-fno-stack-protector -static -ffreestanding -nostdlib'
|
||||
}
|
||||
if v.pref.build_mode == .build_module {
|
||||
// Create the modules & out directory if it's not there.
|
||||
mut out_dir := if v.dir.starts_with('vlib') { '$v_modules_path${os.path_separator}cache${os.path_separator}$v.dir' } else { '$v_modules_path${os.path_separator}$v.dir' }
|
||||
mut out_dir := if v.pref.path.starts_with('vlib') { '$v_modules_path${os.path_separator}cache${os.path_separator}$v.pref.path' } else { '$v_modules_path${os.path_separator}$v.pref.path' }
|
||||
pdir := out_dir.all_before_last(os.path_separator)
|
||||
if !os.is_dir(pdir) {
|
||||
os.mkdir_all(pdir)
|
||||
}
|
||||
v.out_name = '${out_dir}.o' // v.out_name
|
||||
println('Building ${v.out_name}...')
|
||||
v.pref.out_name = '${out_dir}.o' // v.out_name
|
||||
println('Building ${v.pref.out_name}...')
|
||||
}
|
||||
debug_mode := v.pref.is_debug
|
||||
mut debug_options := '-g'
|
||||
|
@ -198,7 +198,7 @@ fn (v mut V) cc() {
|
|||
if debug_mode && os.user_os() != 'windows' {
|
||||
a << ' -rdynamic ' // needed for nicer symbolic backtraces
|
||||
}
|
||||
if v.pref.ccompiler != 'msvc' && v.os != .freebsd {
|
||||
if v.pref.ccompiler != 'msvc' && v.pref.os != .freebsd {
|
||||
a << '-Werror=implicit-function-declaration'
|
||||
}
|
||||
for f in v.generate_hotcode_reloading_compiler_flags() {
|
||||
|
@ -269,24 +269,24 @@ fn (v mut V) cc() {
|
|||
// Cross compiling windows
|
||||
//
|
||||
// Output executable name
|
||||
a << '-o "$v.out_name"'
|
||||
if os.is_dir(v.out_name) {
|
||||
verror("\'$v.out_name\' is a directory")
|
||||
a << '-o "$v.pref.out_name"'
|
||||
if os.is_dir(v.pref.out_name) {
|
||||
verror("\'$v.pref.out_name\' is a directory")
|
||||
}
|
||||
// macOS code can include objective C TODO remove once objective C is replaced with C
|
||||
if v.os == .mac {
|
||||
if v.pref.os == .mac {
|
||||
a << '-x objective-c'
|
||||
}
|
||||
// The C file we are compiling
|
||||
a << '"$v.out_name_c"'
|
||||
if v.os == .mac {
|
||||
if v.pref.os == .mac {
|
||||
a << '-x none'
|
||||
}
|
||||
// Min macos version is mandatory I think?
|
||||
if v.os == .mac {
|
||||
if v.pref.os == .mac {
|
||||
a << '-mmacosx-version-min=10.7'
|
||||
}
|
||||
if v.os == .windows {
|
||||
if v.pref.os == .windows {
|
||||
a << '-municode'
|
||||
}
|
||||
cflags := v.get_os_cflags()
|
||||
|
@ -297,18 +297,18 @@ fn (v mut V) cc() {
|
|||
a << libs
|
||||
// Without these libs compilation will fail on Linux
|
||||
// || os.user_os() == 'linux'
|
||||
if !v.pref.is_bare && v.pref.build_mode != .build_module && v.os in [.linux, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .haiku] {
|
||||
if !v.pref.is_bare && v.pref.build_mode != .build_module && v.pref.os in [.linux, .freebsd, .openbsd, .netbsd, .dragonfly, .solaris, .haiku] {
|
||||
a << '-lm -lpthread '
|
||||
// -ldl is a Linux only thing. BSDs have it in libc.
|
||||
if v.os == .linux {
|
||||
if v.pref.os == .linux {
|
||||
a << ' -ldl '
|
||||
}
|
||||
if v.os == .freebsd {
|
||||
if v.pref.os == .freebsd {
|
||||
// FreeBSD: backtrace needs execinfo library while linking
|
||||
a << ' -lexecinfo '
|
||||
}
|
||||
}
|
||||
if !v.pref.is_bare && v.os == .js && os.user_os() == 'linux' {
|
||||
if !v.pref.is_bare && v.pref.os == .js && os.user_os() == 'linux' {
|
||||
a << '-lm'
|
||||
}
|
||||
args := a.join(' ')
|
||||
|
@ -351,6 +351,18 @@ start:
|
|||
}
|
||||
if v.pref.is_debug {
|
||||
println(res.output)
|
||||
verror("
|
||||
==================
|
||||
C error. This should never happen.
|
||||
|
||||
V compiler version: V $Version $vhash()
|
||||
Host OS: ${pref.get_host_os().str()}
|
||||
Target OS: $v.pref.os.str()
|
||||
|
||||
If you were not working with C interop and are not sure about what's happening,
|
||||
please put the whole output in a pastebin and contact us through the following ways with a link to the pastebin:
|
||||
- Raise an issue on GitHub: https://github.com/vlang/v/issues/new/choose
|
||||
- Ask a question in #help on Discord: https://discord.gg/vlang")
|
||||
}
|
||||
else {
|
||||
if res.output.len < 30 {
|
||||
|
@ -359,11 +371,19 @@ start:
|
|||
q := res.output.all_after('error: ').limit(150)
|
||||
println('==================')
|
||||
println(q)
|
||||
println('...')
|
||||
println('==================')
|
||||
println('...\n(Use `v -cg` to print the entire error message)\n')
|
||||
println('(Use `v -cg` to print the entire error message)\n')
|
||||
}
|
||||
verror("C error.
|
||||
|
||||
Please make sure that:
|
||||
- You have all V dependencies installed.
|
||||
- You did not declare a C function that was not included. (Try commenting your code that involves C interop)
|
||||
- You are running the latest version of V. (Try running `v up` and rerunning your command)
|
||||
|
||||
If you're confident that all of the above is true, please try running V with the `-cg` option which enables more debugging capabilities.\n")
|
||||
}
|
||||
verror('C error. This should never happen. ' + '\nPlease create a GitHub issue: https://github.com/vlang/v/issues/new/choose')
|
||||
}
|
||||
diff := time.ticks() - ticks
|
||||
// Print the C command
|
||||
|
@ -402,16 +422,16 @@ start:
|
|||
println('-compress does not work on Windows for now')
|
||||
return
|
||||
}
|
||||
ret := os.system('strip $v.out_name')
|
||||
ret := os.system('strip $v.pref.out_name')
|
||||
if ret != 0 {
|
||||
println('strip failed')
|
||||
return
|
||||
}
|
||||
// NB: upx --lzma can sometimes fail with NotCompressibleException
|
||||
// See https://github.com/vlang/v/pull/3528
|
||||
mut ret2 := os.system('upx --lzma -qqq $v.out_name')
|
||||
mut ret2 := os.system('upx --lzma -qqq $v.pref.out_name')
|
||||
if ret2 != 0 {
|
||||
ret2 = os.system('upx -qqq $v.out_name')
|
||||
ret2 = os.system('upx -qqq $v.pref.out_name')
|
||||
}
|
||||
if ret2 != 0 {
|
||||
println('upx failed')
|
||||
|
@ -430,10 +450,10 @@ start:
|
|||
|
||||
fn (c mut V) cc_windows_cross() {
|
||||
println('Cross compiling for Windows...')
|
||||
if !c.out_name.ends_with('.exe') {
|
||||
c.out_name = c.out_name + '.exe'
|
||||
if !c.pref.out_name.ends_with('.exe') {
|
||||
c.pref.out_name += '.exe'
|
||||
}
|
||||
mut args := '-o $c.out_name -w -L. '
|
||||
mut args := '-o $c.pref.out_name -w -L. '
|
||||
cflags := c.get_os_cflags()
|
||||
// -I flags
|
||||
args += if c.pref.ccompiler == 'msvc' { cflags.c_options_before_target_msvc() } else { cflags.c_options_before_target() }
|
||||
|
@ -509,65 +529,12 @@ fn (c &V) build_thirdparty_obj_files() {
|
|||
build_thirdparty_obj_file_with_msvc(flag.value, rest_of_module_flags)
|
||||
}
|
||||
else {
|
||||
build_thirdparty_obj_file(flag.value, rest_of_module_flags)
|
||||
c.build_thirdparty_obj_file(flag.value, rest_of_module_flags)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn find_c_compiler() string {
|
||||
args := env_vflags_and_os_args()
|
||||
defaultcc := find_c_compiler_default()
|
||||
return cmdline.option(args, '-cc', defaultcc)
|
||||
}
|
||||
|
||||
fn find_c_compiler_default() 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'
|
||||
}
|
||||
|
||||
fn find_c_compiler_thirdparty_options() string {
|
||||
fullargs := env_vflags_and_os_args()
|
||||
mut cflags := cmdline.many_values(fullargs,'-cflags')
|
||||
$if !windows {
|
||||
cflags << '-fPIC'
|
||||
}
|
||||
if '-m32' in fullargs {
|
||||
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
|
||||
}
|
||||
|
||||
fn missing_compiler_info() string {
|
||||
$if windows {
|
||||
return 'https://github.com/vlang/v/wiki/Installing-a-C-compiler-on-Windows'
|
||||
|
|
|
@ -20,12 +20,12 @@ pub fn (c &CFlag) str() string {
|
|||
fn (v &V) get_os_cflags() []CFlag {
|
||||
mut flags := []CFlag
|
||||
mut ctimedefines := []string
|
||||
if v.compile_defines.len > 0 {
|
||||
ctimedefines << v.compile_defines
|
||||
if v.pref.compile_defines.len > 0 {
|
||||
ctimedefines << v.pref.compile_defines
|
||||
}
|
||||
|
||||
for flag in v.table.cflags {
|
||||
if flag.os == '' || (flag.os == 'linux' && v.os == .linux) || (flag.os == 'darwin' && v.os == .mac) || (flag.os == 'freebsd' && v.os == .freebsd) || (flag.os == 'windows' && v.os == .windows) {
|
||||
if flag.os == '' || (flag.os == 'linux' && v.pref.os == .linux) || (flag.os == 'darwin' && v.pref.os == .mac) || (flag.os == 'freebsd' && v.pref.os == .freebsd) || (flag.os == 'windows' && v.pref.os == .windows) {
|
||||
flags << flag
|
||||
}
|
||||
if flag.os in ctimedefines {
|
||||
|
|
|
@ -43,7 +43,7 @@ mut:
|
|||
cut_pos int
|
||||
}
|
||||
|
||||
fn new_cgen(out_name_c string) &CGen {
|
||||
pub fn new_cgen(out_name_c string) &CGen {
|
||||
path := out_name_c
|
||||
out := os.create(path)or{
|
||||
println('failed to create $path')
|
||||
|
@ -272,7 +272,7 @@ fn (g mut CGen) add_to_main(s string) {
|
|||
g.fn_main = g.fn_main + s
|
||||
}
|
||||
|
||||
fn build_thirdparty_obj_file(path string, moduleflags []CFlag) {
|
||||
fn (v &V) build_thirdparty_obj_file(path string, moduleflags []CFlag) {
|
||||
obj_path := os.realpath(path)
|
||||
if os.exists(obj_path) {
|
||||
return
|
||||
|
@ -288,11 +288,9 @@ fn build_thirdparty_obj_file(path string, moduleflags []CFlag) {
|
|||
cfiles += '"' + os.realpath(parent + os.path_separator + file) + '" '
|
||||
}
|
||||
}
|
||||
cc := find_c_compiler()
|
||||
cc_thirdparty_options := find_c_compiler_thirdparty_options()
|
||||
btarget := moduleflags.c_options_before_target()
|
||||
atarget := moduleflags.c_options_after_target()
|
||||
cmd := '$cc $cc_thirdparty_options $btarget -c -o "$obj_path" $cfiles $atarget '
|
||||
cmd := '$v.pref.ccompiler $v.pref.third_party_option $btarget -c -o "$obj_path" $cfiles $atarget '
|
||||
res := os.exec(cmd)or{
|
||||
println('failed thirdparty object build cmd: $cmd')
|
||||
verror(err)
|
||||
|
|
|
@ -112,7 +112,7 @@ fn (p mut Parser) comp_time() {
|
|||
else if name == 'clang' {
|
||||
p.comptime_if_block('__clang__', not)
|
||||
}
|
||||
else if p.v.compile_defines_all.len > 0 && name in p.v.compile_defines_all {
|
||||
else if p.v.pref.compile_defines_all.len > 0 && name in p.v.pref.compile_defines_all {
|
||||
// Support for *optional* custom compile defines, i.e.:
|
||||
//
|
||||
// `[if custom]` => custom should be defined
|
||||
|
@ -249,7 +249,7 @@ fn (p mut Parser) chash() {
|
|||
flag = flag.replace('@VLIB_PATH', p.pref.vlib_path)
|
||||
flag = flag.replace('@VMOD', v_modules_path)
|
||||
// p.log('adding flag "$flag"')
|
||||
_ = p.table.parse_cflag(flag, p.mod, p.v.compile_defines_all ) or {
|
||||
_ = p.table.parse_cflag(flag, p.mod, p.v.pref.compile_defines_all ) or {
|
||||
p.error_with_token_index(err, p.cur_tok_index() - 1)
|
||||
return
|
||||
}
|
||||
|
|
|
@ -510,7 +510,7 @@ fn (p mut Parser) fn_decl() {
|
|||
}
|
||||
|
||||
if p.first_pass() && p.attr == 'live' && !(is_live || is_solive) {
|
||||
println('INFO: run `v -live $p.v.dir `, if you want to use [live] function $f.name .')
|
||||
println('INFO: run `v -live $p.v.pref.path `, if you want to use [live] function $f.name .')
|
||||
}
|
||||
|
||||
if p.is_vh || p.first_pass() || is_live || is_fn_header || skip_main_in_test {
|
||||
|
@ -774,7 +774,7 @@ fn (p mut Parser) verify_fn_before_call(f &Fn) {
|
|||
// p.tok == fn_name
|
||||
fn (p mut Parser) fn_call(f mut Fn, method_ph int, receiver_var, receiver_type string) {
|
||||
p.verify_fn_before_call(f)
|
||||
is_comptime_define := f.comptime_define != '' && !(f.comptime_define in p.v.compile_defines )
|
||||
is_comptime_define := f.comptime_define != '' && !(f.comptime_define in p.v.pref.compile_defines )
|
||||
if is_comptime_define {
|
||||
p.cgen.nogen = true
|
||||
}
|
||||
|
|
|
@ -10,10 +10,10 @@ fn (v &V) generate_hotcode_reloading_compiler_flags() []string {
|
|||
mut a := []string
|
||||
if v.pref.is_live || v.pref.is_so {
|
||||
// See 'man dlopen', and test running a GUI program compiled with -live
|
||||
if (v.os == .linux || os.user_os() == 'linux') {
|
||||
if (v.pref.os == .linux || os.user_os() == 'linux') {
|
||||
a << '-rdynamic'
|
||||
}
|
||||
if (v.os == .mac || os.user_os() == 'mac') {
|
||||
if (v.pref.os == .mac || os.user_os() == 'mac') {
|
||||
a << '-flat_namespace'
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ fn (v &V) generate_hotcode_reloading_compiler_flags() []string {
|
|||
|
||||
fn (v &V) generate_hotcode_reloading_declarations() {
|
||||
mut cgen := v.cgen
|
||||
if v.os != .windows {
|
||||
if v.pref.os != .windows {
|
||||
if v.pref.is_so {
|
||||
cgen.genln('pthread_mutex_t live_fn_mutex;')
|
||||
}
|
||||
|
@ -55,8 +55,8 @@ fn (v &V) generate_hotcode_reloading_main_caller() {
|
|||
// We are in live code reload mode, so start the .so loader in the background
|
||||
mut cgen := v.cgen
|
||||
cgen.genln('')
|
||||
file_base := filepath.filename(v.dir).replace('.v', '')
|
||||
if v.os != .windows {
|
||||
file_base := filepath.filename(v.pref.path).replace('.v', '')
|
||||
if v.pref.os != .windows {
|
||||
// unix:
|
||||
so_name := file_base + '.so'
|
||||
cgen.genln(' char *live_library_name = "$so_name";')
|
||||
|
@ -79,7 +79,7 @@ fn (v &V) generate_hot_reload_code() {
|
|||
mut cgen := v.cgen
|
||||
// Hot code reloading
|
||||
if v.pref.is_live {
|
||||
mut file := os.realpath(v.dir)
|
||||
mut file := os.realpath(v.pref.path)
|
||||
file_base := filepath.filename(file).replace('.v', '')
|
||||
so_name := file_base + '.so'
|
||||
// Need to build .so file before building the live application
|
||||
|
@ -115,7 +115,7 @@ void lfnmutex_print(char *s){
|
|||
}
|
||||
}
|
||||
')
|
||||
if v.os != .windows {
|
||||
if v.pref.os != .windows {
|
||||
cgen.genln('
|
||||
void* live_lib=0;
|
||||
int load_so(byteptr path) {
|
||||
|
|
|
@ -5,7 +5,6 @@ module compiler
|
|||
|
||||
import (
|
||||
os
|
||||
os.cmdline
|
||||
strings
|
||||
filepath
|
||||
v.pref
|
||||
|
@ -35,21 +34,15 @@ enum Pass {
|
|||
main
|
||||
}
|
||||
|
||||
struct V {
|
||||
pub struct V {
|
||||
pub mut:
|
||||
os pref.OS // the OS to build for
|
||||
out_name_c string // name of the temporary C file
|
||||
files []string // all V files that need to be parsed and compiled
|
||||
dir string // directory (or file) being compiled (TODO rename to path?)
|
||||
compiled_dir string // contains os.realpath() of the dir of the final file beeing compiled, or the dir itself when doing `v .`
|
||||
table &Table // table with types, vars, functions etc
|
||||
cgen &CGen // C code generator
|
||||
//x64 &x64.Gen
|
||||
pref &pref.Preferences // all the preferences and settings extracted to a struct for reusability
|
||||
lang_dir string // "~/code/v"
|
||||
out_name string // "program.exe"
|
||||
vroot string
|
||||
mod string // module being built with -lib
|
||||
parsers []Parser // file parsers
|
||||
vgen_buf strings.Builder // temporary buffer for generated V code (.str() etc)
|
||||
file_parser_idx map[string]int // map absolute file path to v.parsers index
|
||||
|
@ -57,15 +50,33 @@ pub mut:
|
|||
cached_mods []string
|
||||
module_lookup_paths []string
|
||||
|
||||
// -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']
|
||||
|
||||
v_fmt_all bool // << input set by tools/vfmt.v
|
||||
v_fmt_file string // << file given by the user from tools/vfmt.v
|
||||
v_fmt_all bool // << input set by cmd/tools/vfmt.v
|
||||
v_fmt_file string // << file given by the user from cmd/tools/vfmt.v
|
||||
v_fmt_file_result string // >> file with formatted output generated by vlib/compiler/vfmt.v
|
||||
}
|
||||
|
||||
pub fn new_v(pref &pref.Preferences) &V {
|
||||
rdir := os.realpath(pref.path)
|
||||
|
||||
mut out_name_c := get_vtmp_filename(pref.out_name, '.tmp.c')
|
||||
if pref.is_so {
|
||||
out_name_c = get_vtmp_filename(pref.out_name, '.tmp.so.c')
|
||||
}
|
||||
|
||||
mut vgen_buf := strings.new_builder(1000)
|
||||
vgen_buf.writeln('module vgen\nimport strings')
|
||||
|
||||
return &V{
|
||||
compiled_dir: if os.is_dir(rdir) { rdir } else { filepath.dir(rdir) }
|
||||
table: new_table(pref.obfuscate)
|
||||
out_name_c: out_name_c
|
||||
cgen: new_cgen(out_name_c)
|
||||
//x64: x64.new_gen(out_name)
|
||||
pref: pref
|
||||
vgen_buf: vgen_buf
|
||||
}
|
||||
}
|
||||
|
||||
// Should be called by main at the end of the compilation process, to cleanup
|
||||
pub fn (v &V) finalize_compilation() {
|
||||
// TODO remove
|
||||
|
@ -166,7 +177,7 @@ pub fn (v mut V) compile() {
|
|||
if v.pref.prealloc {
|
||||
cgen.genln('#define VPREALLOC (1)')
|
||||
}
|
||||
if v.os == .js {
|
||||
if v.pref.os == .js {
|
||||
cgen.genln('#define _VJS (1) ')
|
||||
}
|
||||
v_hash := vhash()
|
||||
|
@ -189,11 +200,11 @@ pub fn (v mut V) compile() {
|
|||
cgen.genln('#include <stdint.h>')
|
||||
}
|
||||
|
||||
if v.compile_defines_all.len > 0 {
|
||||
if v.pref.compile_defines_all.len > 0 {
|
||||
cgen.genln('')
|
||||
cgen.genln('// All custom defines : ' + v.compile_defines_all.join(','))
|
||||
cgen.genln('// Turned ON custom defines: ' + v.compile_defines.join(','))
|
||||
for cdefine in v.compile_defines {
|
||||
cgen.genln('// All custom defines : ' + v.pref.compile_defines_all.join(','))
|
||||
cgen.genln('// Turned ON custom defines: ' + v.pref.compile_defines.join(','))
|
||||
for cdefine in v.pref.compile_defines {
|
||||
cgen.genln('#define CUSTOM_DEFINE_${cdefine}')
|
||||
}
|
||||
cgen.genln('//')
|
||||
|
@ -234,7 +245,7 @@ pub fn (v mut V) compile() {
|
|||
if '-debug_alloc' in os.args {
|
||||
cgen.genln('#define DEBUG_ALLOC 1')
|
||||
}
|
||||
if v.pref.is_live && v.os != .windows {
|
||||
if v.pref.is_live && v.pref.os != .windows {
|
||||
cgen.includes << '#include <dlfcn.h>'
|
||||
}
|
||||
// cgen.genln('/*================================== FNS =================================*/')
|
||||
|
@ -261,7 +272,7 @@ pub fn (v mut V) compile() {
|
|||
vgen_parser.parse(.main)
|
||||
// Generate .vh if we are building a module
|
||||
if v.pref.build_mode == .build_module {
|
||||
generate_vh(v.dir)
|
||||
generate_vh(v.pref.path)
|
||||
}
|
||||
// All definitions
|
||||
mut def := strings.new_builder(10000) // Avoid unnecessary allocations
|
||||
|
@ -319,7 +330,7 @@ pub fn (v mut V) compile2() {
|
|||
println(v.files)
|
||||
}
|
||||
mut b := v.new_v2()
|
||||
b.build_c(v.files, v.out_name)
|
||||
b.build_c(v.files, v.pref.out_name)
|
||||
v.cc()
|
||||
}
|
||||
|
||||
|
@ -329,18 +340,18 @@ pub fn (v mut V) compile_x64() {
|
|||
println('You are not on a Linux system, so you will not ' + 'be able to run the resulting executable')
|
||||
}
|
||||
//v.files << v.v_files_from_dir(filepath.join(v.pref.vlib_path,'builtin','bare'))
|
||||
v.files << v.dir
|
||||
v.files << v.pref.path
|
||||
v.set_module_lookup_paths()
|
||||
mut b := v.new_v2()
|
||||
// move all this logic to v2
|
||||
b.build_x64(v.files, v.out_name)
|
||||
b.build_x64(v.files, v.pref.out_name)
|
||||
}
|
||||
|
||||
// make v2 from v1
|
||||
fn (v &V) new_v2() builder.Builder {
|
||||
mut b := builder.new_builder(v.pref)
|
||||
b = { b|
|
||||
os: v.os,
|
||||
os: v.pref.os,
|
||||
module_path: v_modules_path,
|
||||
compiled_dir: v.compiled_dir,
|
||||
module_search_paths: v.module_lookup_paths
|
||||
|
@ -356,7 +367,7 @@ fn (v mut V) generate_init() {
|
|||
nogen := v.cgen.nogen
|
||||
v.cgen.nogen = false
|
||||
consts_init_body := v.cgen.consts_init.join_lines()
|
||||
init_fn_name := mod_gen_name(v.mod) + '__init_consts'
|
||||
init_fn_name := mod_gen_name(v.pref.mod) + '__init_consts'
|
||||
v.cgen.genln('void ${init_fn_name}();\nvoid ${init_fn_name}() {\n$consts_init_body\n}')
|
||||
v.cgen.nogen = nogen
|
||||
}
|
||||
|
@ -482,7 +493,7 @@ pub fn (v mut V) generate_main() {
|
|||
// Generate a C `main`, which calls every single test function
|
||||
v.gen_main_start(false)
|
||||
if v.pref.is_stats {
|
||||
cgen.genln('BenchedTests bt = main__start_testing(${test_fn_names.len},tos3("$v.dir"));')
|
||||
cgen.genln('BenchedTests bt = main__start_testing(${test_fn_names.len},tos3("$v.pref.path"));')
|
||||
}
|
||||
for tfname in test_fn_names {
|
||||
if v.pref.is_stats {
|
||||
|
@ -513,7 +524,7 @@ pub fn (v mut V) generate_main() {
|
|||
}
|
||||
|
||||
pub fn (v mut V) gen_main_start(add_os_args bool) {
|
||||
if v.os == .windows {
|
||||
if v.pref.os == .windows {
|
||||
if 'glfw' in v.table.imports {
|
||||
// GUI application
|
||||
v.cgen.genln('int WINAPI wWinMain(HINSTANCE instance, HINSTANCE prev_instance, LPWSTR cmd_line, int show_cmd) { ')
|
||||
|
@ -531,7 +542,7 @@ pub fn (v mut V) gen_main_start(add_os_args bool) {
|
|||
}
|
||||
v.cgen.genln(' init();')
|
||||
if add_os_args && 'os' in v.table.imports {
|
||||
if v.os == .windows {
|
||||
if v.pref.os == .windows {
|
||||
v.cgen.genln(' os__args = os__init_os_args_wide(argc, argv);')
|
||||
} else {
|
||||
v.cgen.genln(' os__args = os__init_os_args(argc, (byteptr*)argv);')
|
||||
|
@ -547,45 +558,12 @@ pub fn (v mut V) gen_main_end(return_statement string) {
|
|||
v.cgen.genln('}')
|
||||
}
|
||||
|
||||
pub fn final_target_out_name(out_name string) string {
|
||||
$if windows {
|
||||
return out_name.replace('/', '\\') + '.exe'
|
||||
}
|
||||
return if out_name.starts_with('/') { out_name } else { './' + out_name }
|
||||
}
|
||||
|
||||
pub fn (v V) run_compiled_executable_and_exit() {
|
||||
args := env_vflags_and_os_args()
|
||||
if v.pref.is_verbose {
|
||||
println('============ running $v.out_name ============')
|
||||
}
|
||||
mut cmd := '"' + final_target_out_name(v.out_name).replace('.exe', '') + '"'
|
||||
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)
|
||||
}
|
||||
|
||||
pub fn (v &V) v_files_from_dir(dir string) []string {
|
||||
mut res := []string
|
||||
if !os.exists(dir) {
|
||||
if dir == 'compiler' && os.is_dir('vlib') {
|
||||
println('looks like you are trying to build V with an old command')
|
||||
println('use `v -o v v.v` instead of `v -o v compiler`')
|
||||
println('use `v -o v cmd/v` instead of `v -o v compiler`')
|
||||
}
|
||||
verror("$dir doesn't exist")
|
||||
}
|
||||
|
@ -606,27 +584,27 @@ pub fn (v &V) v_files_from_dir(dir string) []string {
|
|||
if file.ends_with('_test.v') {
|
||||
continue
|
||||
}
|
||||
if (file.ends_with('_win.v') || file.ends_with('_windows.v')) && v.os != .windows {
|
||||
if (file.ends_with('_win.v') || file.ends_with('_windows.v')) && v.pref.os != .windows {
|
||||
continue
|
||||
}
|
||||
if (file.ends_with('_lin.v') || file.ends_with('_linux.v')) && v.os != .linux {
|
||||
if (file.ends_with('_lin.v') || file.ends_with('_linux.v')) && v.pref.os != .linux {
|
||||
continue
|
||||
}
|
||||
if (file.ends_with('_mac.v') || file.ends_with('_darwin.v')) && v.os != .mac {
|
||||
if (file.ends_with('_mac.v') || file.ends_with('_darwin.v')) && v.pref.os != .mac {
|
||||
continue
|
||||
}
|
||||
if file.ends_with('_nix.v') && v.os == .windows {
|
||||
if file.ends_with('_nix.v') && v.pref.os == .windows {
|
||||
continue
|
||||
}
|
||||
if file.ends_with('_js.v') && v.os != .js {
|
||||
if file.ends_with('_js.v') && v.pref.os != .js {
|
||||
continue
|
||||
}
|
||||
if file.ends_with('_c.v') && v.os == .js {
|
||||
if file.ends_with('_c.v') && v.pref.os == .js {
|
||||
continue
|
||||
}
|
||||
if v.compile_defines_all.len > 0 && file.contains('_d_') {
|
||||
if v.pref.compile_defines_all.len > 0 && file.contains('_d_') {
|
||||
mut allowed := false
|
||||
for cdefine in v.compile_defines {
|
||||
for cdefine in v.pref.compile_defines {
|
||||
file_postfix := '_d_${cdefine}.v'
|
||||
if file.ends_with(file_postfix) {
|
||||
allowed = true
|
||||
|
@ -740,15 +718,15 @@ pub fn (v &V) get_builtin_files() []string {
|
|||
|
||||
// get user files
|
||||
pub fn (v &V) get_user_files() []string {
|
||||
mut dir := v.dir
|
||||
mut dir := v.pref.path
|
||||
v.log('get_v_files($dir)')
|
||||
// Need to store user files separately, because they have to be added after
|
||||
// libs, but we dont know which libs need to be added yet
|
||||
mut user_files := []string
|
||||
|
||||
// See tools/preludes/README.md for more info about what preludes are
|
||||
// See cmd/tools/preludes/README.md for more info about what preludes are
|
||||
vroot := filepath.dir(vexe_path())
|
||||
preludes_path := filepath.join(vroot,'tools','preludes')
|
||||
preludes_path := filepath.join(vroot,'cmd','tools','preludes')
|
||||
if v.pref.is_live {
|
||||
user_files << filepath.join(preludes_path,'live_main.v')
|
||||
}
|
||||
|
@ -858,284 +836,6 @@ pub fn (v &V) log(s string) {
|
|||
println(s)
|
||||
}
|
||||
|
||||
pub fn new_v(args []string) &V {
|
||||
// Create modules dirs if they are missing
|
||||
if !os.is_dir(v_modules_path) {
|
||||
os.mkdir(v_modules_path)or{
|
||||
panic(err)
|
||||
}
|
||||
os.mkdir('$v_modules_path${os.path_separator}cache')or{
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
// optional, custom modules search path
|
||||
user_mod_path := cmdline.option(args, '-user_mod_path', '')
|
||||
// Location of all vlib files
|
||||
vroot := filepath.dir(vexe_path())
|
||||
vlib_path := cmdline.option(args, '-vlib-path', filepath.join(vroot,'vlib'))
|
||||
vpath := cmdline.option(args, '-vpath', v_modules_path)
|
||||
mut vgen_buf := strings.new_builder(1000)
|
||||
vgen_buf.writeln('module vgen\nimport strings')
|
||||
target_os := cmdline.option(args, '-os', '')
|
||||
mut out_name := cmdline.option(args, '-o', 'a.out')
|
||||
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.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')
|
||||
}
|
||||
*/
|
||||
|
||||
}
|
||||
is_test := dir.ends_with('_test.v')
|
||||
is_script := dir.ends_with('.v') || dir.ends_with('.vsh')
|
||||
if is_script && !os.exists(dir) {
|
||||
println('`$dir` does not exist')
|
||||
exit(1)
|
||||
}
|
||||
// No -o provided? foo.v => foo
|
||||
if out_name == 'a.out' && dir.ends_with('.v') && dir != '.v' {
|
||||
out_name = dir[..dir.len - 2]
|
||||
// Building V? Use v2, since we can't overwrite a running
|
||||
// executable on Windows + the precompiled V is more
|
||||
// optimized.
|
||||
if out_name == 'v' && os.is_dir('vlib/compiler') {
|
||||
println('Saving the resulting V executable in `./v2`')
|
||||
println('Use `v -o v v.v` if you want to replace current ' + 'V executable.')
|
||||
out_name = 'v2'
|
||||
}
|
||||
}
|
||||
// if we are in `/foo` and run `v .`, the executable should be `foo`
|
||||
if dir == '.' && out_name == 'a.out' {
|
||||
base := os.getwd().all_after(os.path_separator)
|
||||
out_name = base.trim_space()
|
||||
}
|
||||
// `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)
|
||||
}
|
||||
}
|
||||
}
|
||||
mut _os := pref.OS.mac
|
||||
// No OS specifed? Use current system
|
||||
if target_os == '' {
|
||||
$if linux {
|
||||
_os = .linux
|
||||
}
|
||||
$if macos {
|
||||
_os = .mac
|
||||
}
|
||||
$if windows {
|
||||
_os = .windows
|
||||
}
|
||||
$if freebsd {
|
||||
_os = .freebsd
|
||||
}
|
||||
$if openbsd {
|
||||
_os = .openbsd
|
||||
}
|
||||
$if netbsd {
|
||||
_os = .netbsd
|
||||
}
|
||||
$if dragonfly {
|
||||
_os = .dragonfly
|
||||
}
|
||||
$if solaris {
|
||||
_os = .solaris
|
||||
}
|
||||
$if haiku {
|
||||
_os = .haiku
|
||||
}
|
||||
}
|
||||
else {
|
||||
_os = os_from_string(target_os)
|
||||
}
|
||||
// println('VROOT=$vroot')
|
||||
// v.exe's parent directory should contain vlib
|
||||
if !os.is_dir(vlib_path) || !os.is_dir(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=$vlib_path vexe_path=${vexe_path()}')
|
||||
exit(1)
|
||||
}
|
||||
mut out_name_c := get_vtmp_filename(out_name, '.tmp.c')
|
||||
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 {
|
||||
verror('use -freestanding instead of -bare')
|
||||
}
|
||||
obfuscate := '-obf' in args
|
||||
is_repl := '-repl' in args
|
||||
pref := &pref.Preferences{
|
||||
is_test: is_test
|
||||
is_script: is_script
|
||||
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: obfuscate
|
||||
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: find_c_compiler()
|
||||
building_v: !is_repl && (rdir_name == 'compiler' || rdir_name == 'v.v' || rdir_name == 'vfmt.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
|
||||
}
|
||||
if pref.is_verbose || pref.is_debug {
|
||||
println('C compiler=$pref.ccompiler')
|
||||
}
|
||||
if pref.is_so {
|
||||
out_name_c = get_vtmp_filename(out_name, '.tmp.so.c')
|
||||
}
|
||||
$if !linux {
|
||||
if pref.is_bare && !out_name.ends_with('.c') {
|
||||
verror('-freestanding only works on Linux for now')
|
||||
}
|
||||
}
|
||||
return &V{
|
||||
os: _os
|
||||
out_name: out_name
|
||||
dir: dir
|
||||
compiled_dir: if os.is_dir(rdir) { rdir } else { filepath.dir(rdir) }
|
||||
lang_dir: vroot
|
||||
table: new_table(obfuscate)
|
||||
out_name_c: out_name_c
|
||||
cgen: new_cgen(out_name_c)
|
||||
//x64: x64.new_gen(out_name)
|
||||
vroot: vroot
|
||||
pref: pref
|
||||
mod: mod
|
||||
vgen_buf: vgen_buf
|
||||
compile_defines: compile_defines
|
||||
compile_defines_all: compile_defines_all
|
||||
}
|
||||
}
|
||||
|
||||
fn non_empty(a []string) []string {
|
||||
return a.filter(it.len != 0)
|
||||
}
|
||||
|
||||
pub fn env_vflags_and_os_args() []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..]
|
||||
}
|
||||
}
|
||||
else {
|
||||
args << os.args
|
||||
}
|
||||
return non_empty(args)
|
||||
}
|
||||
|
||||
pub 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.')
|
||||
}
|
||||
}
|
||||
|
||||
pub fn vexe_path() string {
|
||||
vexe := os.getenv('VEXE')
|
||||
if '' != vexe {
|
||||
|
@ -1223,12 +923,3 @@ pub fn set_vroot_folder(vroot_path string) {
|
|||
vname := if os.user_os() == 'windows' { 'v.exe' } else { 'v' }
|
||||
os.setenv('VEXE', os.realpath([vroot_path, vname].join(os.path_separator)), true)
|
||||
}
|
||||
|
||||
pub fn new_v_compiler_with_args(args []string) &V {
|
||||
vexe := vexe_path()
|
||||
mut allargs := [vexe]
|
||||
allargs << args
|
||||
os.setenv('VOSARGS', allargs.join(' '), true)
|
||||
return new_v(allargs)
|
||||
}
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
strings
|
||||
os
|
||||
filepath
|
||||
v.pref
|
||||
)
|
||||
/*
|
||||
.vh generation logic.
|
||||
|
@ -52,7 +53,11 @@ fn generate_vh(mod string) {
|
|||
filtered := vfiles.filter(it.ends_with('.v') && !it.ends_with('test.v') && !it.ends_with('_windows.v') && !it.ends_with('_win.v') && !it.ends_with('_lin.v') && !it.contains('${os.path_separator}examples') && !it.contains('_js.v') && !it.contains('_bare.v') && !it.contains('${os.path_separator}js')) // TODO merge once filter allows it
|
||||
// println('f:')
|
||||
// println(filtered)
|
||||
mut v := new_v(['foo.v'])
|
||||
mut pref := &pref.Preferences {
|
||||
path: 'foo.v'
|
||||
}
|
||||
pref.fill_with_defaults()
|
||||
mut v := new_v(pref)
|
||||
// v.pref.generating_vh = true
|
||||
mut g := VhGen{
|
||||
consts: strings.new_builder(1000)
|
||||
|
@ -166,4 +171,3 @@ fn (g mut VhGen) generate_type() {
|
|||
// g.i = old
|
||||
// g.i--
|
||||
}
|
||||
|
||||
|
|
|
@ -3,11 +3,14 @@
|
|||
// that can be found in the LICENSE file.
|
||||
module compiler
|
||||
|
||||
import os
|
||||
import filepath
|
||||
import (
|
||||
filepath
|
||||
os
|
||||
v.pref
|
||||
)
|
||||
|
||||
pub const (
|
||||
v_modules_path = os.home_dir() + '.vmodules'
|
||||
v_modules_path = pref.default_module_path
|
||||
)
|
||||
// Holds import information scoped to the parsed file
|
||||
struct ImportTable {
|
||||
|
|
|
@ -206,16 +206,16 @@ pub fn (v mut V) cc_msvc() {
|
|||
a << '/MDd'
|
||||
}
|
||||
if v.pref.is_so {
|
||||
if !v.out_name.ends_with('.dll') {
|
||||
v.out_name = v.out_name + '.dll'
|
||||
if !v.pref.out_name.ends_with('.dll') {
|
||||
v.pref.out_name += '.dll'
|
||||
}
|
||||
// Build dll
|
||||
a << '/LD'
|
||||
}
|
||||
else if !v.out_name.ends_with('.exe') {
|
||||
v.out_name = v.out_name + '.exe'
|
||||
else if !v.pref.out_name.ends_with('.exe') {
|
||||
v.pref.out_name += '.exe'
|
||||
}
|
||||
v.out_name = os.realpath(v.out_name)
|
||||
v.pref.out_name = os.realpath(v.pref.out_name)
|
||||
// alibs := []string // builtin.o os.o http.o etc
|
||||
if v.pref.build_mode == .build_module {
|
||||
// Compile only
|
||||
|
@ -263,7 +263,7 @@ pub fn (v mut V) cc_msvc() {
|
|||
a << real_libs.join(' ')
|
||||
a << '/link'
|
||||
a << '/NOLOGO'
|
||||
a << '/OUT:"$v.out_name"'
|
||||
a << '/OUT:"$v.pref.out_name"'
|
||||
a << '/LIBPATH:"$r.ucrt_lib_path"'
|
||||
a << '/LIBPATH:"$r.um_lib_path"'
|
||||
a << '/LIBPATH:"$r.vs_lib_path"'
|
||||
|
|
|
@ -6,7 +6,7 @@ module compiler
|
|||
import os
|
||||
import filepath
|
||||
|
||||
pub fn get_vtmp_folder() string {
|
||||
fn get_vtmp_folder() string {
|
||||
vtmp := filepath.join(os.tmpdir(),'v')
|
||||
if !os.is_dir(vtmp) {
|
||||
os.mkdir(vtmp)or{
|
||||
|
@ -16,7 +16,7 @@ pub fn get_vtmp_folder() string {
|
|||
return vtmp
|
||||
}
|
||||
|
||||
pub fn get_vtmp_filename(base_file_name string, postfix string) string {
|
||||
fn get_vtmp_filename(base_file_name string, postfix string) string {
|
||||
vtmp := get_vtmp_folder()
|
||||
return os.realpath(filepath.join(vtmp,filepath.filename(os.realpath(base_file_name)) + postfix))
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
// branch prediction hints. the C version will be
|
||||
// removed once the perfomance is matched.
|
||||
// you can test performance by running:
|
||||
// `v run tools/bench/wyhash.v`
|
||||
// `v run cmd/tools/bench/wyhash.v`
|
||||
// try running with and without the `-prod` flag
|
||||
module wyhash
|
||||
|
||||
|
|
|
@ -102,7 +102,7 @@ pub fn (b &Builder) v_files_from_dir(dir string) []string {
|
|||
if !os.exists(dir) {
|
||||
if dir == 'compiler' && os.is_dir('vlib') {
|
||||
println('looks like you are trying to build V with an old command')
|
||||
println('use `v -o v v.v` instead of `v -o v compiler`')
|
||||
println('use `v -o v cmd/v` instead of `v -o v compiler`')
|
||||
}
|
||||
verror("$dir doesn't exist")
|
||||
}
|
||||
|
|
|
@ -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 pref
|
||||
|
||||
import (
|
||||
filepath
|
||||
os
|
||||
)
|
||||
|
||||
pub const (
|
||||
default_module_path = os.home_dir() + '.vmodules'
|
||||
)
|
||||
|
||||
pub fn (p mut Preferences) fill_with_defaults() {
|
||||
if p.vroot == '' {
|
||||
// Location of all vlib files
|
||||
p.vroot = filepath.dir(vexe_path())
|
||||
}
|
||||
if p.vlib_path == '' {
|
||||
p.vlib_path = filepath.join(p.vroot,'vlib')
|
||||
}
|
||||
if p.vpath == '' {
|
||||
p.vpath = default_module_path
|
||||
}
|
||||
if p.out_name == ''{
|
||||
rpath := os.realpath(p.path)
|
||||
filename := filepath.filename(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 { filepath.dir(rpath) }
|
||||
p.out_name = filepath.join(target_dir, base)
|
||||
|
||||
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'
|
||||
}
|
||||
}
|
||||
if p.os == ._auto {
|
||||
// No OS specifed? Use current system
|
||||
p.os = get_host_os()
|
||||
}
|
||||
if p.ccompiler == '' {
|
||||
p.ccompiler = default_c_compiler()
|
||||
}
|
||||
p.is_test = p.path.ends_with('_test.v')
|
||||
p.is_script = p.path.ends_with('.v') || p.path.ends_with('.vsh')
|
||||
}
|
||||
|
||||
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'
|
||||
}
|
||||
|
||||
//TODO Remove code duplication
|
||||
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
|
||||
}
|
|
@ -0,0 +1,147 @@
|
|||
// 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 pref
|
||||
|
||||
pub enum OS {
|
||||
_auto // Reserved so .mac cannot be misunderstood as auto
|
||||
mac
|
||||
linux
|
||||
windows
|
||||
freebsd
|
||||
openbsd
|
||||
netbsd
|
||||
dragonfly
|
||||
js // TODO
|
||||
android
|
||||
solaris
|
||||
haiku
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
'mac' {
|
||||
return .mac
|
||||
}
|
||||
'macos' {
|
||||
return .mac
|
||||
}
|
||||
'freebsd' {
|
||||
return .freebsd
|
||||
}
|
||||
'openbsd' {
|
||||
return .openbsd
|
||||
}
|
||||
'netbsd' {
|
||||
return .netbsd
|
||||
}
|
||||
'dragonfly' {
|
||||
return .dragonfly
|
||||
}
|
||||
'js' {
|
||||
return .js
|
||||
}
|
||||
'solaris' {
|
||||
return .solaris
|
||||
}
|
||||
'android' {
|
||||
return .android
|
||||
}
|
||||
'haiku' {
|
||||
return .haiku
|
||||
}
|
||||
'linux_or_macos' {
|
||||
return .linux
|
||||
}
|
||||
'' {
|
||||
return ._auto
|
||||
}
|
||||
else {
|
||||
panic('bad os $os_str')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn (o OS) str() string {
|
||||
match o {
|
||||
._auto {
|
||||
return 'RESERVED: AUTO'
|
||||
}
|
||||
.mac {
|
||||
return 'MacOS'
|
||||
}
|
||||
.linux {
|
||||
return 'Linux'
|
||||
}
|
||||
.windows {
|
||||
return 'Windows'
|
||||
}
|
||||
.freebsd {
|
||||
return 'FreeBSD'
|
||||
}
|
||||
.openbsd {
|
||||
return 'OpenBSD'
|
||||
}
|
||||
.netbsd {
|
||||
return 'NetBSD'
|
||||
}
|
||||
.dragonfly {
|
||||
return 'Dragonfly'
|
||||
}
|
||||
.js {
|
||||
return 'JavaScript'
|
||||
}
|
||||
.android {
|
||||
return 'Android'
|
||||
}
|
||||
.solaris {
|
||||
return 'Solaris'
|
||||
}
|
||||
.haiku {
|
||||
return 'Haiku'
|
||||
}
|
||||
else {
|
||||
//TODO Remove when V is smart enough to know that there's no other possibilities
|
||||
//should never be reached as all enum types have been enumerated
|
||||
panic('unknown OS enum type: $o')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_host_os() OS {
|
||||
$if linux {
|
||||
return .linux
|
||||
}
|
||||
$if macos {
|
||||
return .mac
|
||||
}
|
||||
$if windows {
|
||||
return .windows
|
||||
}
|
||||
$if freebsd {
|
||||
return .freebsd
|
||||
}
|
||||
$if openbsd {
|
||||
return .openbsd
|
||||
}
|
||||
$if netbsd {
|
||||
return .netbsd
|
||||
}
|
||||
$if dragonfly {
|
||||
return .dragonfly
|
||||
}
|
||||
$if solaris {
|
||||
return .solaris
|
||||
}
|
||||
$if haiku {
|
||||
return .haiku
|
||||
}
|
||||
panic('unknown host OS')
|
||||
}
|
|
@ -12,69 +12,66 @@ pub enum BuildMode {
|
|||
build_module
|
||||
}
|
||||
|
||||
pub enum OS {
|
||||
mac
|
||||
linux
|
||||
windows
|
||||
freebsd
|
||||
openbsd
|
||||
netbsd
|
||||
dragonfly
|
||||
js // TODO
|
||||
android
|
||||
solaris
|
||||
haiku
|
||||
}
|
||||
|
||||
pub struct Preferences {
|
||||
pub mut:
|
||||
build_mode BuildMode
|
||||
// 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_live bool // main program that contains live/hot code
|
||||
is_solive bool // a shared library, that will be used in a -live main program
|
||||
is_so bool // an ordinary shared library, -shared, no matter if it is live or not
|
||||
is_prof bool // benchmark every function
|
||||
translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc
|
||||
is_prod bool // use "-O2"
|
||||
is_verbose bool // print extra information with `v.log()`
|
||||
obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"
|
||||
is_repl bool
|
||||
is_run bool
|
||||
show_c_cmd bool // `v -show_c_cmd` prints the C command to build program.v.c
|
||||
sanitize bool // use Clang's new "-fsanitize" option
|
||||
is_debug bool // false by default, turned on by -g or -cg, it tells v to pass -g to the C backend compiler.
|
||||
is_vlines bool // turned on by -g, false by default (it slows down .tmp.c generation slightly).
|
||||
is_keep_c bool // -keep_c , tell v to leave the generated .tmp.c alone (since by default v will delete them after c backend finishes)
|
||||
os OS // the OS to compile for
|
||||
build_mode BuildMode
|
||||
// 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_live bool // main program that contains live/hot code
|
||||
is_solive bool // a shared library, that will be used in a -live main program
|
||||
is_so bool // an ordinary shared library, -shared, no matter if it is live or not
|
||||
is_prof bool // benchmark every function
|
||||
translated bool // `v translate doom.v` are we running V code translated from C? allow globals, ++ expressions, etc
|
||||
is_prod bool // use "-O2"
|
||||
is_verbose bool // print extra information with `v.log()`
|
||||
obfuscate bool // `v -obf program.v`, renames functions to "f_XXX"
|
||||
is_repl bool
|
||||
is_run bool
|
||||
show_c_cmd bool // `v -show_c_cmd` prints the C command to build program.v.c
|
||||
sanitize bool // use Clang's new "-fsanitize" option
|
||||
is_debug bool // false by default, turned on by -g or -cg, it tells v to pass -g to the C backend compiler.
|
||||
is_vlines bool // turned on by -g, false by default (it slows down .tmp.c generation slightly).
|
||||
is_keep_c bool // -keep_c , tell v to leave the generated .tmp.c alone (since by default v will delete them after c backend finishes)
|
||||
// NB: passing -cg instead of -g will set is_vlines to false and is_g 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).
|
||||
is_pretty_c bool // -pretty_c , tell v to run clang-format -i over the produced C file, before it is compiled. Use with -keep_c or with -o x.c .
|
||||
is_cache bool // turns on v usage of the module cache to speed up compilation.
|
||||
is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run
|
||||
no_auto_free bool // `v -nofree` disable automatic `free()` insertion for better performance in some applications (e.g. compilers)
|
||||
cflags string // Additional options which will be passed to the C compiler.
|
||||
is_pretty_c bool // -pretty_c , tell v to run clang-format -i over the produced C file, before it is compiled. Use with -keep_c or with -o x.c .
|
||||
is_cache bool // turns on v usage of the module cache to speed up compilation.
|
||||
is_stats bool // `v -stats file_test.v` will produce more detailed statistics for the tests that were run
|
||||
no_auto_free bool // `v -nofree` disable automatic `free()` insertion for better performance in some applications (e.g. compilers)
|
||||
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'.
|
||||
ccompiler string // the name of the used C compiler
|
||||
building_v bool
|
||||
autofree bool
|
||||
compress bool
|
||||
// skip_builtin bool // Skips re-compilation of the builtin module
|
||||
ccompiler string // the name of the used C compiler
|
||||
third_party_option string
|
||||
building_v bool
|
||||
autofree bool
|
||||
compress bool
|
||||
// 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
|
||||
fast bool // use tcc/x64 codegen
|
||||
enable_globals bool // allow __global for low level code
|
||||
// generating_vh bool
|
||||
fast bool // use tcc/x64 codegen
|
||||
enable_globals bool // allow __global for low level code
|
||||
// is_fmt bool
|
||||
is_bare bool
|
||||
user_mod_path string // `v -user_mod_path /Users/user/modules` adds a new lookup path for imported modules
|
||||
vlib_path string
|
||||
vpath string
|
||||
x64 bool
|
||||
output_cross_c bool
|
||||
prealloc bool
|
||||
v2 bool
|
||||
is_bare bool
|
||||
user_mod_path string // `v -user_mod_path /Users/user/modules` adds a new lookup path for imported modules
|
||||
vlib_path string
|
||||
vpath string
|
||||
x64 bool
|
||||
output_cross_c bool
|
||||
prealloc bool
|
||||
v2 bool
|
||||
vroot string
|
||||
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']
|
||||
|
||||
mod string
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue