Search code examples
c++bazelbazel-cpp

Setting different preprocessor defines per source file in bazel cc_library


I'm trying to write bazel rules for a 3rd party library that specify different pre-processor define values per file i.e.

c++ ... -DVALUE=file1.cpp -c file1.cpp
c++ ... -DVALUE=file2.cpp -c file2.cpp
c++ ... -DVALUE=file3.cpp -c file3.cpp

This is basically set_property() on the file to add COMPILE_DEFINITIONS in CMake.

Using copts or local_defines for cc_library() doesn't seem to support this use case as they are common for all source files in the library.

The terrible ways to do this that I can think of:

  • have a private library per file and consolidate all of them to one library.
  • Patch the library or inject a header file using -include to add the definition.

Is there a better way to achieve this? Thanks!


Solution

  • The simplest approach to that is to just make a separate cc_library for each file, and then aggregate them together. Bazel isn't actually going to create a separate .a file in most configurations, so it doesn't change very much. A macro or list comprehension may be helpful to avoid copy/paste for the attribute values shared between all of the cc_libary targets.

    The other option is writing a custom rule. my_c_compile and my_c_archive are some basic examples, you could combine them pretty easily into a single rule that takes multiple source files and applies separate user_compile_flags to each. That seems like a lot of work though.

    Bazel also includes a full implementation of cc_library in Starlark which you could start from when writing a custom rule, but that's really complicated in many ways which you don't need. It's in src/main/starlark/builtins_bzl/common/cc/cc_library.bzl.