228 lines
6.6 KiB
V
228 lines
6.6 KiB
V
// 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${filepath.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.options_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(filepath.separator) {
|
|
dir = dir.all_before_last(filepath.separator)
|
|
}
|
|
if dir.starts_with('.$filepath.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' + filepath.separator) } else if dir.starts_with('.\\') || dir.starts_with('./') { dir[2..] } else if dir.starts_with(filepath.separator) { dir.all_after(filepath.separator) } else { dir }
|
|
mod = mod_path.replace(filepath.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(filepath.separator) {
|
|
d := out_name.all_before_last(filepath.separator)
|
|
if !os.is_dir(d) {
|
|
println('creating a new directory "$d"')
|
|
os.mkdir(d)or{
|
|
panic(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
// println('VROOT=$vroot')
|
|
cflags := cmdline.options(args, '-cflags').join(' ')
|
|
defines := cmdline.options(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' || 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 + filepath.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.options(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
|
|
}
|