附录4 V编译器命令行使用
编译器命令行
V编译器命令行本身大小就3M多,实在是小巧得很。
V命令行的设计还是很简洁,合理的,编译器本身和包管理工具等都在主命令行中,比较实用。而不是像rust和node那样,编译器和包管理等工具分开。
不过其实V的一部分子命令并不是直接包含在主命令行中,而是作为单独的工具命令行,由V编译器来调用。这样的好处是不会让主命令行文件过大,但是使用的时候却是统一通过主命令行。
执行v help就可以查看到下面的命令行使用说明:
Usage:v [options] [command] [arguments]
直接执行V,不带任何参数时,直接进入交互模式
编译某个指定的.v源代码文件,会生成同名的可执行文件,也可以使用-o选项,生成特定的可执行文件名
编译某一个指定的目录,编译器会编译目录中所有*.v的源代码,生成一个单一的可执行文件或库文件,文件名跟目录同名
所有以 _ test.v结束的文件,会被编译器当做测试文件,编译器执行测试文件时,会按顺序执行所有的以test_开头的测试函数
可以把常用的编译选项维护到 VFLAGS 的系统环境变量中,运行编译器时,会合并VFLAGS中的选项,这样就不用每次都重复输入相同的选项
Usage:v [options] [command] [arguments]
新建项目子命令:
new #创建新的V项目,主要是生成v.mod项目文件
init #对现有已存在的V项目生成v.mod项目文件
标准开发子命令:
run #编译并运行指定的V源文件或目录,运行后删除可执行文件,每次都重新编译
crun #编译并运行指定的V源文件或目录,运行后不删除可执行文件,如果源代码没有改动,再次运行会直接运行可执行文件,而不用重新编译,加快运行时间,vsh脚本也可以使用
test #运行指定目录的测试文件
fmt #格式化代码
vet #分析代码存在的错误
doc #生成指定模块的文档
repl #运行交互式模式
watch #编译项目,并监控源文件修改,保存后自动重新编译
where #查找指定的符号(fn,method,struct,interface,
#enum,const,var,regexp)所在的位置
ast #将V源代码生成json格式的AST语法树,直观展现V的语法树
scan #扫描V源文件,输出源文件中所有的token
vlib-docs #调用v doc生成vlib标准库的文档
interpret #直接解释执行V代码
安装和升级子命令:
symlink #unix系统在/usr/local/bin/v生成链接,windows生成环境变量
up #升级编译器V到最新版本,等同于git pull,然后make
self [-prod] #让V编译器自己编译自己(不执行git pull,不使用make)
#可使用-prod优化编译
version #查看编译器版本
包管理子命令:
install #从vpm/git/hg安装指定的一个或多个模块
remove #删除已安装的模块
search #搜索模块
update #升级指定已安装的模块
upgrade #升级所有已安装的模块
list #列出所有已安装的模块
outdated #列出所有过时需要升级的模块
show #显示模块的详细信息
其他子命令:
ls #安装,更新,执行vls语言服务
translate #把C源代码翻译成V源代码,或封装C代码库给V调用
doctor #输出当前电脑的基本环境信息,用于提单到github时,报告环境信息
tracev #生成一个带跟踪调试信息的V编译器可以使用v help xxx进一步查看各个子命令的具体帮助文本:
可查看build和run的子命令详细内容,此部分较为重要,同时build和run子命令的编译选项是共用的
跨平台编译
编译器选项-os,用来编译生成指定平台的可执行文件,目前可以是:linux/mac/windows/ msvc。
并发编译
V编译器不使用-prod进行生产编译的时候,编译速度很快,但是如果使用-prod进行生产编译,编译速度就会慢很多,于是Alex开发了并发编译,使用上所有CPU核心。基本的并发编译原理是:把生成的C代码切分成多份,并发编译切分后的代码,最后再链接生成。
编译V编译器,速度可以提升十几倍:
编译速度比较:未使用并发编译2分20秒,使用并发编译 7.4秒,足足快了18倍。
编译最简单的hello world例子,速度提升了5.9倍左右。由此可见,代码量越多,提升的速度越明显。
常用命令例子
代码格式化工具
命令行中提供了代码格式化子命令,用来格式化代码:
关于代码格式化工具,还有一个非常实用的功能,可以在代码中使用vfmt off/on来控制某段代码是否要自动格式化,这样就可以保留手工编写的格式。
工具命令行
工具命令行的代码位于cmd/tools目录中,当V命令行使用到的子命令还没有编译时,会自动编译子命令,然后再调用。也可以使用以下命令一次性编译所有工具命令行:
常用子命令有:
编译器自身的编译选项
编译V编译器自身的时候,也可以添加一些自定义编译选项,让V有不同的行为,比如:
使用以上几个时间选项编译V编译器后,编译器在编译文件时,会详细显示每一个文件在不同阶段消耗的时间:
glibc和musl libc编译
大部分的linux应用都是基于glibc作为C标准库,不过musl也是一个很优秀的C标准库,体积小,可以静态链接,有自身的特色和场景,目前比较适合在移动端作为C标准库使用,alpine linux发行版的也是使用musl作为C标准库,系统很小型,轻量。
V编译器也支持musl编译,调用musl-gcc作为编译器。
安装musl
在linux系统中,glibc是内置的,musl需要安装,下面是从源代码编译安装的步骤:
编译对比
安装成功后,就可以使用musl-gcc选项来编译V源代码,以下是glibc和musl的不同编译结果对比,
最简单的V源代码,如果依赖的libc内容越多,差异应该越大。
main.v
使用-cc musl-gcc就是使用musl编译,
以下是在linux mint 20.2版本中的编译对比:
普通编译
v main.v (开发默认采用tcc进行编译,速度最快,就是v -cc tcc main.v)
564.2K
v -cc gcc main.v
235.3K
v -cc musl-gcc main.v
230K
生产编译
v -prod -cc gcc main.v
97.6K
v -prod -cc musl-gcc main.v
91.8K
静态链接
v -cc gcc -cflags -static main.v
1.1M
v -cc musl-gcc -cflags -static main.v
264.2K
生产编译+静态链接
v -prod -cc gcc -cflags -static main.v
967.5K
v -prod -cc musl-gcc -cflags -static main.v
91.9K
相关环境变量
VEXE
VEXE环境变量用于指定V源代码的根目录,一般来说V命令行也在这个目录中。
除非有特殊场景,一般不建议人为指定。
V命令行启动的时候,会检查是否人为指定了该环境变量,如果指定了,就直接使用该环境变量。
如果没有指定,则将VEXE环境变量设置为V命令行所在的目录,
如果fork了V编译器源代码,要修改V编译器源代码,那么最好不要人为设置这个环境变量,让V命令行自动设置该环境变量。
VMODULES
VMODULES环境变量用于指定存放第三方包的目录,所有通过v install下载的第三方包都会统一下载到该目录中,如果没有设置该环境变量,默认存放在~/.vmodules中。
VOSARGS
用于设置V编译器默认使用的flags字符串,优先级高于os.args和VFLAGS的设置,如果环境变量设置了VOSRAGS则会忽略os.args和VFLAGS的设置,不过感觉这个环境变量没有什么存在的用处,一般用VFLAGS也就够了。
VFLAGS
用于设置V编译器默认使用的flags字符串,环境变量中设置的VFLAGS会和os.args中的flags合并,如果两者中有相同的flag,os.args中的flag优先。
CFLAGS
用于设置调用C编译器要使用的c flag字符串。
LDFLAGS
用于设置调用C编译器要使用的ldflags字符串。
VTMP
用于设置V的临时目录,如果没有设置,则使用操作系统临时目录下的V_开头的目录作为V的临时目录。
VCACHE
用于设置V的缓存目录,如果没有设置,则使用操作系统临时目录下的vcache_folder作为缓存目录。
VWATCH_TIMEOUT
用于设置v watch子命令即使文件没有发生变化,也自动重启程序的时间,以秒为单位。如果没有设置该环境变量,v watch默认是300秒自动重启程序。
VCOLORS
用于设置V的终端是否显示彩色字体,可选值为:always,never.
VERBOSE
用于设置编译器是否为详细输出模式,可选值为:1/0.
VCHILD
待定未尝试。
VDIFF_TOOL
v fmt中,如果指定了该环境变量,v fmt -diff不再使用系统默认的比较工具diff,而是使用指定的比较工具。
VDIFF_OPTIONS
v fmt中,传递给VDIFF_TOOL比较工具的选项。
PKG_CONFIG_PATH
C编译工具pkg-config使用的环境变量,V版本的pkg-config工具也使用了这个环境变量,默认会搜索/usr/lib/pkg-config目录,若找不到,则会去PKG_CONFIG_PATH环境变量指定的路径下查找。
最后更新于
这有帮助吗?