kaniini/libucontext

How to compile for macOS M1 (Apple Silicon)?

Closed this issue · 5 comments

I have no idea, how to compile this :(
I tried make, but with no luck.
I tried meson, just

meson builddir && cd builddir
meson compile

With no luck either:

../include/libucontext/bits.h:8:9: error: unknown type name 'greg_t'
typedef greg_t libucontext_greg_t;
        ^
../include/libucontext/bits.h:9:9: error: unknown type name 'ucontext_t'
typedef ucontext_t libucontext_ucontext_t;
        ^
../arch/aarch64/makecontext.c:24:16: error: offsetof requires struct, union, or class type, 'libucontext_ucontext_t' (aka 'int') invalid
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.regs[0]) == R0_OFFSET, "R0_OFFSET is invalid");
               ^        ~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/lib/clang/13.0.0/include/stddef.h:104:24: note: expanded from macro 'offsetof'
#define offsetof(t, d) __builtin_offsetof(t, d)
                       ^                  ~
../arch/aarch64/makecontext.c:25:16: error: offsetof requires struct, union, or class type, 'libucontext_ucontext_t' (aka 'int') invalid
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.sp) == SP_OFFSET, "SP_OFFSET is invalid");
               ^        ~~~~~~~~~~~~~~~~~~~~~~
/Library/Developer/CommandLineTools/usr/lib/clang/13.0.0/include/stddef.h:104:24: note: expanded from macro 'offsetof'
#define offsetof(t, d) __builtin_offsetof(t, d)
                       ^                  ~

encoupled with an error "The deprecated ucontext routines require _XOPEN_SOURCE to be defined"

All in all, how can it be compiled and installed into the system?
I want to use it instead of makecontext and others while porting source code of my project to M1

try compile like that:
For object files:
cd arch/aarch64 && cc *.c *.S -I. -I../common -Iinclude -I../../include -fPIC -DPIC -O2 -ggdb3 -D_BSD_SOURCE -std=gnu99 -c
Archive objects to static library (libucontext.a):
ar rcs libucontext.a *.o
Compile objects to dynamic library (libucontext.dylib):
cc -dynamiclib -o libucontext.1.dylib -compatibility_version 1 -current_version 1 *.o

The non-Meson build system should now work. I'll cut a new release shortly.

kov commented

I still hit this issue even with @Torrekie's change:

> make
cc -std=gnu99 -D_BSD_SOURCE -fPIC -DPIC -ggdb3 -O2 -Wall -Iinclude -Iarch/aarch64 -Iarch/common -c -o arch/aarch64/makecontext.o arch/aarch64/makecontext.c
In file included from arch/aarch64/makecontext.c:19:
In file included from include/libucontext/libucontext.h:7:
include/libucontext/bits.h:8:9: error: unknown type name 'greg_t'
typedef greg_t libucontext_greg_t;
        ^
arch/aarch64/makecontext.c:24:61: error: offsetof requires struct, union, or class type, 'struct __darwin_mcontext64 *' invalid
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.regs[0]) == R0_OFFSET, "R0_OFFSET is invalid");
                                                            ^
arch/aarch64/makecontext.c:25:61: error: offsetof requires struct, union, or class type, 'struct __darwin_mcontext64 *' invalid
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.sp) == SP_OFFSET, "SP_OFFSET is invalid");
                                                            ^
arch/aarch64/makecontext.c:26:61: error: offsetof requires struct, union, or class type, 'struct __darwin_mcontext64 *' invalid
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.pc) == PC_OFFSET, "PC_OFFSET is invalid");
                                                            ^
arch/aarch64/makecontext.c:27:61: error: offsetof requires struct, union, or class type, 'struct __darwin_mcontext64 *' invalid
_Static_assert(offsetof(libucontext_ucontext_t, uc_mcontext.pstate) == PSTATE_OFFSET, "PSTATE_OFFSET is invalid");
                                                            ^
