Skip to content

Instantly share code, notes, and snippets.

@justinturpin
Created May 23, 2024 17:15
Show Gist options
  • Save justinturpin/98290dd9dfe1ca654b368fd01b3edcc8 to your computer and use it in GitHub Desktop.
Save justinturpin/98290dd9dfe1ca654b368fd01b3edcc8 to your computer and use it in GitHub Desktop.
Piper static build
// Build Piper-TTS into a static binary
const std = @import("std");
const ArrayListu8 = std.ArrayList([]const u8);
/// Non-recursively iterate over a directory and add its *.c paths to paths.
/// This isn't used anywhere, but I'm putting it here in case anyone finds it useful.
/// If you want it to be recursive, you basically change dir.iterate() to dir.walk().
pub fn glob_sources(allocator: std.mem.Allocator, base: []const u8, ext: []const u8, paths: *ArrayListu8) !void {
var dir = try std.fs.cwd().openDir(base, .{ .iterate = true });
var iterator = dir.iterate();
while (try iterator.next()) |entry| {
const path_ext = std.fs.path.extension(entry.name);
if (std.mem.eql(u8, path_ext, ext)) {
const path = try std.fs.path.join(allocator, &.{ base, entry.name });
try paths.append(path);
}
}
}
pub fn build(b: *std.Build) !void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// ----------------------------------------------------
// Espeak-ng (todo, the espeak-ng data needs to be installed prior to this)
// ----------------------------------------------------
const espeakg_ng = b.addStaticLibrary(.{
.name = "espeak_ng",
.target = target,
.optimize = optimize,
});
espeakg_ng.addIncludePath(.{ .path = "espeak-ng/src/include" });
espeakg_ng.addIncludePath(.{ .path = "espeak-ng/src/ucd-tools/src/include" });
espeakg_ng.addIncludePath(.{ .path = "espeak-ng/src/speechPlayer/include" });
espeakg_ng.addCSourceFiles(.{ .files = &.{
"espeak-ng/src/libespeak-ng/common.c",
"espeak-ng/src/libespeak-ng/mnemonics.c",
"espeak-ng/src/libespeak-ng/error.c",
"espeak-ng/src/libespeak-ng/ieee80.c",
"espeak-ng/src/libespeak-ng/compiledata.c",
"espeak-ng/src/libespeak-ng/compiledict.c",
"espeak-ng/src/libespeak-ng/dictionary.c",
"espeak-ng/src/libespeak-ng/encoding.c",
"espeak-ng/src/libespeak-ng/intonation.c",
"espeak-ng/src/libespeak-ng/langopts.c",
"espeak-ng/src/libespeak-ng/numbers.c",
"espeak-ng/src/libespeak-ng/phoneme.c",
"espeak-ng/src/libespeak-ng/phonemelist.c",
"espeak-ng/src/libespeak-ng/readclause.c",
"espeak-ng/src/libespeak-ng/setlengths.c",
"espeak-ng/src/libespeak-ng/soundicon.c",
"espeak-ng/src/libespeak-ng/spect.c",
"espeak-ng/src/libespeak-ng/ssml.c",
"espeak-ng/src/libespeak-ng/synthdata.c",
"espeak-ng/src/libespeak-ng/synthesize.c",
"espeak-ng/src/libespeak-ng/tr_languages.c",
"espeak-ng/src/libespeak-ng/translate.c",
"espeak-ng/src/libespeak-ng/translateword.c",
"espeak-ng/src/libespeak-ng/voices.c",
"espeak-ng/src/libespeak-ng/wavegen.c",
"espeak-ng/src/libespeak-ng/speech.c",
"espeak-ng/src/libespeak-ng/espeak_api.c",
} });
espeakg_ng.addCSourceFiles(.{ .files = &.{
"espeak-ng/src/ucd-tools/src/case.c",
"espeak-ng/src/ucd-tools/src/categories.c",
"espeak-ng/src/ucd-tools/src/ctype.c",
"espeak-ng/src/ucd-tools/src/proplist.c",
"espeak-ng/src/ucd-tools/src/scripts.c",
"espeak-ng/src/ucd-tools/src/tostring.c",
} });
espeakg_ng.installHeadersDirectory(b.path("espeak-ng/src/include/espeak"), "espeak", .{});
espeakg_ng.installHeadersDirectory(b.path("espeak-ng/src/include/espeak-ng"), "espeak-ng", .{});
espeakg_ng.linkSystemLibrary("c");
espeakg_ng.linkSystemLibrary("c++");
// Install the artifact, because certain include headers need to be present
b.installArtifact(espeakg_ng);
// ----------------------------------------------------
// Piper-phonemize
// ----------------------------------------------------
const piper_phonemize = b.addStaticLibrary(.{ .name = "piper_phonemize", .target = target, .optimize = optimize });
piper_phonemize.addCSourceFiles(.{ .files = &.{
"piper-phonemize/src/phonemize.cpp",
"piper-phonemize/src/phoneme_ids.cpp",
"piper-phonemize/src/tashkeel.cpp",
"piper-phonemize/src/shared.cpp",
} });
piper_phonemize.addIncludePath(.{ .path = "piper-phonemize/src" });
piper_phonemize.installHeader(b.path("piper-phonemize/src/phonemize.hpp"), "piper-phonemize/phonemize.hpp");
piper_phonemize.installHeader(b.path("piper-phonemize/src/shared.hpp"), "piper-phonemize/shared.hpp");
piper_phonemize.installHeader(b.path("piper-phonemize/src/phoneme_ids.hpp"), "piper-phonemize/phoneme_ids.hpp");
piper_phonemize.installHeader(b.path("piper-phonemize/src/tashkeel.hpp"), "piper-phonemize/tashkeel.hpp");
piper_phonemize.installHeader(b.path("piper-phonemize/src/json.hpp"), "piper-phonemize/json.hpp");
piper_phonemize.linkSystemLibrary("c++");
piper_phonemize.linkLibrary(espeakg_ng);
b.installArtifact(piper_phonemize);
// ----------------------------------------------------
// Main piper executable
// ----------------------------------------------------
const piper = b.addExecutable(.{
.name = "piper",
.target = target,
.optimize = optimize,
});
piper.addCSourceFiles(.{ .files = &.{
"piper/src/cpp/main.cpp",
"piper/src/cpp/piper.cpp",
} });
// Add spdlog to piper directly
piper.addCSourceFiles(.{ .files = &.{
"spdlog/src/spdlog.cpp",
"spdlog/src/stdout_sinks.cpp",
"spdlog/src/color_sinks.cpp",
"spdlog/src/file_sinks.cpp",
"spdlog/src/async.cpp",
"spdlog/src/cfg.cpp",
"spdlog/src/bundled_fmtlib_format.cpp",
}, .flags = &.{"-DSPDLOG_COMPILED_LIB"} });
piper.addIncludePath(.{ .path = "spdlog/include" });
piper.linkLibrary(piper_phonemize);
piper.linkSystemLibrary("c++");
piper.linkSystemLibrary("onnxruntime");
b.installArtifact(piper);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment