I am trying to build Makefile of a submodule in a bazel project. I see that bazel does provide genrule to execute bash command. I am facing two issues currently -
1. How to cd into a directory before executing command, something like -
genrule(
name = "hello-make",
srcs = ["hello"] + glob(["hello/**"]),
outs = ["hello/main"],
cmd = "(cd $(location :hello) && make)",
)
2. How do I update update submodule before executing genrule?
Adding cmd = "(git submodule init && git submodule update)"
gives fatal: Not a git repository (or any of the parent directories): .git
Step to reproduce:
git clone [email protected]:bazelbuild/examples.git
cd examples/ && git submodule add [email protected]:mucsi96/cpp-hello-world.git cpp-tutorial/stage1/main/hello
cd cpp-tutorial/stage1/ && bazel build //main:hello-world
After this step I want to add a rule that allows me init, update and make the hello submodule.
Is there a better way to build [email protected]:mucsi96/cpp-hello-world.git
than creating it as a submodule of git clone [email protected]:bazelbuild/examples.git
?
The actual projects are more complex and creating a BUILD file for cpp-hello-world.git is not feasible.
Bazel works along the lines of other build tools like Make, Maven, or Gradle. However, unlike other tools which are framework-specific, Bazel is tailor-fit for projects with multi-language dependencies.
Bazel is fast and builds correctly - It can cache build results and only rebuild what it needs to, which make it fast. Its platform independent - It can run on Linux, macOS, Windows. Bazel scales - It can handle large source files easily. It works with various repositories and user bases in the tens of thousands.
A BUILD file contains several different types of instructions for Bazel. The most important type is the build rule, which tells Bazel how to build the desired outputs, such as executable binaries or libraries.
A User's Guide to Bazel. To run Bazel, go to your base workspace directory or any of its subdirectories and type bazel . % bazel help [Bazel release bazel-<version>] Usage: bazel <command> <options> ... Available commands: analyze-profile Analyzes build profile data.
Instead of rolling your own genrule
to build a (presumably C++) project that uses a Makefile
, check out rules_foreign_cc
instead. rules_foreign_cc
is used by envoy
and other various large C++ programs to build external CMake and Make based dependencies.
See the simple_make
example. In it, you would first make a filegroup
to collect all the sources and files related to the project to be built, including the Makefile
itself:
filegroup(
name = "sources",
srcs = glob(["**"]),
visibility = ["//simple_make:__subpackages__"],
)
Then, call rules_foreign_cc
's make
rule, which also comes with other make
-specific attributes like prefix
, make_env_vars
, and even a way to override the entire make
command with make_commands
. In this example, we're just using the lib_source
and static_libraries
attributes:
load("@rules_foreign_cc//tools/build_defs:make.bzl", "make")
make(
name = "make_lib",
lib_source = "//simple_make/code:sources",
static_libraries = ["liba.a"],
)
Finally, run bazel build //package/to:make_lib
to invoke the make
rule.
How do I update update submodule before executing genrule?
Try not to do this especially if it updates the sources of the project in-place. genrules
and other rules should not modify the state of your sources during a build, but instead only build output files. Consider running a separate script to update submodules prior to the build.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With