0

I'm building some custom C++ Bazel rules, and I need to add support for modifying the include paths of the C++ headers, the same way cc_library headers can be modified with strip_include_prefix.

My custom rule is implemented using ctx.actions.run like this:

custom_cc_library = rule(
  _impl,
  attrs = {
    ...
    "hdrs": attr.label_list(allow_files = [".h"]),
    "strip_include_prefix": attr.string(),
    ...
  },
)

Then within _impl I call the following function to rewrite hdrs:

def _strip_prefix(ctx, hdrs, prefix):
    stripped = []
    for hdr in hdrs:
        stripped = hdr
        if file.path.startswith(strip_prefix):
            stripped_file = ctx.actions.declare_file(file.path[len(strip_prefix):])
            ctx.actions.run_shell(
                command = "mkdir -p {dest} && cp {src} {dest};".format(src=hdr.path, dest=stripped.path),
                inputs = [hdr],
                outputs = [stripped],
            )
        stripped.append(stripped_file)
    return stripped

This doesn't work because Bazel won't copy files outside of their package directory, and besides it feels like the totally wrong approach to implementing this.

What is the best way to modify C++ header directories for dependencies to achieve the same functionality as cc_library's parameter strip_include_prefix?

Conor Taylor
  • 2,998
  • 7
  • 37
  • 69
  • 1
    Unfortunately, the [cc_library rule](https://github.com/bazelbuild/bazel/blob/f0c7ff45a04a8bb03517ca692ec8d530175f7232/src/main/java/com/google/devtools/build/lib/bazel/rules/cpp/BazelCcLibraryRule.java#L27), and its [stripIncludePrefix implementation](https://github.com/bazelbuild/bazel/blob/137b759c8f6d37d7512d621571aa9446d5c1ec4d/src/main/java/com/google/devtools/build/lib/rules/cpp/CcCompilationHelper.java#L833) are in Bazel's Java code. – Laurenz May 24 '20 at 20:38
  • 1
    @Laurenz yup I know, it's a pity. But I'm hoping to find a way to implement similar functionality within Starlark. – Conor Taylor May 24 '20 at 21:36

1 Answers1

0

You can create the header layout you want in a directory within your package, and then add that to the include path via create_compilation_outputs.includes. That's basically what the cc_library implementation boils down to.

The cc_library implementation names it _virtual_includes, and creates it using getUniqueDirectoryArtifact which is a helper in the Java code to create it "in a directory that is unique to the rule". I use something like "_%s_virtual_includes" % ctx.label.name to get similar functionality from Starlark, and give a hint that it's a private implementation detail which other rules should avoid relying on.

Brian Silverman
  • 3,085
  • 11
  • 13