arch/aarch64/makecontext.c:41:18: error: member reference type 'struct __darwin_mcontext64 *' is a pointer; did you mean to use '->'?
        ucp->uc_mcontext.sp = (uintptr_t) sp;
        ~~~~~~~~~~~~~~~~^
                        ->
arch/aarch64/makecontext.c:41:19: error: no member named 'sp' in 'struct __darwin_mcontext64'
        ucp->uc_mcontext.sp = (uintptr_t) sp;
        ~~~~~~~~~~~~~~~~ ^
arch/aarch64/makecontext.c:42:18: error: member reference type 'struct __darwin_mcontext64 *' is a pointer; did you mean to use '->'?
        ucp->uc_mcontext.pc = (uintptr_t) func;
        ~~~~~~~~~~~~~~~~^
                        ->
arch/aarch64/makecontext.c:42:19: error: no member named 'pc' in 'struct __darwin_mcontext64'
        ucp->uc_mcontext.pc = (uintptr_t) func;
        ~~~~~~~~~~~~~~~~ ^
arch/aarch64/makecontext.c:43:18: error: member reference type 'struct __darwin_mcontext64 *' is a pointer; did you mean to use '->'?
        ucp->uc_mcontext.regs[19] = (uintptr_t) ucp->uc_link;
        ~~~~~~~~~~~~~~~~^
                        ->
arch/aarch64/makecontext.c:43:19: error: no member named 'regs' in 'struct __darwin_mcontext64'
        ucp->uc_mcontext.regs[19] = (uintptr_t) ucp->uc_link;
        ~~~~~~~~~~~~~~~~ ^
arch/aarch64/makecontext.c:44:18: error: member reference type 'struct __darwin_mcontext64 *' is a pointer; did you mean to use '->'?
        ucp->uc_mcontext.regs[30] = (uintptr_t) &libucontext_trampoline;
        ~~~~~~~~~~~~~~~~^
                        ->
arch/aarch64/makecontext.c:44:19: error: no member named 'regs' in 'struct __darwin_mcontext64'
        ucp->uc_mcontext.regs[30] = (uintptr_t) &libucontext_trampoline;
        ~~~~~~~~~~~~~~~~ ^
arch/aarch64/makecontext.c:48:27: error: member reference type 'struct __darwin_mcontext64 *' is a pointer; did you mean to use '->'?
        regp = &(ucp->uc_mcontext.regs[0]);
                 ~~~~~~~~~~~~~~~~^
                                 ->
arch/aarch64/makecontext.c:48:28: error: no member named 'regs' in 'struct __darwin_mcontext64'
        regp = &(ucp->uc_mcontext.regs[0]);
                 ~~~~~~~~~~~~~~~~ ^
15 errors generated.
make: *** [arch/aarch64/makecontext.o] Error 1

That's a very recent install of latest Monterey.

@kov Finally I got it compiled with slight modifications of source code. Maybe, this intruction will work for you too :)

git clone https://github.com/kaniini/libucontext
cd libucontext
nano Makefile

Find assignment to LIBUCONTEXT_LINKER_FLAGS and replace it with:

LIBUCONTEXT_LINKER_FLAGS = -dynamiclib -install_name ${LIBUCONTEXT_SONAME} -current_version ${LIBUCONTEXT_SOVERSION} -compatibility_version ${LIBUCONTEXT_SOVERSION}

Now we are ready to make libucontext:

make FREESTANDING=yes ARCH=aarch64

Finally, copy resulting files to the default brew search folder /opt/homebrew:

cp libucontext.a /opt/homebrew/lib
cp libucontext.dylib /opt/homebrew/lib
cp -r include/* /opt/homebrew/include/

The last is optional, but useful. If the resulting .dylib is not in system search path, you'll have to specify DYLD_LIBRARY_PATH when launching a binary dynamically linked with this library.

Yes, on macOS, you need to use FREESTANDING feature.