0

我使用下面的 bazel 规则来构建带有 bazel 的静态库:

def _cc_static_library_impl(ctx):
    cc_deps = [dep[CcInfo] for dep in ctx.attr.deps]
    libraries = []
    for cc_dep in cc_deps:
        for link_input in cc_dep.linking_context.linker_inputs.to_list():
            for library in link_input.libraries:
                libraries += library.pic_objects
    args = ["r", ctx.outputs.out.path] + [f.path for f in libraries]
    ctx.actions.run(
        inputs = libraries,
        outputs = [ctx.outputs.out],
        executable = "/usr/bin/ar",
        arguments = args,
    )
    return [DefaultInfo()]

cc_static_library = rule(
    implementation = _cc_static_library_impl,
    attrs = {
        "deps": attr.label_list(providers = [CcInfo]),
    },
    outputs = {"out": "lib%{name}.a"},
)

如何从当前工具链中提取要使用的命令而不是使用硬编码/usr/bin/ar?我的规则是基于我在互联网上找到的,我对此知之甚少。这个例子似乎做了一些相关的事情: https ://github.com/bazelbuild/rules_cc/blob/main/examples/my_c_archive/my_c_archive.bzl

4

1 回答 1

1

这是相关部分my_c_archive

    archiver_path = cc_common.get_tool_for_action(
        feature_configuration = feature_configuration,
        action_name = CPP_LINK_STATIC_LIBRARY_ACTION_NAME,
    )

这为您提供了路径,然后您需要添加cc_toolchain.all_files到您的ctx.actions.run调用中,所以它最终看起来像这样:

    ctx.actions.run(
        inputs = depset(
            direct = [libraries],
            transitive = [
                cc_toolchain.all_files,
            ],
        ),
        outputs = [ctx.outputs.out],
        executable = archiver_path,
        arguments = args,
    )

但是,您还会注意到my_c_archive构建了一个命令行和环境变量来调用归档程序。一个简单的工具链不会在其中任何一个中传递任何东西,但如果不添加它们(例如,传递-m32或设置PATH),更复杂的工具链可能无法正常工作。

cc_importcc_import.bzl 中in的 Starlark 实现的_create_archive_action一部分是处理所有复杂问题的好起点。它创建了一个动作来从一组目标文件中生成一个静态库,并且可以灵活地使用许多工具链。

于 2021-06-30T20:14:45.260 回答