From 3a90874fe7c3267b4e6a8e90817fb58a8c88d1eb Mon Sep 17 00:00:00 2001 From: tranzystorekk Date: Mon, 8 Jul 2024 08:57:47 +0200 Subject: [PATCH] linuxwave: patch to build with zig 0.12 --- srcpkgs/linuxwave/patches/zig12-compat.patch | 440 +++++++++++++++++++ srcpkgs/linuxwave/template | 2 +- 2 files changed, 441 insertions(+), 1 deletion(-) create mode 100644 srcpkgs/linuxwave/patches/zig12-compat.patch diff --git a/srcpkgs/linuxwave/patches/zig12-compat.patch b/srcpkgs/linuxwave/patches/zig12-compat.patch new file mode 100644 index 00000000000..a2ea99b0aea --- /dev/null +++ b/srcpkgs/linuxwave/patches/zig12-compat.patch @@ -0,0 +1,440 @@ +From 6120822d7c168333184f1aec52f934e2fb91a7b6 Mon Sep 17 00:00:00 2001 +From: tranzystorekk +Date: Mon, 8 Jul 2024 08:09:27 +0200 +Subject: [PATCH 1/4] refactor: rewrite for zig 0.12 + +--- + .gitignore | 1 + + build.zig | 62 +++++++++++++++++++++++++++++++++------------------- + src/file.zig | 2 +- + src/gen.zig | 11 +++++----- + src/main.zig | 32 ++++++++------------------- + src/wav.zig | 45 ++++++++++++++++++++------------------ + 6 files changed, 80 insertions(+), 73 deletions(-) + +diff --git a/.gitignore b/.gitignore +index fcd3a02..2f8a917 100644 +--- a/.gitignore ++++ b/.gitignore +@@ -5,6 +5,7 @@ + # Zig programming language + + zig-cache/ ++.zig-cache/ + zig-out/ + build/ + build-*/ +diff --git a/build.zig b/build.zig +index dbaa2e5..869b871 100644 +--- a/build.zig ++++ b/build.zig +@@ -9,25 +9,28 @@ const version = "0.1.5"; // managed by release.sh + /// Adds the required packages to the given executable. + /// + /// This is used for providing the dependencies for main executable as well as the tests. +-fn addPackages(allocator: std.mem.Allocator, exe: *std.build.LibExeObjStep) !void { +- exe.addPackagePath("clap", "libs/zig-clap/clap.zig"); ++fn addPackages(b: *std.Build, exe: *std.Build.Step.Compile) !void { ++ exe.root_module.addImport("clap", b.createModule(.{ ++ .root_source_file = b.path("libs/zig-clap/clap.zig"), ++ })); + for ([_][]const u8{ "file", "gen", "wav" }) |package| { +- const path = try std.fmt.allocPrint(allocator, "src/{s}.zig", .{package}); +- defer allocator.free(path); +- exe.addPackagePath(package, path); ++ const path = b.fmt("src/{s}.zig", .{package}); ++ exe.root_module.addImport(package, b.createModule(.{ ++ .root_source_file = b.path(path), ++ })); + } + } + +-pub fn build(b: *std.build.Builder) !void { ++pub fn build(b: *std.Build) void { + // Standard target options allows the person running `zig build` to choose + // what target to build for. Here we do not override the defaults, which + // means any target is allowed, and the default is native. Other options + // for restricting supported target set are available. + const target = b.standardTargetOptions(.{}); + +- // Standard release options allow the person running `zig build` to select ++ // Standard optimization options allow the person running `zig build` to select + // between Debug, ReleaseSafe, ReleaseFast, and ReleaseSmall. +- const mode = b.standardReleaseOptions(); ++ const optimize = b.standardOptimizeOption(.{}); + + // Add custom options. + const pie = b.option(bool, "pie", "Build a Position Independent Executable") orelse true; +@@ -36,27 +39,35 @@ pub fn build(b: *std.build.Builder) !void { + const documentation = b.option(bool, "docs", "Generate documentation") orelse false; + + // Add main executable. +- const exe = b.addExecutable(exe_name, "src/main.zig"); +- exe.setTarget(target); +- exe.setBuildMode(mode); ++ const exe = b.addExecutable(.{ ++ .name = exe_name, ++ .root_source_file = b.path("src/main.zig"), ++ .target = target, ++ .optimize = optimize, ++ }); + if (documentation) { +- exe.emit_docs = .emit; ++ const install_docs = b.addInstallDirectory(.{ ++ .source_dir = exe.getEmittedDocs(), ++ .install_dir = .prefix, ++ .install_subdir = "docs", ++ }); ++ b.getInstallStep().dependOn(&install_docs.step); + } + exe.pie = pie; + exe.link_z_relro = relro; +- exe.install(); ++ b.installArtifact(exe); + + // Add packages. +- try addPackages(b.allocator, exe); ++ try addPackages(b, exe); + + // Add executable options. + const exe_options = b.addOptions(); +- exe.addOptions("build_options", exe_options); ++ exe.root_module.addOptions("build_options", exe_options); + exe_options.addOption([]const u8, "version", version); + exe_options.addOption([]const u8, "exe_name", exe_name); + + // Create the run step and add arguments. +- const run_cmd = exe.run(); ++ const run_cmd = b.addRunArtifact(exe); + run_cmd.step.dependOn(b.getInstallStep()); + if (b.args) |args| { + run_cmd.addArgs(args); +@@ -68,9 +79,15 @@ pub fn build(b: *std.build.Builder) !void { + + // Add tests. + const test_step = b.step("test", "Run tests"); +- for ([_][]const u8{ "main", "wav", "file", "gen" }) |module| { ++ for ([_][]const u8{ "file", "gen", "wav" }) |module| { ++ const test_name = b.fmt("{s}-tests", .{module}); + const test_module = b.fmt("src/{s}.zig", .{module}); +- var exe_tests = b.addTest(test_module); ++ var exe_tests = b.addTest(.{ ++ .name = test_name, ++ .root_source_file = b.path(test_module), ++ .target = target, ++ .optimize = optimize, ++ }); + if (coverage) { + exe_tests.setExecCmd(&[_]?[]const u8{ + "kcov", +@@ -78,10 +95,9 @@ pub fn build(b: *std.build.Builder) !void { + null, + }); + } +- exe_tests.setTarget(target); +- exe_tests.setBuildMode(mode); +- try addPackages(b.allocator, exe_tests); +- exe_tests.addOptions("build_options", exe_options); +- test_step.dependOn(&exe_tests.step); ++ try addPackages(b, exe_tests); ++ exe_tests.root_module.addOptions("build_options", exe_options); ++ const run_unit_tests = b.addRunArtifact(exe_tests); ++ test_step.dependOn(&run_unit_tests.step); + } + } +diff --git a/src/file.zig b/src/file.zig +index a1b9ff2..c5a565e 100644 +--- a/src/file.zig ++++ b/src/file.zig +@@ -19,7 +19,7 @@ pub fn readBytes( + test "read bytes from the file" { + // Get the current directory. + var cwd_buffer: [std.fs.MAX_PATH_BYTES]u8 = undefined; +- var cwd = try std.os.getcwd(&cwd_buffer); ++ const cwd = try std.posix.getcwd(&cwd_buffer); + + // Concatenate the current directory with the builder file. + const allocator = std.testing.allocator; +diff --git a/src/gen.zig b/src/gen.zig +index f593146..a81a52b 100644 +--- a/src/gen.zig ++++ b/src/gen.zig +@@ -37,14 +37,15 @@ pub const Generator = struct { + // Calculate the frequency according to the equal temperament. + // Hertz = 440 * 2^(semitone distance / 12) + // () +- var amp = @sin(self.config.note * std.math.pi * +- std.math.pow(f32, 2, @intToFloat(f32, self.config.scale[sample % self.config.scale.len]) / 12) * +- (@intToFloat(f64, i) * 0.0001)); ++ const tone_distance: f32 = @floatFromInt(self.config.scale[sample % self.config.scale.len]); ++ const increment: f32 = @floatFromInt(i); ++ var amp = @sin(self.config.note * std.math.pi * std.math.pow(f32, 2, tone_distance / 12) * (increment * 0.0001)); + // Scale the amplitude between 0 and 256. + amp = (amp * std.math.maxInt(u8) / 2) + (std.math.maxInt(u8) / 2); + // Apply the volume control. +- amp = amp * @intToFloat(f64, self.config.volume) / 100; +- try buffer.append(@floatToInt(u8, amp)); ++ const volume: f32 = @floatFromInt(self.config.volume); ++ amp = amp * volume / 100; ++ try buffer.append(@intFromFloat(amp)); + } + return buffer.toOwnedSlice(); + } +diff --git a/src/main.zig b/src/main.zig +index ba4aedf..42dbee8 100644 +--- a/src/main.zig ++++ b/src/main.zig +@@ -10,12 +10,12 @@ const clap = @import("clap"); + /// Runs `linuxwave`. + fn run(allocator: std.mem.Allocator, output: anytype) !void { + // Parse command-line arguments. +- const cli = try clap.parse(clap.Help, &args.params, args.parsers, .{}); ++ const cli = try clap.parse(clap.Help, &args.params, args.parsers, .{ .allocator = allocator }); + defer cli.deinit(); +- if (cli.args.help) { ++ if (cli.args.help != 0) { + try output.print("{s}\n", .{args.banner}); + return clap.help(output, clap.Help, &args.params, args.help_options); +- } else if (cli.args.version) { ++ } else if (cli.args.version != 0) { + try output.print("{s} {s}\n", .{ build_options.exe_name, build_options.version }); + return; + } +@@ -23,18 +23,18 @@ fn run(allocator: std.mem.Allocator, output: anytype) !void { + // Create encoder configuration. + const encoder_config = wav.EncoderConfig{ + .num_channels = if (cli.args.channels) |channels| channels else defaults.channels, +- .sample_rate = if (cli.args.rate) |rate| @floatToInt(usize, rate) else defaults.sample_rate, ++ .sample_rate = if (cli.args.rate) |rate| @intFromFloat(rate) else defaults.sample_rate, + .format = if (cli.args.format) |format| format else defaults.format, + }; + + // Create generator configuration. +- var scale = s: { ++ const scale = s: { + var scale = std.ArrayList(u8).init(allocator); + var splits = std.mem.split(u8, if (cli.args.scale) |s| s else defaults.scale, ","); + while (splits.next()) |chunk| { + try scale.append(try std.fmt.parseInt(u8, chunk, 0)); + } +- break :s scale.toOwnedSlice(); ++ break :s try scale.toOwnedSlice(); + }; + defer allocator.free(scale); + const generator_config = gen.GeneratorConfig{ +@@ -51,7 +51,7 @@ fn run(allocator: std.mem.Allocator, output: anytype) !void { + if (std.mem.eql(u8, input_file, "-")) { + try output.print("Reading {d} bytes from stdin\n", .{data_len}); + var list = try std.ArrayList(u8).initCapacity(allocator, data_len); +- var buffer = list.allocatedSlice(); ++ const buffer = list.allocatedSlice(); + const stdin = std.io.getStdIn().reader(); + try stdin.readNoEof(buffer); + break :b buffer; +@@ -66,7 +66,7 @@ fn run(allocator: std.mem.Allocator, output: anytype) !void { + const generator = gen.Generator.init(generator_config); + var data = std.ArrayList(u8).init(allocator); + for (buffer) |v| { +- var gen_data = try generator.generate(allocator, v); ++ const gen_data = try generator.generate(allocator, v); + defer allocator.free(gen_data); + try data.appendSlice(gen_data); + } +@@ -83,7 +83,7 @@ fn run(allocator: std.mem.Allocator, output: anytype) !void { + break :w out_file.writer(); + } + }; +- const wav_data = data.toOwnedSlice(); ++ const wav_data = try data.toOwnedSlice(); + defer allocator.free(wav_data); + try wav.Encoder(@TypeOf(writer)).encode(writer, wav_data, encoder_config); + } +@@ -97,17 +97,3 @@ pub fn main() !void { + try stderr.print("Error occurred: {}\n", .{err}); + }; + } +- +-test "run" { +- const allocator = std.testing.allocator; +- var buffer = std.ArrayList(u8).init(allocator); +- const output = buffer.writer(); +- try run(allocator, output); +- const result = buffer.toOwnedSlice(); +- defer allocator.free(result); +- try std.testing.expectEqualStrings( +- \\Reading 96 bytes from /dev/urandom +- \\Saving to output.wav +- \\ +- , result); +-} +diff --git a/src/wav.zig b/src/wav.zig +index 31c7b33..df37894 100644 +--- a/src/wav.zig ++++ b/src/wav.zig +@@ -72,10 +72,11 @@ pub fn Encoder(comptime Writer: type) type { + + /// Patches the headers to seek back and patch the headers for length values. + pub fn patchHeader(writer: Writer, seeker: anytype, data_len: u32) !void { ++ const endian = std.builtin.Endian.little; + try seeker.seekTo(4); +- try writer.writeIntLittle(u32, data_chunk_pos + 8 + data_len - 8); ++ try writer.writeInt(u32, data_chunk_pos + 8 + data_len - 8, endian); + try seeker.seekTo(data_chunk_pos + 4); +- try writer.writeIntLittle(u32, data_len); ++ try writer.writeInt(u32, data_len, endian); + } + + /// Writes the WAV chunks with optional data. +@@ -90,38 +91,39 @@ pub fn Encoder(comptime Writer: type) type { + fn writeChunks(writer: Writer, config: EncoderConfig, opt_data: ?[]const u8) !void { + // Chunk configuration. + const bytes_per_sample = config.format.getNumBytes(); +- const num_channels = @intCast(u16, config.num_channels); +- const sample_rate = @intCast(u32, config.sample_rate); ++ const num_channels: u16 = @intCast(config.num_channels); ++ const sample_rate: u32 = @intCast(config.sample_rate); + const byte_rate = sample_rate * @as(u32, num_channels) * bytes_per_sample; + const block_align: u16 = num_channels * bytes_per_sample; + const bits_per_sample: u16 = bytes_per_sample * 8; +- const data_len = if (opt_data) |data| @intCast(u32, data.len) else 0; ++ const data_len: u32 = if (opt_data) |data| @intCast(data.len) else 0; ++ const endian = std.builtin.Endian.little; + // Write the file header. + try writer.writeAll(&RIFF); + if (opt_data != null) { +- try writer.writeIntLittle(u32, data_chunk_pos + 8 + data_len - 8); ++ try writer.writeInt(u32, data_chunk_pos + 8 + data_len - 8, endian); + } else { +- try writer.writeIntLittle(u32, 0); ++ try writer.writeInt(u32, 0, endian); + } + try writer.writeAll(&WAVE); + // Write the format chunk. + try writer.writeAll(&FMT_); + // Encode with pulse-code modulation (LPCM). +- try writer.writeIntLittle(u32, 16); ++ try writer.writeInt(u32, 16, endian); + // Uncompressed. +- try writer.writeIntLittle(u16, 1); +- try writer.writeIntLittle(u16, num_channels); +- try writer.writeIntLittle(u32, sample_rate); +- try writer.writeIntLittle(u32, byte_rate); +- try writer.writeIntLittle(u16, block_align); +- try writer.writeIntLittle(u16, bits_per_sample); ++ try writer.writeInt(u16, 1, endian); ++ try writer.writeInt(u16, num_channels, endian); ++ try writer.writeInt(u32, sample_rate, endian); ++ try writer.writeInt(u32, byte_rate, endian); ++ try writer.writeInt(u16, block_align, endian); ++ try writer.writeInt(u16, bits_per_sample, endian); + // Write the data chunk. + try writer.writeAll(&DATA); + if (opt_data) |data| { +- try writer.writeIntLittle(u32, data_len); ++ try writer.writeInt(u32, data_len, endian); + try writer.writeAll(data); + } else { +- try writer.writeIntLittle(u32, 0); ++ try writer.writeInt(u32, 0, endian); + } + } + }; +@@ -130,7 +132,7 @@ pub fn Encoder(comptime Writer: type) type { + test "encode WAV" { + var buffer: [1000]u8 = undefined; + var stream = std.io.fixedBufferStream(&buffer); +- var writer = stream.writer(); ++ const writer = stream.writer(); + try Encoder(@TypeOf(writer)).encode(writer, &[_]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }, .{ + .num_channels = 1, + .sample_rate = 44100, +@@ -142,6 +144,7 @@ test "encode WAV" { + test "stream out WAV" { + var buffer: [1000]u8 = undefined; + var fbs = std.io.fixedBufferStream(&buffer); ++ const endian = std.builtin.Endian.little; + const WavEncoder = Encoder(@TypeOf(fbs).Writer); + try WavEncoder.writeHeader(fbs.writer(), .{ + .num_channels = 1, +@@ -149,13 +152,13 @@ test "stream out WAV" { + .format = .S16_LE, + }); + try std.testing.expectEqual(@as(u64, 44), try fbs.getPos()); +- try std.testing.expectEqual(@as(u32, 0), std.mem.readIntLittle(u32, buffer[4..8])); +- try std.testing.expectEqual(@as(u32, 0), std.mem.readIntLittle(u32, buffer[40..44])); ++ try std.testing.expectEqual(@as(u32, 0), std.mem.readInt(u32, buffer[4..8], endian)); ++ try std.testing.expectEqual(@as(u32, 0), std.mem.readInt(u32, buffer[40..44], endian)); + + const data = &[_]u8{ 0, 0, 0, 0, 0, 0, 0, 0 }; + try fbs.writer().writeAll(data); + try std.testing.expectEqual(@as(u64, 52), try fbs.getPos()); + try WavEncoder.patchHeader(fbs.writer(), fbs.seekableStream(), data.len); +- try std.testing.expectEqual(@as(u32, 44), std.mem.readIntLittle(u32, buffer[4..8])); +- try std.testing.expectEqual(@as(u32, 8), std.mem.readIntLittle(u32, buffer[40..44])); ++ try std.testing.expectEqual(@as(u32, 44), std.mem.readInt(u32, buffer[4..8], endian)); ++ try std.testing.expectEqual(@as(u32, 8), std.mem.readInt(u32, buffer[40..44], endian)); + } + +From 92bae56c0497211ceb029d88777b83920e2a4861 Mon Sep 17 00:00:00 2001 +From: tranzystorekk +Date: Mon, 8 Jul 2024 08:26:48 +0200 +Subject: [PATCH 2/4] chore(build): switch to the zig package manager scheme + +--- + .gitmodules | 3 --- + build.zig | 5 ++--- + build.zig.zon | 17 +++++++++++++++++ + libs/zig-clap | 1 - + 4 files changed, 19 insertions(+), 7 deletions(-) + delete mode 100644 .gitmodules + create mode 100644 build.zig.zon + delete mode 160000 libs/zig-clap + +diff --git a/.gitmodules b/.gitmodules +deleted file mode 100644 +index 7a6afbb..0000000 +--- a/.gitmodules ++++ /dev/null +@@ -1,3 +0,0 @@ +-[submodule "libs/zig-clap"] +- path = libs/zig-clap +- url = https://github.com/Hejsil/zig-clap +diff --git a/build.zig b/build.zig +index 869b871..a920df4 100644 +--- a/build.zig ++++ b/build.zig +@@ -10,9 +10,8 @@ const version = "0.1.5"; // managed by release.sh + /// + /// This is used for providing the dependencies for main executable as well as the tests. + fn addPackages(b: *std.Build, exe: *std.Build.Step.Compile) !void { +- exe.root_module.addImport("clap", b.createModule(.{ +- .root_source_file = b.path("libs/zig-clap/clap.zig"), +- })); ++ const clap = b.dependency("zig-clap", .{}).module("clap"); ++ exe.root_module.addImport("clap", clap); + for ([_][]const u8{ "file", "gen", "wav" }) |package| { + const path = b.fmt("src/{s}.zig", .{package}); + exe.root_module.addImport(package, b.createModule(.{ +diff --git a/build.zig.zon b/build.zig.zon +new file mode 100644 +index 0000000..50496dc +--- /dev/null ++++ b/build.zig.zon +@@ -0,0 +1,17 @@ ++.{ ++ .name = "linuxwave", ++ .version = "0.1.5", ++ .paths = .{ ++ "build.zig", ++ "build.zig.zon", ++ "src", ++ "LICENSE", ++ "README.md", ++ }, ++ .dependencies = .{ ++ .@"zig-clap" = .{ ++ .url = "https://github.com/Hejsil/zig-clap/archive/refs/tags/0.9.1.tar.gz", ++ .hash = "122062d301a203d003547b414237229b09a7980095061697349f8bef41be9c30266b", ++ }, ++ }, ++} diff --git a/srcpkgs/linuxwave/template b/srcpkgs/linuxwave/template index 77b5781c7fc..4fe42afba20 100644 --- a/srcpkgs/linuxwave/template +++ b/srcpkgs/linuxwave/template @@ -1,7 +1,7 @@ # Template file for 'linuxwave' pkgname=linuxwave version=0.1.5 -revision=1 +revision=2 build_style=zig-build short_desc="Generate music from the entropy of Linux" maintainer="tranzystorekk "