This minimal example C++ project uses the C/C++ rule
set for building a simple
helloworld
binary. Including a rule set requires the project to set up a
multi-repository configuration, because the
rule set is imported as an external repository.
Key takeaways from this example:
- Rule sets are imported as a separate repository
- Targets refer to other repositories via open names
- Building is done out-of-source
A minimal C/C++ project requires at least three files:
- C/C++ source file
TARGETS
file defining the Mustbuild targets- multi-repository configuration for importing the C/C++ rule set
2_cpp_min/ # Workspace root
|
├── helloworld.cpp # Application source
├── TARGETS # Mustbuild top-level targets
└── repos.json # Mustbuild multi-repository configuration
The multi-repository configuration repos.json
contains two
repositories:
example
: the helloworld example projectrules-cc
: the C/C++ rule set, fetched via Git from GitHub
{
"main": "example",
"repositories": {
"example": {
"repository": {"type": "file", "path": "."},
"bindings": {
"rules": "rules-cc"
}
},
"rules-cc": {
"repository": {
"type": "git",
"branch": "master",
"commit": "2ea50063460a3e11dfcbb71651540c0d61fddc1a",
"repository": "https://github.com/just-buildsystem/rules-cc",
"subdir": "rules"
}
}
}
}
The repository example
includes rules-cc
via bindings
, mapping it to the
generic open name rules
.
┌─────────────────┐ rules ┌─────────────────┐
│ example |<─────────┤ rules-cc |
└─────────────────┘ └─────────────────┘
Open names are a way to refer to other repositories without using their actual
names. In this case, targets from example
can refer to rules-cc
via the
generic name rules
.
The actual targets are described in the TARGETS
file. It contains
a single target helloworld
, implemented using the rule
["CC","binary"]
from repository rules
(which is the open name for repository rules-cc
).
{
// Target "helloworld"
helloworld: {
// Use rule ["CC", "binary"] from binding "rules"
type: ref_ext('rules', 'CC', 'binary'),
// Binary name: "helloworld"
name: 'helloworld',
// Source files
srcs: ['helloworld.cpp'],
},
}
To build the project, run must build
. By default, Must will build the
lexicographical first target in the top-level TARGETS
file. In this case, the
helloworld
target.
$ must build
INFO: Found 2 repositories to set up
INFO: Requested target is [["@","example","","helloworld"],{}]
INFO: Discovered 2 actions, 1 trees, 0 blobs
INFO: Processed 2 actions, 0 cache hits.
INFO: Artifacts built, logical paths are:
helloworld [1673e4d63deb6580f81fb57d8a5276abe2ae8bd3:16384:x]
Building the target will not pollute the source directory. In order to obtain
the binary for execution, you first need to install
it to the desired output
directory. Note that there is no rebuild happening as all actions are served
from cache.
$ must install -o .
INFO: Found 2 repositories to set up
INFO: Requested target is [["@","example","","helloworld"],{}]
INFO: Discovered 2 actions, 1 trees, 0 blobs
INFO: Processed 2 actions, 2 cache hits.
INFO: Artifacts built, logical paths are:
./helloworld [1673e4d63deb6580f81fb57d8a5276abe2ae8bd3:16384:x]
$ ./helloworld
Hello World!