-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathgenerate.zig
More file actions
137 lines (112 loc) · 4.73 KB
/
Copy pathgenerate.zig
File metadata and controls
137 lines (112 loc) · 4.73 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
const std = @import("std");
pub fn addConfigFiles(b: *std.Build, wf: *std.Build.Step.WriteFile) void {
const build_zon = @import("build.zig.zon");
// Extract version from URL tag (e.g., #v5.044 -> 5.044.0)
const version = extractVersionFromUrl(build_zon.dependencies.upstream.url) orelse "0.0.0";
// Generate config_package.h
const config_package_content = std.fmt.allocPrint(b.allocator,
\\// Generated by Zig build system
\\#ifndef VERILATOR_CONFIG_PACKAGE_H_
\\#define VERILATOR_CONFIG_PACKAGE_H_
\\
\\#define HAVE_CONFIG_PACKAGE 1
\\
\\#define PACKAGE_NAME "Verilator"
\\#define PACKAGE_STRING "Verilator {s}"
\\#define PACKAGE_TARNAME "verilator"
\\#define PACKAGE_URL "https://verilator.org"
\\#define PACKAGE_VERSION "{s}"
\\#define PACKAGE_VERSION_NUMBER_STRING "{s}"
\\
\\#define CFG_WITH_CCWARN 1
\\#define CFG_WITH_LONGTESTS 1
\\
\\// C++20 coroutines support (requires -fcoroutines or C++20 compiler)
\\#define HAVE_COROUTINES 1
\\
\\#endif
\\
, .{ version, version, version }) catch @panic("OOM");
_ = wf.add("config_package.h", config_package_content);
// Generate config_rev.h - extract git tag/hash from URL
const git_rev = extractGitRef(build_zon.dependencies.upstream.url) orelse "zig-build";
const config_rev_content = std.fmt.allocPrint(b.allocator,
\\// Generated by Zig build system
\\#ifndef VERILATOR_CONFIG_REV_H_
\\#define VERILATOR_CONFIG_REV_H_
\\
\\#define DTVERSION_rev "{s}"
\\
\\#endif
\\
, .{git_rev}) catch @panic("OOM");
_ = wf.add("config_rev.h", config_rev_content);
}
pub fn generateVerilatedMk(b: *std.Build, upstream: *std.Build.Dependency, cxx: []const u8, ar: []const u8) std.Build.LazyPath {
const process_cmd = b.addSystemCommand(&[_][]const u8{"python3"});
process_cmd.addFileArg(b.path("scripts/process_template.py"));
process_cmd.addFileArg(upstream.path("include/verilated.mk.in"));
const output = process_cmd.addOutputFileArg("verilated.mk");
// Pass compiler settings to script
process_cmd.addArg("--cxx");
process_cmd.addArg(cxx);
process_cmd.addArg("--ar");
process_cmd.addArg(ar);
return output;
}
pub fn generateVerilatedConfigH(b: *std.Build, upstream: *std.Build.Dependency, cxx: []const u8) std.Build.LazyPath {
const process_cmd = b.addSystemCommand(&[_][]const u8{"python3"});
process_cmd.addFileArg(b.path("scripts/process_template.py"));
process_cmd.addFileArg(upstream.path("include/verilated_config.h.in"));
const output = process_cmd.addOutputFileArg("verilated_config.h");
// Pass compiler for detection of clang vs gcc flags
process_cmd.addArg("--cxx");
process_cmd.addArg(cxx);
return output;
}
pub fn extractVersionFromUrl(url: []const u8) ?[]const u8 {
// URL formats:
// - "git+https://github.com/verilator/verilator#v5.044"
// - "git+https://github.com/verilator/verilator?ref=v5.042#<commit>"
// Returns: "5.044.0" or "5.042.0"
// Try ?ref=vX.XXX format first
const ref_start = std.mem.indexOf(u8, url, "?ref=v") orelse 0;
const version_start = if (ref_start > 0) ref_start + 6 else blk: {
// Try #vX.XXX format
const hash_v = std.mem.indexOf(u8, url, "#v") orelse return null;
break :blk hash_v + 2;
};
// Find end of version (next # or ? or end)
var version_end = version_start;
while (version_end < url.len) : (version_end += 1) {
if (url[version_end] == '#' or url[version_end] == '?') break;
}
const tag = url[version_start..version_end]; // e.g., "5.044"
// Statically allocate buffer for version string (tag + ".0")
const S = struct {
var buf: [32]u8 = undefined;
};
if (tag.len + 2 > S.buf.len) return null;
@memcpy(S.buf[0..tag.len], tag);
S.buf[tag.len] = '.';
S.buf[tag.len + 1] = '0';
return S.buf[0 .. tag.len + 2];
}
fn extractGitRef(url: []const u8) ?[]const u8 {
// URL formats:
// - "git+https://...#v5.044" -> "v5.044"
// - "git+https://...?ref=v5.042#<commit>" -> "v5.042"
// Try ?ref=vX.XXX format first
if (std.mem.indexOf(u8, url, "?ref=v")) |ref_start| {
const version_start = ref_start + 5; // after "?ref="
var version_end = version_start;
while (version_end < url.len) : (version_end += 1) {
if (url[version_end] == '#') break;
}
return url[version_start..version_end];
}
// Fall back to #vX.XXX format
const hash_start = std.mem.lastIndexOf(u8, url, "#") orelse return null;
if (hash_start + 1 >= url.len) return null;
return url[hash_start + 1 ..];
}