【问题标题】:How do I use waf to build a shared library?如何使用 waf 构建共享库?
【发布时间】:2009-10-20 15:25:15
【问题描述】:

我想使用waf 构建一个共享库,因为它看起来比 GNU 自动工具更容易且更简洁。

到目前为止,我实际上有几个与我开始编写的 wscript 相关的问题:

VERSION='0.0.1'
APPNAME='libmylib'

srcdir = '.'
blddir = 'build'

def set_options(opt):
 opt.tool_options('compiler_cc')
 pass

def configure(conf):
 conf.check_tool('compiler_cc')
 conf.env.append_value('CCFLAGS', '-std=gnu99 -Wall -pedantic -ggdb')

def build(bld):
 bld.new_task_gen(
  features = 'cc cshlib',
  source = '*.c',
  target='libmylib')

包含source = '*.c' 的行不起作用。我必须指定每个 .c 文件而不是使用通配符吗?

例如,我如何启用调试构建(当前 wscript 正在使用调试构建 CFLAGS,但我想将此设置为最终用户可选)。

计划将库源放在一个子目录中,而使用该库的程序则在各自的子目录中。

【问题讨论】:

标签: c linux shared-libraries waf


【解决方案1】:

假设您使用的是最新版本的 waf(撰写本文时为 1.5.9),可以通过构建上下文中的 glob() 方法指定通配符。所以你可以写如下:

bld.new_task_gen(
    features = 'cc cshlib',
    source = bld.glob('*.c'),
    target='mylib')

如果您使用的是没有 glob 的旧版 waf,那么您可以使用一种方法 find_sources_in_dirs

lib = bld.new_task_gen(
    features = 'cc cshlib',
    target = 'mylib')
lib.find_sources_in_dirs('.')

此方法仍在 Waf 中,但计划弃用,最终可能会消失。

srcdirblddir 变量现在是可选的,因此您不需要它们 - 它们默认为“。”无论如何都要“建造”。您不应该在目标名称前面加上“lib”,这是以特定于平台的方式自动完成的(在 Windows 上不添加 lib,共享库使用 .dll)。 Debug vs Release build 是一个非常棘手的问题。最初 Waf 包含此功能,但它在某个时候被删除并且从未重新添加。这是邮件列表中的常见请求,因此将来可能会重新出现。同时,你可以做的比使用gjc's cflags module 更糟糕。只需将其添加到您的项目目录即可。最终的 wscript 将是:

VERSION='0.0.1'
APPNAME='mylib'

def set_options(opt):
    opt.tool_options('compiler_cc')
    opt.tool_options('cflags', tooldir='.')

def configure(conf):
    conf.check_tool('compiler_cc')
    conf.check_tool('cflags', tooldir='.')

def build(bld):
    bld.new_task_gen(
        features = 'cc cshlib',
        source = bld.glob('*.c'),
        target=APPNAME)

要设置调试版本,您将运行以下命令:

./waf configure -d debug

如果您在自己的子目录中使用库,那么您可能应该有一个顶级 wscript 并使用bld.add_subdirs() 技术来添加库/程序目录。每个子目录都有自己的 wscript_build 文件。然后,您可以使用export_incdirsuselib_local 属性在库和程序“模块”之间指定正确的包含目录。

【讨论】:

  • 虽然我没用过,但另一个可能有用的 waf 模块是 autowaf.py: svn.drobilla.net/lad/trunk/autowaf.py "用于轻松构建标准 unixey 包的 Waf 实用程序/libraries" 是 Dave Robillard 和 Nedko Arnaudov 的 GNU GPL v2 或更高版本
【解决方案2】:

多年来,waf 发生了很大变化,因此问题中的代码和答案都不再适用于当前的 waf。现在你只写:

def options(ctx):
    ctx.load('compiler_c')
def configure(ctx):
    ctx.load('compiler_c')
def build(ctx):
    ctx.shlib(source = ctx.path.ant_glob('src/*.c'),
              target = 'name')

请注意,waf 会自动添加 lib 前缀,因此您不要写 target = 'libname'。在 Windows 上,您还必须将 defs 关键字参数添加到 shlib 函数调用。

我个人建议不要使用涉及wscript_build 文件的递归构建脚本。并不是说它不起作用(如recursive makefiles),只是将所有逻辑保存在一个中等大小的构建脚本中要简单得多。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-04-05
    • 1970-01-01
    • 1970-01-01
    • 2012-04-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多