Skip to content

Commit

Permalink
Add support for building with Zig
Browse files Browse the repository at this point in the history
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 are two new GitHub Actions workflows:
- zig build is essentially a copy of the cmake build workflow
  - it builds the collector and runs tests
- zig xbuild uses zig to cross-compile for different platforms
  - we don't actually run the tests as that would require emulation

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
plajjan committed Dec 20, 2023
1 parent a842861 commit 177780f
Show file tree
Hide file tree
Showing 4 changed files with 623 additions and 36 deletions.
52 changes: 52 additions & 0 deletions .github/workflows/zig-build.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This workflow is for zig-basd build/test running on multiple platforms.
# TODO: move from nightly to zig 0.12 once it is released
name: zig build

on: [push, pull_request]

jobs:
build:
name: ${{ matrix.os }} thr:${{ matrix.enable_threads }} rwlock::${{ matrix.enable_rwlock }} redir:${{ matrix.redirect_malloc }} dll:${{ matrix.shared_libs }} cpp::${{ matrix.enable_cplusplus }}
runs-on: ${{ matrix.os }}

strategy:
# Deliver the feedback for all matrix combinations.
fail-fast: false

matrix:
os: [ ubuntu-latest ]
#os: [ macos-latest, ubuntu-latest, windows-latest ]
enable_cplusplus: [ false, true ]
build_type: [ Release ]
gc_assertions: [ true ]
large_config: [ true ]
enable_threads: [ false, true ]
enable_rwlock: [ false, true ]
redirect_malloc: [ false, true ]
shared_libs: [ false, true ]
exclude:
- enable_threads: false
enable_rwlock: true
- os: macos-latest
enable_cplusplus: false
- os: ubuntu-latest
enable_cplusplus: false

steps:
- uses: actions/checkout@v4
- name: "Install zig"
run: |
mkdir zig && cd zig && curl https://ziglang.org/builds/zig-linux-x86_64-0.12.0-dev.1814+5c0d58b71.tar.xz | tar Jx --strip-components=1 && cd ..
- name: Build
run: >
zig/zig build
-Dbuild_shared_libs=${{ matrix.shared_libs }}
-Dbuild_tests=true
-Denable_cplusplus=${{ matrix.enable_cplusplus }}
-Denable_gc_assertions=${{ matrix.gc_assertions }}
-Denable_large_config=${{ matrix.large_config }}
-Denable_redirect_malloc=${{ matrix.redirect_malloc }}
-Denable_rwlock=${{ matrix.enable_rwlock }}
-Denable_threads=${{ matrix.enable_threads }}
-Denable_werror=true
test
29 changes: 29 additions & 0 deletions .github/workflows/zig-xbuild.yml
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.
# TODO: move from nightly to zig 0.12 once it is released
name: zig cross-compile

on: [push, pull_request]

jobs:
build:
name: ${{ matrix.ttriple }} dll:${{ matrix.shared_libs }}
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 ]
shared_libs: [ false, true ]

steps:
- uses: actions/checkout@v4
- name: "Install zig"
run: |
mkdir zig && cd zig && curl https://ziglang.org/builds/zig-linux-x86_64-0.12.0-dev.1814+5c0d58b71.tar.xz | tar Jx --strip-components=1 && cd ..
- name: Build
run: >
zig/zig build
-Dtarget=${{ matrix.ttriple }}
-Dbuild_shared_libs=${{ matrix.shared_libs }}
122 changes: 86 additions & 36 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,29 @@ stored on the thread's stack for the duration of their lifetime.
(This is arguably a longstanding bug, but it hasn't been fixed yet.)


## Installation and Portability
## Building and Installing

There are multiple ways to build the collector:

- CMake
- GNU autoconf
- Zig
- somewhat experimental support for using the Zig build system
- Zig is excellent at cross-compilation
- Makefile
- a static Makefile that offers a subset of configurable options
- Manual C compilation

### Configurable Macros

The library can be configured more precisely during the build by defining
the macros listed in [README.macros](docs/README.macros) file.

The library is built with threads support enabled (i.e. for thread-safe
operation) by default, unless explicitly disabled:
- `--disable-threads` is passed to `./configure`
- `-Denable_threads=OFF` is passed to `cmake`
- `-Denable_threads=false` is passed to `zig build`

The collector operates silently in the default configuration.
In the event of issues, this can usually be changed by defining the
Expand All @@ -183,53 +205,56 @@ Things don't appear to add up for a variety of reasons, most notably
fragmentation losses. These are probably much more significant for the
contrived program `gctest` than for your application.)

