Search code examples
c++buildbazelbazel-rules

One Bazel project produces binary and static library files, another similar project only produces binary files


I am attempting to learn Bazel so I've been using it to build very simple projects in order to understand how it works and some of the ins and outs of the tool.

Currently, I have 1 project (called Enigma) that builds a main.cpp file that relies on a couple of libraries I wrote (I wrote it this way to understand the Bazel rules better, in this particular project it doesn't really make sense to have these libraries, but I digress). When I run the build, I can check my bazel-bin directory and find:

  1. a binary file produced by my cc_binary rule
  2. a static library (*.a) file for one of the cc_library rules I implemented

This makes sense to me. I started a new project, LinkedList that I wanted to build just as a library. From some troubleshooting and research, I decided I needed a rule that depends on that cc_library rule in order for Bazel to actually build it, so I created another main.cpp. When I run the build, I only get a binary from my cc_binary rule, but no *.a files from my cc_library rule. I've examined both the BUILD files I have and cannot find anything glaringly different about them. Both projects' WORKSPACE files are empty and neither project has a .bazelrc file.

Here are the contents of my Enigma BUILD file (which produces libsignal_converter.a in the bazel-bin directory):

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")

cc_binary(
    name = "enigma",
    srcs = [ "main.cpp" ],
    deps = [ ":rotor", ":plugboard" ]
)

cc_library(
    name = "signal_converter",
    srcs = [ "signal_converter.cpp" ],
    hdrs = [ "signal_converter.h" ],
    includes = [ "." ]
)

cc_library(
    name = "plugboard",
    hdrs = [ "plugboard.h" ],
    includes = [ "." ],
    deps = [ ":signal_converter" ]
)

cc_library(
    name = "rotor",
    hdrs = [ "rotor.h" ],
    includes = [ "." ],
    deps = [ ":signal_converter" ]
)

Here are the contents of the bazel-bin directory of the Enigma project:

 _objs
 enigma
 enigma-2.params
 enigma.cppmap
 enigma.runfiles
 enigma.runfiles_manifest
 libsignal_converter.a
 libsignal_converter.a-2.params
 plugboard.cppmap
 rotor.cppmap
 signal_converter.cppmap
 tests.cppmap

Here is the contents of my LinkedList BUILD file, which only produces a binary:

load("@rules_cc//cc:defs.bzl", "cc_binary", "cc_library")

cc_binary(
    name = "dummymain",
    srcs = [ "main.cpp" ],
    deps = [ ":linkedlist" ]
)

cc_library(
    name = "linkedlist",
    hdrs = [ "node.h", "linked_list.h" ]
)

And here are the contents of the bazel-bin directory of the LinkedList project:

 _objs
 dummymain
 dummymain-2.params
 dummymain.cppmap
 dummymain.runfiles
 dummymain.runfiles_manifest
 linkedlist.cppmap

Just in case, I made sure to include my libraries in the main.cpp file and initialize an instance of each class. I get the typical "unused variable" warning, but aside from that it builds and runs as expected.

My question is why does my Enigma project produce *.a files but my LinkedList project does not?

How can I configure my build such that it produces *.a (or *.so) library files with or without a cc_binary rule that depends on them?

What I've tried: At first, my LinkedList project BUILD file only contained a cc_library rule. I believe that Bazel was not building that target (despite me running bazel build //src:linkedlist) because no other rules depended on it and it was a library target (although I feel like I am wrong about that assumption). To remedy that, I created a main.cpp file with a cc_binary rule to accompany it. This seems to trigger a build of the linkedlist target, but I still do not see any library files in my bazel-bin. I would have expected it to produce a statically linked binary as well as the static library (*.a) files but all I get is the binary file.


Solution

  • The "plugboard", "rotor", and "linkedlist" targets contain only header files. There are no files directly compiled in those libraries. Therefore, Bazel suppresses the creation of static archives for those libraries.