Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,6 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
.pic = true,
}),
});

Expand All @@ -93,8 +91,6 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
.pic = true,
});

// Dynamic library (.so, .dylib, .dll)
Expand Down Expand Up @@ -144,8 +140,6 @@ pub fn build(b: *std.Build) void {
.root_source_file = b.path("src/lib.zig"),
.target = target,
.optimize = optimize,
.link_libc = true,
.pic = true,
}),
});

Expand All @@ -163,6 +157,7 @@ Build with: `zig build -Dlinkage=static` or `zig build -Dlinkage=dynamic`
.name = .my_package,
.version = "0.1.0",
.minimum_zig_version = "0.15.0",
.fingerprint = 0x..........,
.paths = .{
"src",
"build.zig",
Expand All @@ -171,6 +166,16 @@ Build with: `zig build -Dlinkage=static` or `zig build -Dlinkage=dynamic`
}
```

> [!IMPORTANT]
> The `paths` field drives **incremental build tracking**. `ZigBuilder` parses
> `build.zig.zon` and registers every file and directory listed in `paths` as a
> build dependency. When any of those files change, Dart's build system
> automatically re-triggers the Zig build. Make sure `paths` includes all source
> directories and files your build depends on (e.g. `"src"`, C headers,
> embedded data files).
>
> The `name` field (`.my_package`) is a comptime enum literal and is ignored.

5. Create `zig/src/lib.zig`:
```zig
export fn add(a: i32, b: i32) i32 {
Expand Down Expand Up @@ -205,4 +210,4 @@ MIT License - see [LICENSE](LICENSE) for details.

<!-- Links -->
[dart_hooks]: https://dart.dev/tools/hooks
[zig_download]: https://ziglang.org/download/
[zig_download]: https://ziglang.org/download/
51 changes: 42 additions & 9 deletions lib/src/builder.dart
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ import 'package:code_assets/code_assets.dart';
import 'package:hooks/hooks.dart';
import 'package:logging/logging.dart';
import 'package:native_toolchain_zig/src/code_config_mapping.dart';
import 'package:native_toolchain_zig/src/target.dart';
import 'package:native_toolchain_zig/src/utils.dart' as utils;
import 'package:native_toolchain_zig/src/zon_parser.dart';
import 'package:path/path.dart' as path;

import 'target.dart';
import 'utils.dart' as utils;

/// Builds Zig code as native assets using `zig build`.
///
/// Integrates with Dart's build hooks to automatically compile Zig code
Expand Down Expand Up @@ -129,8 +129,8 @@ class ZigBuilder implements Builder {
);

if (result.exitCode != 0) {
String stderr = result.stderr as String;
String stdout = result.stdout as String;
String stderr = result.stderr as String;
logger.severe('Build failed:\n$stderr\n$stdout');
throw BuildError(
message:
Expand All @@ -146,18 +146,51 @@ class ZigBuilder implements Builder {
}

String libName = libraryName ?? packageName;
Uri libPath = await _locateLibrary(input.outputDirectory, libName, target);
Uri libPath = _locateLibrary(input.outputDirectory, libName, target);

output.dependencies.add(buildZig.uri);

File buildZigZon = File(path.join(zigDirectory, 'build.zig.zon'));

if (buildZigZon.existsSync()) {
output.dependencies.add(buildZigZon.uri);
}

for (File file in utils.listZigFiles(zigDirectory)) {
output.dependencies.add(file.uri);
// To compile itself.
// TODO(build.zig.zon): write ZON parser in Dart.
if (packageName != 'native_toolchain_zig') {
// Validate?
Object? zon = parseZon(buildZigZon.readAsStringSync());

if (zon case {'paths': List<Object?> zonPaths}) {
for (Object? entry in zonPaths) {
if (entry is! String) {
continue;
}

// build.zig and build.zig.zon are already tracked above.
if (entry == 'build.zig' || entry == 'build.zig.zon') {
continue;
}

String fullPath = path.join(zigDirectory, entry);
FileSystemEntityType type = FileSystemEntity.typeSync(fullPath);

if (type == FileSystemEntityType.file) {
output.dependencies.add(Uri.file(fullPath));
} else if (type == FileSystemEntityType.directory) {
List<FileSystemEntity> entities = Directory(
fullPath,
).listSync(recursive: true);

for (FileSystemEntity entity in entities) {
if (entity is File) {
output.dependencies.add(entity.uri);
}
}
}
}
}
}
}

for (AssetRouting routing in assetRouting) {
Expand All @@ -176,7 +209,7 @@ class ZigBuilder implements Builder {
}
}

Future<Uri> _locateLibrary(Uri outputDir, String libName, Target target) async {
Uri _locateLibrary(Uri outputDir, String libName, Target target) {
String fileName = target.libraryFileName(libName);

List<Uri> searchPaths = <Uri>[
Expand Down
Loading