(I realise we’ve somewhat hijacked @romes’ original post, sorry about that, please let me know if we should move this to a thread of its own/github/somewhere)
@edsko That’s great news! I assume this is because hs-bindgen is built on top of libclang and lets it do all the hard work of understanding C?
You caught me in the middle of giving hs-bindgen a go, so I can probably give you many (many) more test cases if you’d like! 
I’m struggling a bit with limiting which types hs-bindgen-cli looks at, if there a way to say "give me definitions for everything from this (potentially #include
d) file, but don’t try to do everything that those types include? For example
typedef struct {
struct statfs *_Nonnull statfs;
es_mount_disposition_t disposition; /* field available only if message version >= 8 */
uint8_t reserved[60];
} es_event_mount_t;
Can I say I’d like bindings for es_event_mount_t
but not struct statfs
, just give me opaque pointers or something? I’ve been playing around the with the various --select
options, but can’t seem to find the middle ground of get everything defined anywhere in macOS’s SDK, or get nothing at all.
My current testing is using
export MOD=EndpointSecurity;
cabal run hs-bindgen-cli -- preprocess \
--target aarch64-apple-macosx \
--module $MOD -I /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include \
-I /nix/store/c5iby6817ak2wr3x3b3qvybsknp8xkjm-clang-19.1.5-lib/lib/clang/19/include/ \
--select-by-element-name '(enum |struct )?(es|ES).*' \
--enable-blocks \
--clang-option -mmacos-version-min=13.0 ./$MOD.h -o $MOD.hs \
--gen-binding-spec $MOD.hs.spec
With EndpointSecurity.h
just looking like.
#include <EndpointSecurity/EndpointSecurity.h>
Transitively that imports nearly everything provided by the OS/kernel.
Running it, I get a lot of warnings, and maybe 100 or so errors like:
[Error ] [HsBindgen] Missing declaration: 'struct es_fd_t'; did you select the declaration?
[Error ] [HsBindgen] Missing declaration: 'struct es_event_exec_t'; did you select the declaration?
[Error ] [HsBindgen] Missing declaration: 'struct es_string_token_t'; did you select the declaration?
[Error ] [HsBindgen] Missing declaration: 'struct es_event_exec_t'; did you select the declaration?
The other thing that seems to be causing plenty of issues is declarations like
OS_EXPORT
API_AVAILABLE(macos(10.15))
API_UNAVAILABLE(ios)
API_UNAVAILABLE(tvos, watchos)
es_return_t es_subscribe(es_client_t *_Nonnull client, const es_event_type_t *_Nonnull events, uint32_t event_count);
// Expands to
extern __attribute__((__visibility__("default")))
__attribute__((availability(macos,introduced=10.15)))
__attribute__((availability(ios,unavailable)))
__attribute__((availability(tvos,unavailable))) __attribute__((availability(watchos,unavailable)))
es_return_t es_subscribe(es_client_t *_Nonnull client, const es_event_type_t *_Nonnull events, uint32_t event_count);
which produce errors like
[Warning] [HsBindgen] Reparse error: "/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include/EndpointSecurity/ESClient.h" (line 35, column 20):
unexpected out of scope type specifier macro name "macos"
expecting function parameter
OS_EXPORT API_AVAILABLE ( macos ( 10.15 ) ) API_UNAVAILABLE ( ios ) API_UNAVAILABLE ( tvos , watchos ) es_return_t es_subscribe ( es_client_t * _Nonnull client , const es_event_type_t * _Nonnull events , uint32_t event_count )
This definitely feels like I’ve probably bitten off more than I can chew, but if there is a way to limit what gets examined, I might be able to get somewhere. I did see there’s a spec file, but haven’t looked into how I’d go about using that (I managed to make one when using a much simpler include header, so I guess Apple haven’t broken all standards).