The Crystal Programming Language Forum

[solved] Linking macOS Core+CoreFoundation problems

I’m trying to have a Crystal program read and write from the macOS keychain. And to start poking around at this I’m trying to just call this function Apple Developer Documentation

There aren’t very many public programs I could find that link Foundation or CoreFoundation, and the ones I could find were from 2014

If I could get just one function to link I could build from there, but I’m not sure what is going wrong.

I’m trying

@[Link(framework: "Foundation")]
@[Link(framework: "CoreFoundation")]
lib LibCF
  # https://developer.apple.com/documentation/security/1401659-secitemadd?language=objc
  fun sec_item_add = SecItemAdd(a : Void*, b : Void*) : Void*
end

LibCF.sec_item_add(nil, nil)

but I get

Undefined symbols for architecture x86_64:
  "_SecItemAdd", referenced from:
      ___crystal_main in _main.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
Error: execution of command failed with code: 1: `cc "${@}" -o /Users/will/.cache/crystal/crystal-run-a.tmp  -rdynamic -L/usr/local/lib -framework CoreFoundation -framework Foundation -lpcre -lgc -lpthread /usr/local/Cellar/crystal/1.0.0/src/ext/libcrystal.a -L/usr/local/Cellar/libevent/2.1.12/lib -levent -liconv -ldl`

Crystal is adding the -framework parts correctly, but maybe something is wrong with the name mangling? Not sure how to debug this, so any help is appreciated.

SecItemAdd is part of Security framework. So you should be linking against that

@[Link(framework: "Foundation")]
@[Link(framework: "Security")]
lib LibCF
  # https://developer.apple.com/documentation/security/1401659-secitemadd?language=objc
  fun sec_item_add = SecItemAdd(a : Void*, b : Void*) : Void*
end

LibCF.sec_item_add(nil, nil)

Ahh, thank you! I now see that part on the apple docs where it says the framework it’s in. I’ve never read their docs before and missed that bit on this side completely.