前言

本人刚刚接触 Waf ,加之翻译水平一般,有什么错误大家见谅。

精确版本请看 原文地址

Waf 是一份用来帮助编译软件工程的软件。本教程的目标是提供如何为一个使用 Waf 的工程设置脚本的简要说明。

Waf 脚本与命令

软件通常有保存在版本管理系统(git, subversion 等等)的 源文件(source files),以及描述如何处理这些文件的 编译脚本(build scripts) (Makefiles,...)。一些 生成文件(build files) 通常由 源文件(source files) 转换而得,但它们是可选的。在 Waf 中编译脚本是那些命名为 'wscript' 的文件。

通常,一个工程包含下面若干阶段:

  • 配置(configure): 配置工程,找到依赖项的位置
  • 编译(build): 将源文件转换为生成文件
  • 安装(install): 安装生成文件
  • 卸载(uninstall): 卸载生成文件
  • 打包(dist): 生成源文件的存档
  • 清理(clean): 删除生成文件

每一阶段在 wscript 文件中都是以一个 Python 函数构造的,该函数使用 waflib.Context.Context 的一个实例作为函数。

让我们从在文件夹 /tmp/myproject 下 新建一个 wscript 文件开始:

    def configure(conf):print("configure!")

def build(bld):print("build!")

我们也需要一个 Waf 二进制文件,如: http://waf.googlecode.com/files/waf-1.6.1 , 并把该文件拷贝到工程目录下:

    $ cd /tmp/myproject    $ wget http://waf.googlecode.com/files/waf-1.6.1

我们只需简单地将命令作为参数传递给 waf 即可运行此工程:

    $ ./waf-1.6.1 configure build    configure!    build!

目标

编译系统的一个重要组成部分是声明目标的创建过程。这里有一个非常简单的例子:

    def build(bld):        tg = bld(rule='cp ${SRC} ${TGT}', source='wscript', target='foo.txt')        bld(rule='cp ${SRC} ${TGT}', source='foo.txt', target='bar.txt')

调用 bld(..) 创建了一个 任务生成器(task generator) ,它用来生成 任务(tasks) 。 任务则实际运行命令 cp。 命令直到所有脚本都被读取后才会运行,这对计算编译顺序非常重要。

表达式 ${SRC}${TGT} 是快捷方式,用来避免文件名重复。更多的快捷方式可以通过使用 ${} 符合定义,该符号能从 bld.env 属性读取对应的值。

    def build(bld):        bld.env.MESSAGE = 'Hello, world!'        bld(rule='echo ${MESSAGE}', always=True)

bld 对象是类 waflib.Build.BuildContext,它的 env 属性是类 waflib.ConfigSet.ConfigSet 的一个实例。

这些值被保存在此对象中以便于共享/保存/加载。这里是如何在配置和编译过程中共享数据来实现和上个例子同样的事情:

    def configure(cnf):        cnf.env.MESSAGE = 'Hello, world!'

def build(bld):        bld(rule='echo ${MESSAGE}', always=True)

脚本与工具

为让一个脚本使用子目录下的另一脚本,需要使用方法 waflib.Context.Context.recurse 及包含 wscript 文件夹的相对路径。例如,调用 src/wscript 脚本中 build 函数,应该这样写:、

    def build(bld):        bld.recurse('src')

Waf 通过特定模块 Waf tools 提供了对特定语言和编译器的支持。这些工具与 wscript 文件类似且提供如 configure 或者 build 函数。这里是一个C语言的简单工程:

    def options(opt):        opt.load('compiler_c')def configure(cnf):        cnf.load('compiler_c')def build(bld):        bld(features='c cprogram', source='main.c', target='app')

options 函数是另一个预定义的命令,用来设置命令行选项。它的参数是 waflib.Options.OptionsContext 的一个实例。 提供了工具 compiler_c用以检测是否有 C 编译器存在,并设置各种参数如 cnf.env.CFLAGS

