Skip to content

Commit dc89433

Browse files
Update documentation for out-of-tree use
1 parent 1f9e3d5 commit dc89433

File tree

2 files changed

+109
-33
lines changed

2 files changed

+109
-33
lines changed

zirgen/docs/01_Getting_Started.md

Lines changed: 108 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,52 +1,128 @@
11
# Getting Started
22

33
We don't currently release Zirgen in any packaged form, so it's only available
4-
through this repository. Assuming you've cloned and built things from this repo
5-
before, building Zirgen with Bazel is simple with the following command. Note,
6-
though, that this isn't strictly necessary, and that Bazel will automatically
7-
(re)build Zirgen if you use it to invoke the tests as well.
4+
through this repository. This guide assumes you're using Bazel as your build
5+
system, and want to use Zirgen "out of tree" from a separate project.
86

7+
8+
# Project structure
9+
10+
## Pulling in the Zirgen compiler
11+
12+
From a fresh project directory, we're going to need to create three build
13+
configuration files. First, create a `.bazelrc` file, and put the following two
14+
lines in it. These are necessary to ensure MLIR, one of Zirgen's dependencies,
15+
compiles correctly.
916
```
10-
bazel build //zirgen/dsl:zirgen
17+
build --cxxopt=-std=c++17
18+
build --host_cxxopt=-std=c++17
1119
```
1220

13-
## Hello world!
21+
Second, we need to pin our Bazel version. Zirgen is currently built with Bazel
22+
6.0, so we recommend creating a `.bazelversion` file with the following content.
23+
If you want to use a different version of Bazel for any reason, your mileage may
24+
vary.
25+
```
26+
6.0.0
27+
```
1428

15-
Following in the footsteps of our forebears, let's take a look at a classic
16-
"Hello world" program. This program is already available as a test and example,
17-
so we can run it with the following command from the root of this repository:
29+
Third, create a `WORKSPACE` file. This is a Bazel configuration file that deals
30+
with "global" configurations like project dependencies, and this is where we're
31+
going to define how to pull in the Zirgen compiler:
32+
```
33+
workspace(name = "zirgen-oot")
34+
35+
load("@bazel_tools//tools/build_defs/repo:git.bzl", "git_repository")
36+
37+
git_repository(
38+
name = "zirgen",
39+
branch = "main", # feel free to pin a particular commit instead for stability!
40+
remote = "https://github.com/risc0/zirgen.git",
41+
)
42+
43+
load("@zirgen//bazel/rules/zirgen:deps.bzl", "zirgen_dependencies")
44+
zirgen_dependencies()
45+
46+
# configure transitive dependencies
47+
load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
48+
bazel_skylib_workspace()
49+
50+
load("@llvm-raw//utils/bazel:configure.bzl", "llvm_configure")
51+
llvm_configure(name = "llvm-project")
52+
```
1853

54+
At this point, it should be possible to build the Zirgen compiler, which might
55+
take a few minutes but only needs to be done once:
1956
```
20-
$ bazel run //zirgen/dsl:zirgen -- $(pwd)/zirgen/dsl/test/hello_world.zir --test
21-
...
22-
Running 0
23-
[0] Log: Hello world!
24-
Lookups resolved
57+
bazel build @zirgen//zirgen/dsl:zirgen
2558
```
2659

27-
This command passes two arguments to the Zirgen executable. The first,
28-
`$(pwd)/zirgen/dsl/test/hello_world.zir`, specifies the path of the Zirgen file
29-
we want to run on. The second, `--test`, specifies that we want to run all the
30-
tests defined in the file we're running. Typically, the output of Zirgen is a
31-
generated Rust or C++ library that then needs to be integrated with the RISC
32-
Zero proof system. For the sake of simplicity here and as a useful practice
33-
during the development, it is easiest to experiment with Zirgen by writing tests
34-
alongside your circuit code, which can be run in the builtin interpreter without
35-
doing this integration work using the `--test` option. Now, the important part
36-
of the file is the following:
60+
## Setting up your new circuit
3761

62+
Now that the compiler is set up, we just need to start the new circuit. Create a
63+
new directory called `circuit`; the name is not important, but consistency is
64+
key! In this directory, create a new file called `circuit.zir`, and include the
65+
following code:
3866
```
39-
test {
40-
Log("Hello world!");
67+
test Hello {
68+
Log("Hello world!");
4169
}
4270
```
4371

44-
The keyword `test` declares that the thing that follows (enclosed in curly
45-
braces) is a test. Tests can be given an optional name, but if they aren't named
46-
then they are labeled with sequential numbers. This causes the text "Running 0"
47-
to be written to stdout, marking the beginning of the execution of that test.
48-
The statement `Log("Hello world!");` is what causes the text "[0] Log: Hello
49-
world!" to be written to stdout.
72+
Next, add a `BUILD.bazel` file in the same directory, and add the following to
73+
it to configure a new build rule that generates Rust code for the circuit.
74+
```
75+
load("@zirgen//bazel/rules/zirgen:dsl-defs.bzl", "zirgen_genfiles")
76+
77+
filegroup(
78+
name = "imports",
79+
srcs = glob(["*.zir"]),
80+
)
81+
82+
zirgen_genfiles(
83+
name = "CircuitIncs",
84+
zir_file = ":circuit.zir",
85+
data = [":imports"],
86+
zirgen_outs = [
87+
(
88+
["--emit=rust"],
89+
"circuit.rs.inc",
90+
),
91+
],
92+
)
93+
```
94+
95+
## Hello world!
96+
97+
Now with everything set up, we're ready to run the new circuit. The output of
98+
the Zirgen compiler is generated code that can then be called by 0STARK to
99+
generate real proofs. Our circuit is so trivial that there's not really much to
100+
generate, but it can be done with the following Bazel command, which will place
101+
the code in the Bazel build directory:
102+
```
103+
bazel build //circuit:GenerateCircuitIncs
104+
```
105+
106+
Of more immediate interest, it's also possible to test and debug circuits using
107+
a built-in interpreter. This doesn't generate real proofs, but it does make it
108+
easy to try things out as you go along. To run our circuit in the interpreter:
109+
```
110+
bazel run @zirgen//zirgen/dsl:zirgen -- $(pwd)/circuit/circuit.zir --test
111+
```
112+
> ```
113+
> Running Hello
114+
> [0] Log: Hello world!
115+
> Lookups resolved
116+
> Verifying constraints for Hello
117+
> Verifying zll constraints for Hello
118+
> ```
119+
120+
This command invokes the Zirgen compiler through Bazel. Everything after `--` is
121+
passed directly to the `zirgen` executable as a command line option: the first
122+
argument indicates the "main" file of the circuit. The `--test` indicates that
123+
all the tests in the source code should be run in the interpreter. In this case,
124+
our code has one test named `Hello`, and it logs the string "Hello world!" on
125+
cycle zero. And presto! We've set up, written, and run a brand-new circuit!
50126
51127
[Prev](README.md)
52128
[Next](02_Conceptual_Overview.md)

zirgen/docs/03_Building_a_Fibonacci_Circuit.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ component Top() {}
1919
```
2020

2121
Next, we need to tell Bazel about our new circuit, and tell it how to build our
22-
project. Create a `Build.bazel` file in the same directory as our new circuit
22+
project. Create a `BUILD.bazel` file in the same directory as our new circuit
2323
source file, with these contents:
2424

2525
```

0 commit comments

Comments
 (0)