waf python build 工具使用流程

waf 的 build 理念

  build 了之后,可以跟踪到 ${SRC} 和 ${TGT} 有关联的文件,只有 ${SRC} 被修改过,在下次build的时候才会重新 build 这个文件,想想如果一个 project 非常大,在测试过程中或者发布都要 build 一次,每次都要全部 build 一遍,尽管你只修改了一个文件,当然如果你知道你改了哪个文件,可以单独 build 那个文件,但是谁能记得清自己修改了哪些文件,waf 可以解决这个问题,不过 waf 虽然可以用相对路径,但是最终还是绝对路径,如果移动了 project 文件夹,那么 SRC 和 TGT 的关系就丢失了,如果 build 关系也能用相对路径,那就更完美了。

设置运行 waf 的 alias

注意,以下使用的是 Git bash 控制台

waf是python写的,所以用python来运行

alias waf='[python-path]/python.exe [waf-path]/waf'

基本的 wscript

 #!//usr/bin/python
# -*- coding: utf-8 -*- top = '.'
out = 'build' #这个是默认的out文件夹,可以设其它名 def configure(cfg):
for f in cfg.path.ant_glob('folder/**/*.py'): #通过ant.glob来获取某个文件夹下面的所有py文件,f 是 waf 的某个类对象,所以有以下的方法
print(f.abspath()) #绝对路径
print(f.srcpath()) #相对路径,f 是 waf 中的类对象,所以绝对路径是 wscript 所在的路径 def build(bld):
bld(rule='"python.exe -OO -c "import py_compile;py_compile.compile(\'${SRC}\', cfile=\'${TGT}\', doraise=True)"',
source='test/foo.py', #注意:source的路径是相对路径(wscript所在的路径),不然build的过程会说source找不到
target='D:/foo.pyc', #注意:target可以是绝对路径,也可以是相对路径,如果是相对路径,build后会在wscript所在文件夹下的 build(out文件夹) 文件夹中找到
)

代码解析:

top:一般默认是'.',代表源代码所在的工程目录

out:是执行 waf build 后在 wscript 所在路径自动生成的 build 文件夹,target 中如果使用相对路径,都会存放在 out 中,这也是默认的 waf build command 运行的路径,build 的时候可以看到 entering directory 'xxx',如果结合其它非 waf 命令,就要注意这点。

cfg.path:代表 wscript 的所在路径

cfg.path.ant_glob():正则匹配cfg.path下的文件

configure(cfg) 和 build(bld) 函数:waf 内置的函数,我们通过重写它们来实现我们的功能,它们的第一个参数也是内置的 waf 类,有定义好的各种功能

bld()中的 rule 参数,${SRC} 和 ${TGT} 是内置的变量,分别代表 source 和 target 参数,注意:source 和 target 最后传递到 rule 里是一个waf node list [],source 的路径是以 wscript 所在路径为前缀的,而且在win系统中 f 中的路径使用的是'\',既然 rule 是 str,使用 f 就要注意转义。另外可以这样:

"${SRC[0].abspath().replace(\'\\\\\', \'/\')}"

如果是win系统,直接加r:

'r\'%s\''%"${SRC[0].abspath()}"

bld() rule 中执行多行命令

bld(rule = 'set PYTHONPATH=%%%%PYTHONPATH%%%%;D:/myPath && python.exe myPython.py')

代码解释:

用 && 来区别多行执行,这应该是 bat 的多行命令符号

注意%的格式化,'%%'才是代表一个'%',而在str中当命令,如果前面不带r,就要四个%%%%

build bld() task 任务强制执行

waf 会对 source 跟踪,如果编译过的文件没有被修改,那么再次编译的时候就不会去处理那个文件,但是有这样一种情况,我们只是在 bld 中去运行其他的编译工具,那么 source 是不会经常被改变的,而且跟踪的事是其他的编译工具的事情,waf 要强制这个bld运行,只要加 always 参数即可,具体如下:

def build(bld):
bld(
rule = '',
always = True
)

wscript 使用基本流程

waf configure  在build之前必须 configure 过

waf build    build

waf distclean  清理所有 waf 的动作所生成的中间文件,执行后,如果想 build,需要重新 configure

waf install

waf 提供了非常方便的安装方式。

假如在 wscript 中的 build 方法内

