Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for building with Zig #598

Closed
wants to merge 2 commits into from
Closed
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
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 ]
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How to cross-compile for MacOS? I've failed to

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should be a simple matter of: zig build -Dtarget=x86_64-macos-none

Or aarch64-macos-none for apple silicon...

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This results in an error:
.../bdwgc/extra/../os_dep.c:4354:10: error: 'mach/exception.h' file not found

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ivmai ah yes, that's correct. I forgot I'm running with a patched zig. Zig doesn't ship with the correct headers just yet. I opened an issue for this ziglang/zig#18257. They're usually quite fast adding headers but I'm guessing it'll be after the holidays.

In Acton we add in a few extra headers, see https://github.com/actonlang/acton/tree/main/deps/zig-extras/lib/libc/include/any-macos-any

You can do the same, just copy into your zig/lib/...

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, let's wait for right nightly build and then add macos targets.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right yes, agreed, let's wait for it.. I was just thinking if you wanted to test stuff locally first :)

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 }}
7 changes: 3 additions & 4 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -170,10 +170,9 @@ endif()

include_directories(include)

set(SRC 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)
set(SRC allchblk.c alloc.c blacklst.c dbg_mlc.c dyn_load.c finalize.c headers.c
mach_dep.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c
obj_map.c os_dep.c ptr_chck.c reclaim.c typd_mlc.c)
set(NODIST_SRC)
set(ATOMIC_OPS_LIBS)
set(ATOMIC_OPS_LIBS_CMAKE)
Expand Down
7 changes: 3 additions & 4 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,9 @@ else

EXTRA_DIST += extra/gc.c
libgc_la_SOURCES = \
allchblk.c alloc.c blacklst.c dbg_mlc.c \
dyn_load.c finalize.c gc_dlopen.c headers.c \
mach_dep.c malloc.c mallocx.c mark.c mark_rts.c misc.c new_hblk.c \
obj_map.c os_dep.c ptr_chck.c reclaim.c specific.c typd_mlc.c
allchblk.c alloc.c blacklst.c dbg_mlc.c dyn_load.c finalize.c gc_dlopen.c \
headers.c mach_dep.c malloc.c mallocx.c mark.c mark_rts.c misc.c \
new_hblk.c obj_map.c os_dep.c ptr_chck.c reclaim.c specific.c typd_mlc.c

# C Library: Architecture Dependent
# ---------------------------------
Expand Down
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
Loading