随着项目代码工程化时,整体的复杂度是越来越复杂,构建项目所用的编译过程也越来越复杂。库与库之间是有十分复杂的依赖关系,人工去进行维护是十分困难的。这个时候就需要类似Make或者Waf工具来进行维护。Waf编译工具相对于Make编译工具更加轻量化。不用了解很多生涩的正则表达式,但是貌似在C/C++编程领域用的更多的时Make。
C/C++构建包括将源文件转换(编译)为目标文件,并在最后组装(链接)目标文件。 理论上,单一的编程语言应该足以编写任何应用程序,但情况通常更复杂:
为了隐藏实现细节和可移植性问题,每个目标(程序、库)都可以包装为单个任务生成器对象。
def options(opt): opt.load('compiler_c') #扩展 compiler_c、compiler_cxx、compiler_fc 和 compiler_d 分别提供对 C、C++、Fortran 和 D 语言的支持 def configure(conf): conf.load('compiler_c') def build(bld): bld.program(source='main.c', target='app', use='myshlib mystlib') #这声明了一个从 main.c 构建并使用其他两个库的程序 bld.stlib(source='a.c', target='mystlib', use='myobjects') #这声明了一个静态库,使用来自 myobjects 的对象 bld.shlib(source='b.c', target='myshlib') #这声明了一个动态库 bld.objects(source='c.c', target='myobjects')
def options(opt): opt.load('compiler_c') def configure(conf): conf.load('compiler_c') def build(bld): bld.program( source = 'main.c', target = 'appname', #目标会自动转换为 target.exe 或 libtarget.so,具体取决于平台和类型 includes = ['.'], defines = ['LINUX=1', 'BIDULE'], lib = ['m'], #出于可移植性的原因,应提供不带文件扩展名的库名 libpath = ['/usr/lib'], rpath = ['/opt/kde/lib'] vnum = '1.2.3', idx = 123, #有时需要为目标文件扩展名设置计数器以避免目标文件名冲突 install_path = '${SOME_PATH}/bin', #默认情况下安装程序和共享库。要禁用安装,请设置无。 cflags = ['-O2', '-Wall'], #其他标志,应用于支持它们的源文件 )
在各种库进行交互时,需要用use来处理库和库之间的依赖关系。
def build(bld): bld.stlib( source = 'test_staticlib.c', target = 'mylib', name = 'stlib1') #name 属性指向一个Task generator bld.program( source = 'main.c', target = 'app', includes = '.', use = ['stlib1'])
值得注意的是use具有递归属性:
def build(bld): bld.shlib( source = 'a.c', target = 'lib1') bld.stlib( source = 'b.c', use = 'cshlib', #cshlib 标志将传播到库和程序。 target = 'lib2') bld.shlib( source = 'c.c', target = 'lib3', use = 'lib1 lib2') bld.program( #由于共享库依赖 lib1 → lib2,程序应用程序应该同时链接 lib1 和 lib3,但不链接 lib2 source = 'main.c', target = 'app', use = 'lib3')
-use 关键字不仅可以指向具体的库,还可以指向仅有头文件的路径。 def build(bld): bld( includes = '. src', export_includes = 'src', #include 属性是私有的,但 export_includes 将被其他task generator使用 name = 'com_includes') bld.stlib( source = 'a.c', target = 'shlib1', use = 'com_includes') #添加的路径是相对于其他task generator bld.program( source = 'main.c', target = 'app', use = 'shlib1', #export_includes 将传播到其他任务生成器 )
all: builds all programs of all group bin: builds all programs of bin group build: excutes the build check: builds all programs and run tests check-all: "waf check --alltests" clean: cleans the project configure: configures the project dist: makes a tarball for redistributing the sources distcheck: checks if the project compiles distclean: removes build folder and data examples: builds all programs of examples group copter: builds copter programs plane: builds plane programs rover: builds rover programs tests: builds all programs of tests group tools: builds all programs of tools group uninstall: removes the targets installed
WafBook