def build(bld):
start_dir = bld.path.find_dir('src/bar')
bld.install_files('D:/installPath', start_dir.ant_glob('**/*.py[cod]'),
cwd = start_dir, relative_trick = True)

注意:waf build 并不会执行 bld.install_files() 方法,正确执行的方法是:

waf install

waf uninstall   #这是卸载

代码解释:

install_files()

参数1:安装路径

参数2:安装的文件

cwd 和 relative_trick:两者结合,安装到 'D:/installPath' 后,就会保留 cwd 后面的目录结构(就是把cwd的部分去掉),例如 [cwd]/myFolder/* -> [参数1 路径]/myFolder/*

start_dir.ant_glob('**/*.py[cod]'):在 start_dir 下找到所有的 pyc,pyo,pyd,注意:**/* 是waf的正则表达式,表示所有子目录下的文件

更多waf install 函数,请参考:waf 文档5.2.2. Installing files

cmd 判断

如 waf install,它其实执行的是 build(bld),尤其是一些 bld(always = True) 的情况,我们需要根据不同的 cmd 来判断是否需要执行一些函数

bld.cmd == 'build'

bld.cmd == 'install'

等等

waf node

The Waf nodes inherit the class waflib.Node.Node and provide a tree structure to represent the file system

waf node 继承于 waflib.Node.Node,和提供了一个代表文件系统的树结构

一些路径处理方式:

ctx.root:系统的根目录,linux为/,win系统为包含了所有磁盘的文件夹,这个 node 可以用来获得与 wscript 无关的一些路径的node,例如 ctx.root.find_dir("D:/"),在处理一些其它路径的时候非常有用

ctx.srcnode:top 路径,ctx是 wscript 方法的第一个参数

ctx.bldnode:out 路径,ctx是 wscript 方法的第一个参数

node.abspath():返回 node 的绝对路径,类型是str,注意这里的绝对路径是是以top路径为前缀的

node.srcpath():返回 node 的相对路径,类型是str,注意这里是top的相对路径

node.from_path(node):去掉 node 的部分

node.find_dir(''):在 node 的路径下找相应路径,返回一个 node

node.search_node(""):找一个node(文件或者文件夹),如果找不到,返回 None

ctx.path:wscript所在路径

node.parent:父路径

node.child:子目录

node.ant_glob():正则匹配 node 下的文件,默认返回的都是文件,ant_glob() 参数说明:

参数1:str 或者 str list,如果是 list,表示匹配里面多个可能

excl = []:不包含[]中匹配到的内容

dir = False:如果是 True,则返回的是匹配到的文件夹

scr = False:暂时不知道有何作用,可以忽略,不过按照字面的意思,可能是返回的是相对了的路径

常用的正则表达式:

node.ant_glob('*'):node 下的所有文件,不包括子文件夹里面的文件

node.ant_glob('**'):node 下的所有文件,包括子文件夹里面的文件

node.ant_glob('**/folder/'):node folder文件夹(包括子文件夹)下的所有文件

node.ant_glob('**/file'):node folder文件夹(包括子文件夹)下的所有的 file

node.ant_glob('**/*.py[cod]'):node 文件夹(包括子文件夹)下的所有 pyc pyo pyd 文件

提醒:当out 和 top 与 wscript 不在同一个目录,就要注意路径处理

env 环境设置

 #!//usr/bin/python
# -*- coding: utf-8 -*- top = '.'
out = 'build' def configure(cfg):
cfg.env.TESTENV = 0
#or
#cfg.env[TESTENV] = 0 def build(bld):
print(bld.env.TESTENV)

waf 还有很多其它功能

官方文档:https://waf.io/book/#_projects_and_commands

