macOS link error with static curl — missing ___isOSVersionAtLeast · Issue #279 · alexcrichton/curl-rust (original) (raw)

Linking with the static feature on macOS 10.13 fails with the following error:

Undefined symbols for architecture x86_64:
  "___isOSVersionAtLeast", referenced from:
      _sectransp_connect_step1 in libcurl_sys-72a3db42ebafc5cb.rlib(sectransp.o)
      _sectransp_connect_step2 in libcurl_sys-72a3db42ebafc5cb.rlib(sectransp.o)
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

The problem is that rustc links with the -nodefaultlibs flag. This prevents cc from linking with /Library/Developer/CommandLineTools/usr/lib/clang/10.0.0/lib/darwin/libclang_rt.osx.a (or whatever version of xcode you have), which is where ___isOSVersionAtLeast is located.

This is caused by the use of things like __builtin_available(macOS 10.13.4, iOS 11, tvOS 11, *). Usually clang will statically strip out this builtin, which is why it normally works on 10.14. However, if you are building on an older version, it adds the call to ___isOSVersionAtLeast at runtime. Strangely, using a minor semver version (like 10.13.4 instead of 10.13) also prevents it from being determined statically when building on 10.13 (presumably it defaults to --mmacosx-version-min=10.13 which sets the floor to 10.13.0 regardless which minor version you are on).

Here's a reduced example project that will fail on 10.14 (by testing for 10.15).
foo.zip

Hopefully that's all clear. Unfortunately I don't know how to fix this. Presumably rustc uses -nodefaultlibs for a good reason. It seems unlikely to me, but maybe there is a way to discover the correct location of libclang_rt.osx.a and include it in the link list? A more draconian solution would be to unset HAVE_BUILTIN_AVAILABLE, but I think that would disable some important features (like TLS 1.3). Perhaps Alex has some clever ideas?