bld 声明的任务生成器并没有 规则(rule) 关键字,而是用一系列 特性(features) 来引用那些调用适当规则的方法。 在这个例子中,一个规则被调用以编译文件,而另一个用来链接目标文件到二进制文件 app 。 还存在其他一些工具依赖的 特性(features) 如: javaccs 或者 tex

一个同时使用C和C++的工程

下面是一个更复杂一些工程的脚本

    def options(opt):        opt.load('compiler_c compiler_cxx')def configure(cnf):        cnf.load('compiler_c compiler_cxx')        configure.check(features='cxx cxxprogram', lib=['m'], cflags=['-Wall'], defines=['var=foo'], uselib_store='M')def build(bld):        bld(features='c cshlib', source='b.c', target='mylib')        bld(features='c cxx cxxprogram', source='a.c main.cpp', target='app', use=['M','mylib'], lib=['dl'])

方法 waflib.Tools.c_config.check 会内部执行编译以检测在操作系统中是否存在 libm 库。然后它会定义变量如:

  • conf.env.LIB_M = ['m']
  • conf.env.CFLAGS_M = ['-Wall']
  • conf.env.DEFINES_M = ['var=foo']

通过声明 use=['M', 'mylib'],程序 app 会继承所有在配置过程中定义的 M 变量。该程序也会使用库 mylib 并且编译顺序和依赖项都会更改以使 mylibapp 之前链接。

use 属性也适用于其他语言如Java(jar 文件之间的依赖)或者C#(程序集之间的依赖)。

工程特定扩展

feature 关键字是高层次的对现有 Waf 方法的引用。例如: c feature 会添加方法 waflib.Tools.ccroot.apply_incpaths 以执行。要添加一个为所有C目标加入任务生成器路径到包含路径的新方法,可以采用如下声明:

    from waflib import Utilsfrom waflib.TaskGen import feature, before_method    @feature('c')    @before_method('apply_incpaths')def add_current_dir_to_includes(self):        self.includes = Utils.to_list(self.includes)        self.includes.append(self.path)

def build(bld):        tg = bld(features='c', source='main.c', target='app')

这些 feature 方法被绑定到类 waflib.TaskGen.task_gen ,在这个例子中是对象 tg 的类。新的 feature 可以以相同的方式声明:

    from waflib.TaskGen import feature, after_method    @feature('debug_tasks')    @after_method('apply_link')def print_debug(self):print('tasks created %r' % self.tasks)

def build(bld):        tg = bld(features='c cprogram debug_tasks', source='main.c', target='app')

通过绑定新方法到 context 类, 声明可以变得更加用户友好。

    from waflib.Build import BuildContextdef enterprise_program(self, *k, **kw):        kw['features'] = 'c cprogram debug_tasks'return self(*k, **kw)    BuildContext.enterprise_program = enterprise_program

def build(bld):# no feature line        bld.enterprise_program(source='main.c', target='app')

