Skip to content

Commit

Permalink
Update README and example
Browse files Browse the repository at this point in the history
  • Loading branch information
mgord9518 committed Aug 28, 2024
1 parent 59274e4 commit f5c9d0f
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 62 deletions.
12 changes: 6 additions & 6 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -48,14 +48,14 @@ jobs:
- name: Test
run: |
zig build test
zig build test -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseSafe
zig build test -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseFast
zig build test -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseSmall
zig build test -Dstatic_lz4=true -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseSafe
zig build test -Dstatic_lz4=true -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseFast
zig build test -Dstatic_lz4=true -Dtarget=x86_64-linux-gnu -Doptimize=ReleaseSmall
zig build test
zig build test -Dtarget=x86_64-linux-musl -Doptimize=ReleaseSafe
zig build test -Dtarget=x86_64-linux-musl -Doptimize=ReleaseFast
zig build test -Dtarget=x86_64-linux-musl -Doptimize=ReleaseSmall
zig build test -Dstatic_lz4=true -Dtarget=x86_64-linux-musl -Doptimize=ReleaseSafe
zig build test -Dstatic_lz4=true -Dtarget=x86_64-linux-musl -Doptimize=ReleaseFast
zig build test -Dstatic_lz4=true -Dtarget=x86_64-linux-musl -Doptimize=ReleaseSmall
- name: Upload build
uses: "marvinpinto/action-automatic-releases@latest"
Expand Down
89 changes: 50 additions & 39 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,40 +1,33 @@
# squashfuse-zig
WIP SquashFS implementation in Zig, modeled from squashfuse
SquashFS implementation in Zig, modeled after squashfuse

