Skip to content

Commit 005f79f

Browse files
committed
Zig build support added (>= 0.13.0)
1 parent a2d0be9 commit 005f79f

File tree

3 files changed

+239
-0
lines changed

3 files changed

+239
-0
lines changed

.github/workflows/zig-ci.yml

+38
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
name: Zig-CI
2+
3+
on: [push, pull_request]
4+
5+
jobs:
6+
build:
7+
strategy:
8+
fail-fast: false
9+
matrix:
10+
runs-on: [ubuntu-latest, macos-latest, windows-latest]
11+
runs-on: ${{ matrix.runs-on }}
12+
steps:
13+
- uses: actions/checkout@v4
14+
- uses: mlugg/setup-zig@v1
15+
with:
16+
version: master
17+
- name: (Zig) Build
18+
run: zig build --summary all -Dexamples -freference-trace
19+
20+
cross:
21+
runs-on: ubuntu-latest
22+
strategy:
23+
fail-fast: false
24+
matrix:
25+
targets:
26+
- aarch64-linux-gnu
27+
- mipsel-linux-musl
28+
- aarch64-linux-musl
29+
- riscv64-linux-musl
30+
- x86_64-linux-musl
31+
- x86-linux-musl
32+
steps:
33+
- uses: actions/checkout@v4
34+
- uses: mlugg/setup-zig@v1
35+
with:
36+
version: master
37+
- name: Build Summary ${{ matrix.targets }}
38+
run: zig build --summary all -Dexamples -freference-trace -Dtarget=${{ matrix.targets }}

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,4 @@ tools/doc/man-date.ent
7575
.cache/
7676
compile_commands.json
7777
codegen/
78+
*zig-*/

build.zig