这些辅助代码放到单独文件中即可以成为一个 Waf 工具。为了便于部署,新的 Waf 工具甚至可以被添加到 Waf 文件中(参见 http://code.google.com/p/waf/source/browse/trunk/README)。

结论

教程到此结束。 更多信息请参考apis,Waf book,examples。

转载于:https://www.cnblogs.com/Lvkun/archive/2012/03/30/trans-waf-tutorial.html

翻译: Waf 教程相关推荐

  1. uc浏览器电脑版翻译设置在哪 uc浏览器翻译网页教程

    uc浏览器电脑版翻译设置在哪 uc浏览器翻译网页教程 uc浏览器电脑版翻译设置在哪?uc浏览器怎么翻译网页?现在的UC浏览器和以前的谷歌浏览器一样都带有翻译网页和反应单词的功能,如果觉得英文页面看起来 ...

  2. Hyperledger Fabric 官网翻译入门教程--之关键概念(Hyperledger Fabric 模型)

    英文地址:http://hyperledger-fabric.readthedocs.io/en/latest/fabric_model.html Hyperledger Fabric Model/ ...

  3. [翻译Pytorch教程]NLP从零开始:使用序列到序列网络和注意力机制进行翻译

    翻译自官网手册:NLP From Scratch: Translation with a Sequence to Sequence Network and Attention Author: Sean ...

  4. 知云文献翻译安装教程_阅读英文文献的好帮手

    还在为看不懂英文文献而头疼吗? 1.下载 知云文献翻译目前最新版完整版.win版本.适用于win7-win10. 大家最好直接进知云文献翻译的官网进行下载:win知云完整安装包下载 ,可直接在软件内部 ...

  5. [翻译Pytorch教程]NLP从零开始:使用字符级RNN进行名字生成

    翻译自官网手册:NLP From Scratch: Generating Names with a Character-Level RNN Author: Sean Robertson 原文githu ...

  6. 个人网络上翻译计算机教程,计算机翻译教程

    作为计算机辅助翻译入门教材,本书具有以下特点: 内容详实,图文并茂: 以实践为主,注重实际作: 紧跟计算机辅助翻译技术发展,确保科学性与时代性. 本书主要适用于翻译专业及英语专业本科生,也可以作为翻译 ...

  7. [翻译Pytorch教程]NLP部分:使用TorchText进行文本分类

    本教程展示如何在torchtext中调用文本分类数据集,包括: AG_NEWS, SogouNews, DBpedia, YelpReviewPolarity, YelpReviewFull, Yah ...

  8. python翻译器怎么下载_Python实现桌面版翻译工具教程

    为了方便大家测试,这里会直接贴上源码:import requests import time import random import hashlib def get_md5(string): str ...

  9. php英文插件教程,迅睿CMS 优速:百度翻译插件教程

    首先安装好百度翻译插件,进入配置界面如下 第一步,找到config/custom.php文件 第二步,把上面的代码复制进去 第三步,测试成功就对了. 第四步,申请百度appid接口 把参数填在cms后 ...

最新文章

  1. ASP.NET 2.0 HttpHandler实现生成图片验证码(示例代码下载)
  2. pangolin最新版 v2.5.2.975
  3. shellcode模板(使用hash获取API)
  4. java两个和三个_Java语言基础(day_03)
  5. 两数之和-给定一个整数数组nums和一个目标值target,请你在该数组找出和为目标值的那两个整数,并返回他们的数组下标,你可以假设每种输入只会对应一个答案。但是,数组同一个元素不能使-python
  6. 基于python实现遗传算法
  7. Gradle 3.0.0设置Apk文件输出命名
  8. ❤️《微服务开发—Swagger》(建议收藏)
  9. linux文件乱码crt,Linux中文文件显示乱码或Secure CRT显示乱码解决方案
  10. ICMP数据包-实战分析
  11. 3D打印技术最全解析:从设计到工艺
  12. PC淘宝自动发货卡密客户端 绿色免费的软件,能够让您轻松管理购物网站中的虚拟物品
  13. 代码获取DEP按钮及获取DEP控件
  14. CST STUDIO SUITE 2019 Linux download
  15. 苹果手机计算机怎样拉到桌面,20个你应该知道的iPhone 7实用小技巧
  16. Python与金融:为什么将Python用于金融
  17. 微信公众平台开发__导航
  18. C++经典算法题-最大访客数
  19. mysql任意文件读取漏洞学习
  20. 怎样在苹果Mac上显示或隐藏“节假日”日历?

热门文章

  1. 人工智能:模型与算法 之 启发式搜索
  2. Python_切割和查找
  3. 在路上---学习篇(一)Python 数据结构和算法 (4) --希尔排序、归并排序
  4. 洛谷P1402 酒店之王(二分图)
  5. 随手记一次用C#正则表达式获取下拉菜单html标签select以及相关属性值
  6. UITableView 学习笔记
  7. 多线程(一、线程安全案例)
  8. Linux基础笔记_01
  9. 数据库正常运行,突然变慢的解决思路
  10. 禁止解析PHP、限制user_agent、php相关配置