2023-01-18 07:21:58 +00:00
|
|
|
# Dependency Management in Prysm
|
2020-05-31 06:44:34 +00:00
|
|
|
|
|
|
|
Prysm is go project with many complicated dependencies, including some c++ based libraries. There
|
|
|
|
are two parts to Prysm's dependency management. Go modules and bazel managed dependencies. Be sure
|
|
|
|
to read [Why Bazel?](https://github.com/prysmaticlabs/documentation/issues/138) to fully
|
|
|
|
understand the reasoning behind an additional layer of build tooling via Bazel rather than a pure
|
|
|
|
"go build" project.
|
|
|
|
|
|
|
|
## Go Module support
|
|
|
|
|
|
|
|
The Prysm project officially supports go modules with some caveats.
|
|
|
|
|
|
|
|
### Caveat 1: Some c++ libraries are precompiled archives
|
|
|
|
|
|
|
|
Given some of Prysm's c++ dependencies have very complicated project structures which make building
|
|
|
|
difficult or impossible with "go build" alone. Additionally, building c++ dependencies with certain
|
|
|
|
compilers, like clang / LLVM, offer a significant performance improvement. To get around this
|
|
|
|
issue, c++ dependencies have been precompiled as linkable archives. While there isn't necessarily
|
|
|
|
anything bad about precompiled archives, these files are a "blackbox" which a 3rd party author
|
|
|
|
could have compiled anything for this archive and detecting undesired behavior would be nearly
|
|
|
|
impossible. If your risk tolerance is low, always compile everything from source yourself,
|
|
|
|
including complicated c++ dependencies.
|
|
|
|
|
|
|
|
*Recommendation: Use go build only for local development and use bazel build for production.*
|
|
|
|
|
|
|
|
### Caveat 2: Generated gRPC protobuf libraries
|
|
|
|
|
|
|
|
One key advantage of Bazel over vanilla `go build` is that Bazel automatically (re)builds generated
|
|
|
|
pb.go files at build time when file changes are present in any protobuf definition file or after
|
|
|
|
any updates to the protobuf compiler or other relevant dependencies. Vanilla go users should run
|
2023-01-18 07:21:58 +00:00
|
|
|
the following scripts often to ensure their generated files are up to date. Furthermore, Prysm
|
2020-05-31 06:44:34 +00:00
|
|
|
generates SSZ marshal related code based on defined data structures. These generated files must
|
|
|
|
also be updated and checked in as frequently.
|
|
|
|
|
|
|
|
```bash
|
2021-09-16 16:22:39 +00:00
|
|
|
./hack/update-go-pbs.sh
|
|
|
|
./hack/update-go-ssz.sh
|
2020-05-31 06:44:34 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
*Recommendation: Use go build only for local development and use bazel build for production.*
|
|
|
|
|
|
|
|
### Caveat 3: Compile-time optimizations
|
|
|
|
|
|
|
|
When Prysmatic Labs builds production binaries, they use the "release" configuration of bazel to
|
|
|
|
compile with several compiler optimizations and recommended production build configurations.
|
|
|
|
Additionally, the release build properly stamps the built binaries to include helpful metadata
|
|
|
|
about how and when the binary was built.
|
|
|
|
|
|
|
|
*Recommendation: Use go build only for local development and use bazel build for production.*
|
|
|
|
|
|
|
|
```bash
|
|
|
|
bazel build //beacon-chain --config=release
|
|
|
|
```
|
|
|
|
|
|
|
|
## Adding / updating dependencies
|
|
|
|
|
|
|
|
1. Add your dependency as you would with go modules. I.e. `go get ...`
|
2024-02-01 15:42:56 +00:00
|
|
|
1. Run `bazel run //:gazelle -- update-repos -from_file=go.mod` to update the bazel managed dependencies.
|
2020-05-31 06:44:34 +00:00
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
go get github.com/prysmaticlabs/example@v1.2.3
|
2020-11-13 04:32:15 +00:00
|
|
|
bazel run //:gazelle -- update-repos -from_file=go.mod -to_macro=deps.bzl%prysm_deps -prune=true
|
2020-05-31 06:44:34 +00:00
|
|
|
```
|
|
|
|
|
|
|
|
The deps.bzl file should have been updated with the dependency and any transitive dependencies.
|
|
|
|
|
|
|
|
Do NOT add new `go_repository` to the WORKSPACE file. All dependencies should live in deps.bzl.
|
2021-01-04 20:48:39 +00:00
|
|
|
|
|
|
|
## Running tests
|
|
|
|
|
|
|
|
To enable conditional compilation and custom configuration for tests (where compiled code has more
|
|
|
|
debug info, while not being completely optimized), we rely on Go's build tags/constraints mechanism
|
|
|
|
(see official docs on [build constraints](https://golang.org/pkg/go/build/#hdr-Build_Constraints)).
|
|
|
|
Therefore, whenever using `go test`, do not forget to pass in extra build tag, eg:
|
|
|
|
|
|
|
|
```bash
|
|
|
|
go test ./beacon-chain/sync/initial-sync -tags develop
|
|
|
|
```
|