Skip to content

Commit f5b75ea

Browse files
committed
Add system integration and make all dependencies lazy
1 parent f5ba79c commit f5b75ea

3 files changed

Lines changed: 85 additions & 41 deletions

File tree

‎README.md‎

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@
1111
|:---------|:------------------------|-------------:|:------------:|:------------:|:------------:|
1212
| `master` | `v1.85.0-pre1` "googol" | `58.0.0` | ✅ | ✅ | ✅ |
1313
| `1.84.0` | `v1.84.0` "gimbal" | `56.0.0` | ✅ | ✅ | ✅ |
14-
| `1.83.1` | `v1.83.1` "garden" | `56.0.0` | ✅ | ✅ | ✅ |
1514

1615
<details>
1716
<summary>Older versions</summary>
1817

1918
| Refname | libGRPC version | Core version | Zig `0.17.x` | Zig `0.16.x` | Zig `0.15.x` |
2019
|:-----------|:-----------------------|-------------:|:------------:|:------------:|:------------:|
20+
| `1.83.1` | `v1.83.1` "garden" | `56.0.0` | ✅ | ✅ | ✅ |
2121
| `1.82.2` | `v1.82.2` "glacier" | `55.0.0` | ✅ | ✅ | ✅ |
2222
| `1.81.1` | `v1.81.1` "graphic" | `54.0.0` | ✅ | ✅ | ✅ |
2323
| `1.80.0` | `v1.80.0` "glimmering" | `53.0.0` | ✅ | ✅ | ✅ |
@@ -46,7 +46,11 @@ const grpc = b.dependency("grpc", .{
4646
mod.addImport("cgrpc", grpc.module("cgrpc"));
4747
4848
// to use from C:
49-
exe.linkLibrary(grpc.artifact("grpc"));
49+
if (b.systemIntegrationOption("grpc", .{})) {
50+
exe.root_module.linkSystemLibrary("grpc", .{});
51+
} else {
52+
exe.root_module.linkLibrary(grpc.artifact("grpc"));
53+
}
5054
```
5155

5256
## Options
@@ -58,3 +62,20 @@ exe.linkLibrary(grpc.artifact("grpc"));
5862
dynamic
5963
-Dpic=[bool] Produce Position Independent Code. Defaults to true when link_mode is dynamic
6064
```
65+
66+
## System Integration
67+
68+
By default, libgrpc is built from source, to allow cross-compilation and reproducibility.
69+
70+
However, for security reason, or to not waste disk / CPU / time re-compiling a huge library already installed on the system, it might be preferable to use the system's `.so`/`.dylib`
71+
72+
For this purpose, a system integration is available. When building the final binary:
73+
74+
```shell
75+
zig build -fsys=grpc
76+
```
77+
78+
will use the system's gRPC library. The `cgrpc` module then links it, and none of the sources libgrpc is built from get fetched.
79+
80+
The `grpc` artifact is not available in this mode, which is why C users check the same option, as shown in [Use](#use).
81+
As system integration options are shared by the whole build, they get the same answer as this package.

‎build.zig‎

Lines changed: 55 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -18,14 +18,61 @@ pub fn build(b: *Build) !void {
1818
"Produce Position Independent Code. Defaults to true when link_mode is dynamic",
1919
) orelse (linkmode == .dynamic);
2020

21-
// Dependencies
22-
const upstream = b.dependency("upstream", .{});
23-
const abseil = b.dependency("abseil", .{});
24-
const re2 = b.dependency("re2", .{});
25-
const boringssl = b.dependency("boringssl", .{});
26-
const cares = b.dependency("cares", .{});
27-
const gtest = b.dependency("gtest", .{});
28-
const zlib = b.dependency("zlib", .{});
21+
// Generate bindings from grpc C headers
22+
const include_all = b.addWriteFile("grpc_api.h",
23+
\\#include <grpc/grpc.h>
24+
\\#include <grpc/credentials.h>
25+
\\#include <grpc/byte_buffer_reader.h>
26+
);
27+
const grpc_capi = b.addTranslateC(.{
28+
.root_source_file = try include_all.getDirectory().join(b.allocator, "grpc_api.h"),
29+
.target = target,
30+
.optimize = optimize,
31+
});
32+
const bindings = grpc_capi.addModule("cgrpc");
33+
34+
if (b.systemIntegrationOption("grpc", .{})) {
35+
bindings.linkSystemLibrary("grpc", .{});
36+
return;
37+
}
38+
39+
// Core library, declared before the dependencies are known to be available,
40+
// so that packages depending on this one can always find it
41+
const grpc = b.createModule(.{
42+
.target = target,
43+
.optimize = optimize,
44+
.link_libcpp = true,
45+
.pic = pic,
46+
});
47+
const libgrpc = b.addLibrary(.{
48+
.name = "grpc",
49+
.root_module = grpc,
50+
.linkage = linkmode,
51+
.version = file_lists.core_version,
52+
});
53+
b.installArtifact(libgrpc);
54+
bindings.linkLibrary(libgrpc);
55+
56+
// Dependencies, lazy as they are not needed when using the system's libgrpc.
57+
// They are all requested before returning, so that missing ones are fetched together
58+
const deps = .{
59+
.upstream = b.lazyDependency("upstream", .{}),
60+
.abseil = b.lazyDependency("abseil", .{}),
61+
.re2 = b.lazyDependency("re2", .{}),
62+
.boringssl = b.lazyDependency("boringssl", .{}),
63+
.cares = b.lazyDependency("cares", .{}),
64+
.gtest = b.lazyDependency("gtest", .{}),
65+
.zlib = b.lazyDependency("zlib", .{}),
66+
};
67+
const upstream = deps.upstream orelse return;
68+
const abseil = deps.abseil orelse return;
69+
const re2 = deps.re2 orelse return;
70+
const boringssl = deps.boringssl orelse return;
71+
const cares = deps.cares orelse return;
72+
const gtest = deps.gtest orelse return;
73+
const zlib = deps.zlib orelse return;
74+
75+
grpc_capi.addIncludePath(upstream.path("include"));
2976

3077
const libs_step = b.step("dependencies", "Install libraries libgrpc depends on");
3178

@@ -201,19 +248,6 @@ pub fn build(b: *Build) !void {
201248
libs_step.dependOn(&b.addInstallArtifact(libre2, .{}).step);
202249

203250
// Core library
204-
const grpc = b.createModule(.{
205-
.target = target,
206-
.optimize = optimize,
207-
.link_libcpp = true,
208-
.pic = pic,
209-
});
210-
const libgrpc = b.addLibrary(.{
211-
.name = "grpc",
212-
.root_module = grpc,
213-
.linkage = linkmode,
214-
.version = file_lists.core_version,
215-
});
216-
217251
grpc.addCSourceFiles(.{
218252
.root = upstream.path("src/core"),
219253
.files = &file_lists.libgrpc_src_core_cpp,
@@ -237,7 +271,6 @@ pub fn build(b: *Build) !void {
237271
grpc.addCMacro("OSATOMIC_USE_INLINED", "1");
238272
}
239273
libgrpc.installHeadersDirectory(upstream.path("include/grpc"), "grpc", .{});
240-
b.installArtifact(libgrpc);
241274

242275
{ // Build tests to ensure no symbols are missing
243276
const example_step = b.step("examples", "Build example programs");
@@ -355,23 +388,6 @@ pub fn build(b: *Build) !void {
355388
test_step.dependOn(&run_exe.step);
356389
}
357390
}
358-
359-
{ // Generate bindings from grpc C headers
360-
const include_all = b.addWriteFile("grpc_api.h",
361-
\\#include <grpc/grpc.h>
362-
\\#include <grpc/credentials.h>
363-
\\#include <grpc/byte_buffer_reader.h>
364-
);
365-
const grpc_capi = b.addTranslateC(.{
366-
.root_source_file = try include_all.getDirectory().join(b.allocator, "grpc_api.h"),
367-
.target = target,
368-
.optimize = optimize,
369-
});
370-
grpc_capi.addIncludePath(upstream.path("include"));
371-
372-
const bindings = grpc_capi.addModule("cgrpc");
373-
bindings.linkLibrary(libgrpc);
374-
}
375391
}
376392

377393
const common_flags = .{ "-Wall", "-Wextra" };

‎build.zig.zon‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,30 +16,37 @@
1616
.upstream = .{
1717
.url = "git+https://github.com/grpc/grpc?ref=v1.85.0-pre1#cc11ee7e32957382ec96ce02065aa870b7089323",
1818
.hash = "N-V-__8AAL0I3gSsV3C-0ndgBSMMHLly3A8CgeNx1x8Gk1dK",
19+
.lazy = true,
1920
},
2021
.abseil = .{
2122
.url = "git+https://github.com/abseil/abseil-cpp?ref=20260526.0#5650e9cf76d3be4318d5fa3af38ee483ddfd5e4a",
2223
.hash = "N-V-__8AAG4nrQCLR5Wb9-U86e2atvr8nnVn9jWxR4WYNmMg",
24+
.lazy = true,
2325
},
2426
.re2 = .{
2527
.url = "git+https://github.com/google/re2?ref=2022-04-01#0c5616df9c0aaa44c9440d87422012423d91c7d1",
2628
.hash = "N-V-__8AAGxoGACubi_UB9NHSdrrXU_eABgvR1IT1kRFFCuG",
29+
.lazy = true,
2730
},
2831
.boringssl = .{
2932
.url = "git+https://github.com/google/boringssl?ref=0.20260616.0#3adc3d1aba162a578e2547f329fcce8659b8e89c",
3033
.hash = "N-V-__8AAJPC0g0KEU0dz7Kq2qSZ-IRfZhgtn9MblCkh-5pa",
34+
.lazy = true,
3135
},
3236
.cares = .{
3337
.url = "git+https://github.com/c-ares/c-ares?ref=v1.34.5#d3a507e920e7af18a5efb7f9f1d8044ed4750013",
3438
.hash = "N-V-__8AAP0uLwAKiOH9FxdgMWWuzaL-7u5T1YLelhgQ41nA",
39+
.lazy = true,
3540
},
3641
.gtest = .{
3742
.url = "git+https://github.com/google/googletest?ref=v1.17.0#52eb8108c5bdec04579160ae17225d66034bd723",
3843
.hash = "N-V-__8AAEV8PgDOBc81AuVJQ9XhGo46f-4dlQ7sXar_M0_i",
44+
.lazy = true,
3945
},
4046
.zlib = .{
4147
.url = "git+https://github.com/madler/zlib?ref=v1.3.1#51b7f2abdade71cd9bb0e7a373ef2610ec6f9daf",
4248
.hash = "N-V-__8AAB0eQwD-0MdOEBmz7intriBReIsIDNlukNVoNu6o",
49+
.lazy = true,
4350
},
4451
},
4552
}

0 commit comments

Comments
 (0)