waf python build 工具使用流程的更多相关文章

  1. 【Machine Learning】Python开发工具:Anaconda+Sublime

    Python开发工具:Anaconda+Sublime 作者:白宁超 2016年12月23日21:24:51 摘要:随着机器学习和深度学习的热潮,各种图书层出不穷.然而多数是基础理论知识介绍,缺乏实现 ...

  2. 关于前端build工具

    第一.build工具的核心就是帮你安装和帮你做事.安装类工具:Npm.Bower.Yeoman等          做事类工具:Node.Grunt.gulp.Webpack等 安装类工具几乎什么东西 ...

  3. 一种数据与逻辑分离的Python单元测试工具

    一种数据与逻辑分离的Python单元测试工具 几个概念 TestCase TestCase是一个完整的测试单元,最小的测试执行实体,就是我们常说的测试用例. TestSuite 以某种特性将测试用例组 ...

  4. 数据分析之---Python可视化工具

    1. 数据分析基本流程 作为非专业的数据分析人员,在平时的工作中也会遇到一些任务:需要对大量进行分析,然后得出结果,解决问题. 所以了解基本的数据分析流程,数据分析手段对于提高工作效率还是非常有帮助的 ...

  5. python版本管理工具pyenv和包管理工具pipenv

    一.pyenv版本管理工具 pyenv是一个python版本管理工具,可以实现轻松切换多个python版本 它可根据每个用户更改全局python版本,也可以为每个项目指定python版本,还可以管理v ...

  6. $python打包工具pyinstaller的用法

    pyinstaller是一个很好用的python打包工具,在Windows环境下可以将python脚本打包成一个exe可执行文件,并且脚本中所依赖的各种第三方库在打包时候都会被统一处理到一起,这样打包 ...

  7. 学习Python编程技术的流程与步骤,自学与参加培训学习都适用

     一.清楚学习目标 无论是学习什么知识,都要有一个对学习目标的清楚认识.只有这样才能朝着目标持续前进,少走弯路,从学习中得到不断的提升,享受python学习计划的过程. 虽然目前的编程语言有很多,但是 ...

  8. Python 开发工具推荐

    对于开发工具,仁者见仁智者见智,关键是自己喜欢,用着顺手就好,不用刻意去追求别人用的是什么工具. 这里给大家主要推荐三款工具,分别是PyCharm.Sublime Text 3.VS Code,因为这 ...

  9. Python 开发工具链全解

    可能刚开始学习Python时,有人跟你说可以将源文件所在的文件夹添加到 PYTHONPATH环境变量中,然后可以从其他位置导入此代码.在大多数情况下,这个人常常忘记补充这是一个非常糟糕的主意.有些人在 ...

随机推荐

  1. Navicat系列产品激活教程

    准备 本教程可破解12.x版本,如果教程失效请联系我 # 19.1.11 破解暂时失效,请勿更新 (如已更新请卸载重新安装老版本,数据不会丢失 http://download.navicat.com/ ...

  2. Ubuntu16.04配置Tomcat的80端口访问

    [问题描述] 在阿里云 ECS 服务器 Ubuntu16.04 下部署 Java Web 应用时,发现配置的 Tomcat 服务启动后 80 端口无法被监听. [问题原因] 出现该问题的主要原因是:非 ...

  3. Confluence 6 配置服务器基础地址示例

    如果 Confluence 的安装是没有安装在非根目录路径(这个是上下文路径),然后服务器基础 URL 地址应该包括上下文地址.例如,你的 Confluence 正在运行在下面的地址: http:// ...

  4. Confluence 6 配置站点主页面

     主面板(dashboard)是你站点的默认主页,但是你也可以选择使用一个空间的主页为网站访问的首页面. 针对你的 Confluence 站点主要是为用户进行阅读而不是创建内容的话,这样的配置就显得非 ...

  5. python并发编程之进程池,线程池,协程

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  6. 自定义Web框架

    http协议 HTTP简介 HTTP协议是Hyper Text Transfer Protocol(超文本传输协议)的缩写,是用于从万维网(WWW:World Wide Web )服务器传输超文本到本 ...

  7. Java并发编程基础-线程安全问题及JMM(volatile)

    什么情况下应该使用多线程 : 线程出现的目的是什么?解决进程中多任务的实时性问题?其实简单来说,也就是解决“阻塞”的问题,阻塞的意思就是程序运行到某个函数或过程后等待某些事件发生而暂时停止 CPU 占 ...

  8. python网络爬虫笔记(六)

    1.获取属性如果不存在就返回404,通过内置一系列函数,我们可以对任意python对象进行剖析,拿到其内部数据,但是要注意的是,只是在不知道对象信息的时候,我们可以获得对象的信息. 2.实例属性和类属 ...

  9. 课外知识----ini

    ini    初始化英文单词的缩写,用来初始化参数 ini文件配置 [小节] 键=值 [小节] 键=值

  10. export default 和 export 区别

    转载:https://www.cnblogs.com/mengfangui/p/9073459.html   1.export与export default均可用于导出常量.函数.文件.模块等2.在一 ...