+200
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,200 @@
1+
const std = @import("std");
2+
3+
const rmq_version: std.SemanticVersion = .{
4+
.major = 0,
5+
.minor = 15,
6+
.patch = 0,
7+
};
8+
9+
pub fn build(b: *std.Build) void {
10+
const target = b.standardTargetOptions(.{});
11+
const optimize = b.standardOptimizeOption(.{});
12+
13+
const ssl = b.option(bool, "ssl", "Build with SSL support") orelse false;
14+
const shared = b.option(bool, "shared", "Build shared library") orelse false;
15+
const examples = b.option(bool, "examples", "Build examples") orelse false;
16+
17+
const generated_export_header = b.addWriteFile("rabbitmq-c/export.h", export_h);
18+
19+
const lib = if (shared) b.addSharedLibrary(.{
20+
.name = "rabbitmq-c",
21+
.target = target,
22+
.optimize = optimize,
23+
.version = rmq_version,
24+
}) else b.addStaticLibrary(.{
25+
.name = "rabbitmq-c-static",
26+
.target = target,
27+
.optimize = optimize,
28+
.version = rmq_version,
29+
});
30+
if (!shared) {
31+
lib.pie = true;
32+
lib.defineCMacro("AMQP_STATIC", "");
33+
}
34+
const configH = b.addConfigHeader(.{
35+
.style = .blank,
36+
.include_path = "config.h",
37+
}, .{
38+
.HAVE_SELECT = if (lib.rootModuleTarget().os.tag == .windows) {} else null,
39+
.HAVE_POLL = if (lib.rootModuleTarget().os.tag != .windows) {} else null,
40+
.AMQ_PLATFORM = switch (lib.rootModuleTarget().os.tag) {
41+
.linux => "Linux",
42+
.macos => "Darwin",
43+
.windows => "Win32",
44+
else => @panic("Unsupported platform"),
45+
},
46+
.ENABLE_SSL_ENGINE_API = if (ssl) {} else null,
47+
});
48+
lib.defineCMacro("HAVE_CONFIG_H", null);
49+
lib.addConfigHeader(configH);
50+
lib.addIncludePath(generated_export_header.getDirectory());
51+
lib.addIncludePath(b.path("include"));
52+
lib.addIncludePath(b.path("librabbitmq"));
53+
if (lib.rootModuleTarget().os.tag == .windows) {
54+
lib.addIncludePath(b.path("librabbitmq/win32"));
55+
lib.addCSourceFile(.{
56+
.file = b.path("librabbitmq/win32/threads.c"),
57+
});
58+
lib.linkSystemLibrary("ws2_32");
59+
} else lib.addIncludePath(b.path("librabbitmq/unix"));
60+
lib.addCSourceFiles(.{
61+
.root = b.path("librabbitmq"),
62+
.files = &.{
63+
"amqp_api.c", "amqp_connection.c", "amqp_consumer.c", "amqp_framing.c",
64+
"amqp_mem.c", "amqp_socket.c", "amqp_table.c", "amqp_tcp_socket.c",
65+
"amqp_time.c", "amqp_url.c",
66+
},
67+
});
68+
if (ssl) {
69+
lib.addCSourceFiles(.{
70+
.root = b.path("librabbitmq"),
71+
.files = &.{
72+
"amqp_openssl.c",
73+
"amqp_openssl_bio.c",
74+
},
75+
});
76+
lib.linkSystemLibrary("ssl");
77+
lib.linkSystemLibrary("crypto");
78+
}
79+
lib.linkLibC();
80+
lib.installHeadersDirectory(b.path("include"), "", .{});
81+
b.installArtifact(lib);
82+
83+
if (examples) {
84+
inline for (&.{
85+
"amqp_bind.c",
86+
if (ssl)
87+
"amqp_ssl_connect.c"
88+
else
89+
"amqp_connect_timeout.c",
90+
"amqp_consumer.c",
91+
"amqp_exchange_declare.c",
92+
"amqp_listen.c",
93+
"amqp_listenq.c",
94+
"amqp_producer.c",
95+
"amqp_rpc_sendstring_client.c",
96+
"amqp_sendstring.c",
97+
"amqp_unbind.c",
98+
}) |file| {
99+
buildExamples(b, .{
100+
.name = file[0 .. file.len - 2],
101+
.filepaths = &.{file},
102+
.target = target,
103+
.optimize = optimize,
104+
.lib = lib,
105+
});
106+
}
107+
}
108+
}
109+
110+
const buildOptions = struct {
111+
name: []const u8,
112+
target: std.Build.ResolvedTarget,
113+
optimize: std.builtin.OptimizeMode,
114+
filepaths: []const []const u8,
115+
lib: *std.Build.Step.Compile,
116+
};
117+
118+
fn buildExamples(b: *std.Build, options: buildOptions) void {
119+
const example = b.addExecutable(.{
120+
.name = options.name,
121+
.target = options.target,
122+
.optimize = options.optimize,
123+
});
124+
for (options.lib.root_module.include_dirs.items) |include_dir| {
125+
example.root_module.include_dirs.append(b.allocator, include_dir) catch unreachable;
126+
}
127+
example.addIncludePath(b.path("examples"));
128+
example.addCSourceFile(.{
129+
.file = b.path("examples/utils.c"),
130+
});
131+
if (example.rootModuleTarget().os.tag == .windows)
132+
example.addCSourceFile(.{
133+
.file = b.path("examples/win32/platform_utils.c"),
134+
})
135+
else
136+
example.addCSourceFile(.{
137+
.file = b.path("examples/unix/platform_utils.c"),
138+
});
139+
example.addCSourceFiles(.{
140+
.root = b.path("examples"),
141+
.files = options.filepaths,
142+
});
143+
example.linkLibrary(options.lib);
144+
example.linkLibC();
145+
b.installArtifact(example);
146+
147+
const run_cmd = b.addRunArtifact(example);
148+
run_cmd.step.dependOn(b.getInstallStep());
149+
if (b.args) |args| {
150+
run_cmd.addArgs(args);
151+
}
152+
const run_step = b.step(options.name, b.fmt("Run the {s} example", .{options.name}));
153+
run_step.dependOn(&run_cmd.step);
154+
}
155+
156+
const export_h =
157+
\\ #ifndef RABBITMQ_C_EXPORT_H
158+
\\ #define RABBITMQ_C_EXPORT_H
159+
\\
160+
\\ #ifdef AMQP_STATIC
161+
\\ # define AMQP_EXPORT
162+
\\ # define AMQP_NO_EXPORT
163+
\\ #else
164+
\\ # ifndef AMQP_EXPORT
165+
\\ # ifdef rabbitmq_EXPORTS
166+
\\ /* We are building this library */
167+
\\ # define AMQP_EXPORT __attribute__((visibility("default")))
168+
\\ # else
169+
\\ /* We are using this library */
170+
\\ # define AMQP_EXPORT __attribute__((visibility("default")))
171+
\\ # endif
172+
\\ # endif
173+
\\
174+
\\ # ifndef AMQP_NO_EXPORT
175+
\\ # define AMQP_NO_EXPORT __attribute__((visibility("hidden")))
176+
\\ # endif
177+
\\ #endif
178+
\\
179+
\\ #ifndef AMQP_DEPRECATED
180+
\\ # define AMQP_DEPRECATED __attribute__ ((__deprecated__))
181+
\\ #endif
182+
\\
183+
\\ #ifndef AMQP_DEPRECATED_EXPORT
184+
\\ # define AMQP_DEPRECATED_EXPORT AMQP_EXPORT AMQP_DEPRECATED
185+
\\ #endif
186+
\\
187+
\\ #ifndef AMQP_DEPRECATED_NO_EXPORT
188+
\\ # define AMQP_DEPRECATED_NO_EXPORT AMQP_NO_EXPORT AMQP_DEPRECATED
189+
\\ #endif
190+
\\
191+
\\/* NOLINTNEXTLINE(readability-avoid-unconditional-preprocessor-if) */
192+
\\ #if 0 /* DEFINE_NO_DEPRECATED */
193+
\\ # ifndef AMQP_NO_DEPRECATED
194+
\\ # define AMQP_NO_DEPRECATED
195+
\\ # endif
196+
\\ #endif
197+
\\
198+
\\ #endif /* RABBITMQ_C_EXPORT_H */
199+
\\
200+
;

0 commit comments

Comments
 (0)