My main goals for this project are as follows:
* Make library usage as similar to Zig's stdlib as possible
* Performant; choose the best compression implementations by default (this
is already done using libdeflate in place of zlib)
* Fully-compatible with existing squashfuse tools
* Keep code as clean as possible (whew, yeah we're not there yet)
Active/ complete goals:
- [ ] Library usage in line with Zig stdlib
- [ ] (Partial) Dir implementation
- [ ] Move Inode methods into Dir and File structs
- [ ] File struct
- [x] Performance; choose the fastest decompression libraries by default
(being done for the CLI tool by default via libdeflate)
- [x] (Partial) Compatibility with existing squashfuse tools

With some very basic benchmarking, extracting a zlib-compressed AppImage
(FreeCAD, the largest AppImage I've been able to find so far), takes 3.1
seconds using the `--extract` flag with squashfuse-zig's CLI tool, which
is currently single-thread only.

For reference, `unsquashfs` with multi-threaded decompression takes 1.5 seconds
and single-threaded takes 6.5 seconds.

Surely almost all of the single-threaded performace gain can be chalked up to
using libdeflate, but performance by default is important. I'd like to compare
it to the actual squashfuse's `squashfuse_extract` program to see how it
compares.
Future goals:
- [ ] Writing?
- [ ] Multithreading

Importing example:

[build.zig.zon](example/build.zig.zon)
```zig
// build.zig.zon
.{
.name = "example",
.name = "import_example",
.version = "0.0.0",
.minimum_zig_version = "0.13.0",
.dependencies = .{
.squashfuse = .{
.url = "https://github.com/mgord9518/squashfuse-zig/archive/refs/tags/continuous.tar.gz",
// Leave this commented initially, then Zig will complain and give
// you the correct value
//.url = "https://github.com/mgord9518/squashfuse-zig/archive/refs/tags/continuous.tar.gz",
//.hash = "1220e675672f86be446965d5b779a384c81c7648e385428ed5a8858842cfa38a4e22",
.path = "../",
},
},
Expand All @@ -46,45 +39,63 @@ Importing example:
},
}
```

[build.zig](example/build.zig)
```zig
// build.zig
const std = @import("std");
pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});
// Import and configure dependency
// As of now, there isn't a way to disable a compression library, so every
// one will either be statically linked in or an attempt will be made to
// dlload it from the system
//
// This will be changed in the future, but the API will probably stay the
// same
const squashfuse_dep = b.dependency("squashfuse", .{
.target = target,
.optimize = optimize,
// These options will be renamed in the future
.@"enable-zlib" = true,
.@"use-libdeflate" = true,
.@"enable-xz" = false,
.@"enable-lzma" = false,
.@"enable-lzo" = false,
.@"enable-lz4" = false,
.@"enable-zstd" = false,
.zlib_decompressor = .libz,
.static_zlib = false,
.zstd_decompressor = .libzstd,
.static_zstd = true,
});
const exe = b.addExecutable(.{
.name = "example",
.name = "import_example",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});
// libc should be explicitly linked unless all compression libraries are
// using the Zig implementation or are statically linked
exe.linkLibC();
exe.root_module.addImport(
"squashfuse",
squashfuse_dep.module("squashfuse"),
);
// Link up required libraries
// TODO: automate this
exe.linkLibrary(squashfuse_dep.artifact("deflate"));
// If a C-ABI compression library is used and static building is enabled,
// the library must be linked here
exe.linkLibrary(squashfuse_dep.artifact("zstd"));
b.installArtifact(exe);
const run_cmd = b.addRunArtifact(exe);
run_cmd.step.dependOn(b.getInstallStep());
if (b.args) |args| {
run_cmd.addArgs(args);
}
const run_step = b.step("run", "Run the app");
run_step.dependOn(&run_cmd.step);
}
```
2 changes: 1 addition & 1 deletion build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.{
.name = "squashfuse-zig",
.version = "0.3.3",
.version = "0.3.4",

.paths = [][]const u8{
"build.zig",
Expand Down
32 changes: 18 additions & 14 deletions example/build.zig
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,43 @@ pub fn build(b: *std.Build) void {
const target = b.standardTargetOptions(.{});
const optimize = b.standardOptimizeOption(.{});

// As of now, there isn't a way to disable a compression library, so every
// one will either be statically linked in or an attempt will be made to
// dlload it from the system
//
// This will be changed in the future, but the API will probably stay the
// same
const squashfuse_dep = b.dependency("squashfuse", .{
.target = target,
.optimize = optimize,

// These options will be renamed in the future
.@"enable-zlib" = true,
.@"use-libdeflate" = true,
.@"enable-xz" = true,
.@"enable-lz4" = true,
.zlib_decompressor = .libz,
.static_zlib = false,

.@"enable-lzma" = false,
.@"enable-lzo" = false,
.@"enable-zstd" = false,
.zstd_decompressor = .libzstd,
.static_zstd = true,
});

const exe = b.addExecutable(.{
.name = "example",
.name = "squashfs_inspector",
.root_source_file = b.path("src/main.zig"),
.target = target,
.optimize = optimize,
});

// When using compression libraries implemented in C, they must be linked
// to the main executable
exe.linkLibrary(squashfuse_dep.artifact("deflate"));
exe.linkLibrary(squashfuse_dep.artifact("lz4"));
exe.linkLibrary(squashfuse_dep.artifact("lzma"));
// libc should be explicitly linked unless all compression libraries are
// using the Zig implementation or are statically linked
exe.linkLibC();

exe.root_module.addImport(
"squashfuse",
squashfuse_dep.module("squashfuse"),
);

// If a C-ABI compression library is used and static building is enabled,
// the library must be linked here
exe.linkLibrary(squashfuse_dep.artifact("zstd"));

b.installArtifact(exe);

const run_cmd = b.addRunArtifact(exe);
Expand Down
2 changes: 1 addition & 1 deletion example/build.zig.zon
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
.{
.name = "example",
.name = "import_example",
.version = "0.0.0",
.minimum_zig_version = "0.13.0",

Expand Down
3 changes: 2 additions & 1 deletion example/src/main.zig
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ pub fn main() !void {

const argv0 = args_it.next().?;
const argv1 = args_it.next() orelse {
std.debug.print("usage: {s} <squashfs>\n", .{argv0});
std.debug.print("SquashFS inspector!\n", .{});
std.debug.print("usage: {s} <SQUASHFS>\n", .{argv0});
return;
};

Expand Down

0 comments on commit f5c9d0f

Please sign in to comment.