On most Unix-like platforms, the collector can be built either using a
GNU autoconf-based build infrastructure (type `./configure; make` in the
simplest case), or using CMake (see the sample below), or with a classic
makefile by itself (type `make -f Makefile.direct`).
### GNU Autoconf

Please note that the collector source repository does not contain configure
Please note that the collector source repository does not contain `configure`
and similar auto-generated files, thus the full procedure of autoconf-based
build of `master` branch of the collector could look like:

git clone https://github.com/ivmai/bdwgc
cd bdwgc
git clone https://github.com/ivmai/libatomic_ops
./autogen.sh
./configure
make -j
make check
``` sh
git clone https://github.com/ivmai/bdwgc
cd bdwgc
./autogen.sh
./configure
make -j
make check
```

Cloning of `libatomic_ops` is now optional provided the compiler supports
atomic intrinsics. See [README.autoconf](docs/README.autoconf) for details.

As noted above, alternatively, the collector could be built with CMake, like
this:
### CMake

mkdir out
cd out
cmake -Dbuild_tests=ON ..
cmake --build .
ctest
```sh
mkdir out && cd out
cmake -Dbuild_tests=ON ..
cmake --build .
ctest
```

See [README.cmake](docs/README.cmake) for details.

Finally, on most targets, the collector could be built and tested directly
with a single compiler invocation, like this:
### Zig

gcc -I include -o gctest tests/gctest.c extra/gc.c && ./gctest
Building using zig is in its simplest form straight forward:

On Windows, CMake could be used to build the library as described above or
by typing `nmake -f NT_MAKEFILE`, this assumes you have Microsoft command-line
tools installed and suitably configured. See
[README.win32](docs/platforms/README.win32) for details.
```sh
zig build
```

The library is built with threads support on (i.e. for thread-safe operation)
by default, unless `--disable-threads` is passed to `./configure` (or
`-Denable_threads=OFF` is passed to `cmake` tool).
It is possible to configure the build through the use of variables, for example
`zig build -Denable_redirect_malloc -Denable_threads=false`. Zig offers
excellent cross-compilation functionality, for example to compile the collector
for MacOS on Apple Silicon (M1 / M2 / M3):

The library could be configured more precisely during the build by defining
the macros listed in [README.macros](docs/README.macros) file.
```sh
zig build -Dtarget=aarch64-macos-gnu
```

Currently, a nightly version of zig 0.12 is required, which can be downloaded
from https://ziglang.org/download/

### Makefile

Below we focus on the collector build using classic makefile. For the
Makefile.direct-based process, typing `make check` instead of `make` will
Expand All @@ -243,19 +268,44 @@ desktops. It may use up to about 30 MB of memory. (The multi-threaded
version will use more. 64-bit versions may use more.) `make check` will also,
as its last step, attempt to build and test the "cord" string library.)

Makefile.direct will generate a library libgc.a which you should link against.
Typing `make -f Makefile.direct cords` will build the cord library (libcord.a)
as well.

The GNU style build process understands the usual targets. `make check`
runs a number of tests. `make install` installs at least libgc, and libcord.
Try `./configure --help` to see the configuration options. It is currently
not possible to exercise all combinations of build options this way.

Makefile.direct will generate a library libgc.a which you should link against.
Typing `make -f Makefile.direct cords` will build the cord library (libcord.a)
as well.


### Manual C compilation

Finally, on most targets, the collector could be built and tested directly
with a single compiler invocation, like this:

``` sh
cc -I include -o gctest tests/gctest.c extra/gc.c && ./gctest
```

### Windows nmake

On Windows, CMake could be used to build the library as described above or
by typing `nmake -f NT_MAKEFILE`, this assumes you have Microsoft command-line
tools installed and suitably configured. See
[README.win32](docs/platforms/README.win32) for details.

All include files that need to be used by clients will be put in the
include subdirectory. (Normally this is just gc.h. `make cords` adds
"cord.h" and "ec.h".)

### Atomic ops

The GC requires atomic ops. Most modern compilers offer builtin atomics. In case
your compiler does not, you can download and use `libatomic_ops` from
https://github.com/ivmai/libatomic_ops

## Portability

The collector currently is designed to run essentially unmodified on
machines that use a flat 32-bit or 64-bit address space.
That includes the vast majority of Workstations and x86 (i386 or later) PCs.
Expand Down
Loading

0 comments on commit 177780f

Please sign in to comment.