[build2] How to achive a mini-monorepo project structure

Matt Armstrong matt at rfc20.org
Fri Jan 28 03:36:13 UTC 2022


I have a small but rapidly changing exploratory project, with a small
number of libraries and a small number of executables.  It is unlikely
that anybody else will ever use this code.  For this reason, I keep it
all in one git repository.

In other build systems, I have easily expressed this as a kind of
"mini-monorepo" structure: one version control repository, N libraries,
N binaries.

This is similar in Go, or even Python, where language level packages are
defined in part by directory structure.  C/C++ doesn't have that, but it
can be a useful intra-project organizational structure.

In Bazel, I would drop BUILD files in each directory, declare targets as
needed, and refer to them by their fully qualified paths (relative to
the workspace root).

In Meson, I have lower level libraries processed first, and refer to
targets by their global name.  The directory structure and meson.build
structure hardly matter, from the point of view of how Meson builds out
the Ninja config.

In build2, I have failed to express this project structure after two
attempts of carefully reading through the tutorial and honestly trying.
I must be missing something.  I feel like something that would be
trivial to do in a Makefile is probably possible in build2.  :-)

One thing I'll note is that the
https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml
does not cover this use case.  I can't find coverage of how one target
is built from another across directories.  There is great coverage for
producing and consuming packages, and for working with single-directory
packages, but multi-directory packages are thin.

In particular, I look at
https://build2.org/build2-toolchain/doc/build2-toolchain-intro.xhtml#guide-add-remove-deps
and it mentions four steps:

1. edit the `repositories.manifest`
2. edit the `manifest`
3. edit `buildfile`
4. edit the source code

I assume only 3 and 4 are needed for depending on things within a
project?

Interestingly, I got the same error as
https://github.com/build2/build2/issues/118, and found that issue with a
web search.

My repro is similar to the one in that issue, but uses --source instead
of --project:

```
$ bdep new -l c++ -t bare hello
$ cd hello
$ bdep new --source -l c++ -t lib libhello
$ bdep new --source -l c++ -t exe hello
$ bdep init -C @gcc cc config.cxx=g++
```

That builds, but if I uncomment this from `hello/buildfile`

```
# import libs += libhello%lib{hello}
```

I get the build error:

```
% b
synchronizing /tmp/scratch/hello-gcc/:
  upgrade hello/0.1.0-a.0.20220128023556
error: unable to import target libhello%lib{hello}
  info: use config.import.libhello configuration variable to specify its project out_root
info: while configuring hello
```

If I instead change `hello/buildfile` to look like this:

```
libs = libhello%lib{hello}
#import libs += libhello%lib{hello}

exe{hello}: {hxx ixx txx cxx}{**} $libs testscript

cxx.poptions =+ "-I$out_root" "-I$src_root"
```

I get the same error.

How can I teach b that hello/buildfile may use libhello from
libhello/buildfile?



More information about the users mailing list