-
Notifications
You must be signed in to change notification settings - Fork 408
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
This adds a build.zig that allows building the garbage collector using the Zig build system. It implements a subset of the configuration options offered by CMake and following the naming convention in CMake for all those options. There is a new GitHub Actions configuration file that runs a job that uses zig to compile the collector and targetting different targets using cross-compilation. It doesn't run any actual tests (and it should!). The README is slightly updated, not just adding an explanation of zig but restructuring the whole section on how to build the GC somewhat. The build.zig follows the format used in zig v0.12. The final 0.12 version is not out yet, so users will have to use a build from the zig master branch for now. This is not ideal but the whole zig build system is so new that there have been backwards incompatible changes from 0.11 which is why we opt to use 0.12 that is likely going to be closer to the final form.
- Loading branch information
Showing
3 changed files
with
290 additions
and
36 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# This workflow uses Zig and its excellent cross-compilation support to test | ||
# compiling for multiple platforms. No tests are actually run since it would | ||
# require emulation. We should add a test for the native platform though. | ||
name: zig build | ||
|
||
on: [push, pull_request] | ||
|
||
jobs: | ||
build: | ||
name: ${{ matrix.ttriple }} | ||
runs-on: ubuntu-latest | ||
|
||
strategy: | ||
fail-fast: false | ||
matrix: | ||
ttriple: [ aarch64-linux-musl, wasm32-wasi, x86_64-linux-gnu.2.27, x86_64-linux-musl, x86_64-windows-gnu ] | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
- name: "Install zig" | ||
run: | | ||
curl -o zig.tar.xz https://ziglang.org/builds/zig-linux-x86_64-0.12.0-dev.1814+5c0d58b71.tar.xz | ||
mkdir -p zig | ||
cd zig | ||
tar Jx --strip-components=1 -f ../zig.tar.xz | ||
cd .. | ||
- name: Build | ||
run: | | ||
zig/zig build -Dtarget=${{ matrix.ttriple }} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
// THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED | ||
// OR IMPLIED. ANY USE IS AT YOUR OWN RISK. | ||
// | ||
// Permission is hereby granted to use or copy this program | ||
// for any purpose, provided the above notices are retained on all copies. | ||
// Permission to modify the code and to distribute modified code is granted, | ||
// provided the above notices are retained, and a notice that the code was | ||
// modified is included with the above copyright notice. | ||
|
||
const std = @import("std"); | ||
const print = @import("std").debug.print; | ||
|
||
pub fn build(b: *std.build.Builder) void { | ||
const optimize = b.standardOptimizeOption(.{}); | ||
const target = b.standardTargetOptions(.{}); | ||
const t = target.toTarget(); | ||
var default_enable_threads = true; | ||
if (t.isWasm()) { // matches both emscripten and wasi | ||
default_enable_threads = false; | ||
} | ||
const enable_threads = b.option(bool, "enable_threads", "Support threads") orelse default_enable_threads; | ||
const enable_parallel_mark = b.option(bool, "enable_parallel_mark", "Parallelize marking and free list construction") orelse true; | ||
const enable_thread_local_alloc = b.option(bool, "enable_thread_local_alloc", "Turn on thread-local allocation optimization") orelse true; | ||
const enable_gcj_support = b.option(bool, "enable_gcj_support", "Support for gcj") orelse true; | ||
const enable_java_finalization = b.option(bool, "enable_java_finalization", "Support for java finalization") orelse true; | ||
const enable_atomic_uncollectable = b.option(bool, "enable_atomic_uncollectable", "Support for atomic uncollectible allocation") orelse true; | ||
const enable_redirect_malloc = b.option(bool, "enable_redirect_malloc", "Redirect malloc and friend to GC routines") orelse false; | ||
const enable_disclaim = b.option(bool, "enable_disclaim", "Support alternative finalization interface") orelse true; | ||
const enable_large_config = b.option(bool, "enable_large_config", "Optimize for large heap or root set") orelse true; | ||
const enable_mmap = b.option(bool, "enable_mmap", "Use mmap instead of sbrk to expand the heap") orelse true; | ||
const enable_munmap = b.option(bool, "enable_munmap", "Return page to the OS if empty for N collections") orelse true; | ||
|
||
const lib = b.addStaticLibrary(.{ | ||
.name = "gc", | ||
.target = target, | ||
.optimize = optimize, | ||
}); | ||
|
||
var flags = std.ArrayList([]const u8).init(b.allocator); | ||
defer flags.deinit(); | ||
|
||
if (t.abi.isMusl()) { | ||
std.log.debug("Musl detected", .{}); | ||
flags.appendSlice(&.{"-DNO_GETCONTEXT"}) catch unreachable; | ||
} | ||
|
||
flags.appendSlice(&.{ | ||
"-fno-sanitize=undefined", | ||
// Always enabled | ||
"-DALL_INTERIOR_POINTERS", | ||
"-DNO_EXECUTE_PERMISSION", | ||
// Zig comes with clang that supports atomics so we can hardcode this | ||
"-DGC_BUILTIN_ATOMIC", | ||
// TODO: Should this be configurable? | ||
"-DNO_PROC_FOR_LIBRARIES", | ||
}) catch unreachable; | ||
|
||
if (enable_threads) { | ||
flags.appendSlice(&.{"-DGC_THREADS"}) catch unreachable; | ||
if (enable_parallel_mark) | ||
flags.appendSlice(&.{"-DPARALLEL_MARK"}) catch unreachable; | ||
if (enable_thread_local_alloc) { | ||
lib.addCSourceFiles(.{ | ||
.files = &.{ | ||
"specific.c", | ||
"thread_local_alloc.c", | ||
}, | ||
.flags = flags.items, | ||
}); | ||
} | ||
if (t.os.tag == .windows) { | ||
lib.addCSourceFiles(.{ | ||
.files = &.{"win32_threads.c"}, | ||
.flags = flags.items, | ||
}); | ||
} else { | ||
lib.addCSourceFiles(.{ | ||
.files = &.{ | ||
"gc_dlopen.c", | ||
"pthread_start.c", | ||
"pthread_support.c" | ||
}, | ||
.flags = flags.items, | ||
}); | ||
if (t.os.tag == .macos) { | ||
lib.addCSourceFiles(.{ | ||
.files = &.{"darwin_stop_world.c"}, | ||
.flags = flags.items, | ||
}); | ||
} else { | ||
lib.addCSourceFiles(.{ | ||
.files = &.{"pthread_stop_world.c"}, | ||
.flags = flags.items, | ||
}); | ||
} | ||
} | ||
} | ||
|
||
if (enable_gcj_support) { | ||
flags.appendSlice(&.{"-DGC_GCJ_SUPPORT"}) catch unreachable; | ||
lib.addCSourceFiles(.{ | ||
.files = &.{"gcj_mlc.c"}, | ||
.flags = flags.items, | ||
}); | ||
} | ||
|
||
if (enable_disclaim) { | ||
flags.appendSlice(&.{"-DENABLE_DISCLAIM"}) catch unreachable; | ||
lib.addCSourceFiles(.{ | ||
.files = &.{"fnlz_mlc.c"}, | ||
.flags = flags.items, | ||
}); | ||
} | ||
|
||
if (enable_java_finalization) | ||
flags.appendSlice(&.{"-DJAVA_FINALIZATION"}) catch unreachable; | ||
|
||
if (enable_atomic_uncollectable) | ||
flags.appendSlice(&.{"-DGC_ATOMIC_UNCOLLECTABLE"}) catch unreachable; | ||
|
||
if (enable_redirect_malloc) { | ||
flags.appendSlice(&.{ | ||
"-DREDIRECT_MALLOC=GC_malloc", | ||
"-DIGNORE_FREE", | ||
}) catch unreachable; | ||
if (t.os.tag == .windows) { | ||
flags.appendSlice(&.{"-DREDIRECT_MALLOC_IN_HEADER"}) catch unreachable; | ||
} else { | ||
flags.appendSlice(&.{"-DGC_USE_DLOPEN_WRAP"}) catch unreachable; | ||
} | ||
} | ||
|
||
if (enable_munmap) { | ||
flags.appendSlice(&.{"-DUSE_MMAP"}) catch unreachable; | ||
flags.appendSlice(&.{"-DUSE_MUNMAP"}) catch unreachable; | ||
} else if (enable_mmap) { | ||
flags.appendSlice(&.{"-DUSE_MMAP"}) catch unreachable; | ||
} | ||
|
||
if (enable_large_config) | ||
flags.appendSlice(&.{"-DLARGE_CONFIG"}) catch unreachable; | ||
|
||
const source_files = [_][]const u8{ | ||
"alloc.c", | ||
"reclaim.c", | ||
"allchblk.c", | ||
"misc.c", | ||
"mach_dep.c", | ||
"os_dep.c", | ||
"mark_rts.c", | ||
"headers.c", | ||
"mark.c", | ||
"obj_map.c", | ||
"blacklst.c", | ||
"finalize.c", | ||
"new_hblk.c", | ||
"dbg_mlc.c", | ||
"malloc.c", | ||
"dyn_load.c", | ||
"typd_mlc.c", | ||
"ptr_chck.c", | ||
"mallocx.c", | ||
}; | ||
|
||
lib.addCSourceFiles(.{ | ||
.files = &source_files, | ||
.flags = flags.items, | ||
}); | ||
lib.addIncludePath(.{ .path = "include" }); | ||
lib.linkLibC(); | ||
lib.installHeader("include/gc.h", "gc.h"); | ||
lib.installHeadersDirectory("include/gc", "gc"); | ||
b.installArtifact(lib); | ||
|
||
} |