Search code examples
c++windowsbazel

Bazel - Including all headers from a directory when importing a static library


I am a total newbie to Bazel and trying to add a static library to my build.

Lets say as a simple example say I have the following.

cc_import(
  name = "my_test_lib"
  static_library = "lib\my_test_lib\test.lib"
  hdrs = ["lib\my_test_lib\include\headerA.h", 
          "lib\my_test_lib\include\headerB.h"]
  visibility = ["//visibility:public"],
)

Now this works fine.

However, what if I have a huge number of includes and within the include directory there is a number of subdirectories. Do I have to individually enter each one that my main project depends on, or can I do something like the following to essentially make all headers in this directory / subdirectories available?

 hdrs = [ "lib\my_test_lib\include\*"]

Solution

  • What you need is the glob function.

    To use it in your above example, you would do something like this

    cc_import(
      name = "my_test_lib"
      static_library = "lib/my_test_lib/test.lib"
      hdrs = glob(["lib/my_test_lib/include/*.h"])
      visibility = ["//visibility:public"],
    )
    

    which would find all files ending with .h under lib\my_test_lib\include and put them in the hdrs attribute of your cc_import.

    There's more information about glob in the Bazel documentation: https://docs.bazel.build/versions/master/be/functions.html#glob

    Note: Always use forward slashes on all platforms in Bazel BUILD files (even on Windows).

    Multiple glob patterns

    It's sometimes useful to put in more than one pattern in the glob, for example like this

    cc_import(
      ...
      hdrs = glob([
        "lib/my_test_lib/include/*.h",
        "lib/my_test_lib/include/*.hpp",
        "lib/my_test_lib/public/*.h",
      ]),
      ...
    )
    

    Combining a glob with a hard coded list of files

    Another useful thing is combining globs with hard coded paths. You might have a few files you want in there and then a directory you also want to include. You can do this by using the + operator to concatenate the hard coded list of paths with the glob results like this

    cc_import(
      ...
      hdrs = [
        "lib/my_test_lib/some_header.h",
      ] + glob([
        "lib/my_test_lib/include/*.h",
      ]),
      ...
    )
    

    Globbing a directory hierarchy (beware of massive inclusions)

    The glob function also support traversing directories and their sub directories when finding files. This can be done using the ** glob pattern. So, to for example grab all .h files in the my_test_lib directory, use this glob

    cc_import(
      ...
      hdrs = glob([
        "lib/my_test_lib/**/*.h",
      ]),
      ...
    )
    

    Beware: This will include all files below the specified directory, as expected. This can go out of hand since it's not explicit what files get included. Might be better to stay away from **.