Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Undefined symbols for architecture x86_64 on OS X with fat library

I have build libcrypto.a and libssl.a myself from source, specifying darwin64-x86_64-cc (for 64-bit) and darwin-i386-cc (for 32-bit) to OpenSSL's configure script.
Created the fat libraries with lipo and added them as a dependency in my Xcode project.

However, I'am getting an undefined symbol error:

undefined symbols for architecture x86_64:
  "_OPENSSL_ia32cap_P", referenced from:
      _AES_cbc_encrypt in libcrypto.a(aes-x86_64.o)
ld: symbol(s) not found for architecture x86_64

Note: Using the same technique works fine for iOS, though.

lipo -detailed_info libcrypto.a reveals:

Fat header in: libcrypto.a
fat_magic 0xcafebabe
nfat_arch 2
architecture i386
    cputype CPU_TYPE_I386
    cpusubtype CPU_SUBTYPE_I386_ALL
    offset 48
    size 2700624
    align 2^2 (4)
architecture x86_64
    cputype CPU_TYPE_X86_64
    cpusubtype CPU_SUBTYPE_X86_64_ALL
    offset 2700672
    size 3938432
    align 2^2 (4)
like image 692
Leandros Avatar asked Mar 09 '15 14:03

Leandros


People also ask

What is undefined symbols for architecture x86_64?

Why Is the Undefined Symbols for Architecture x86_64: Error Happening? This error is happening due to the lack of included values inside the declared statements in your code. The browser is going to render the information incorrectly and show this error, especially if you are working with Main and Similarity tools.

How do I fix undefined symbol in XCode?

The error Undefined symbols for architecture arm64: "_OBJC_CLASS_$_SKAdImpression" during the iOS build usually happens if XCode or CocoaPods version is lower than required. To fix it update XCode to 12.5 or higher and CocoaPods to 1.10. 0 or higher.


1 Answers

It looks to be a bug in the code generator for x64 in the static library case.

The easiest, non patch openssl change workaround is to add a reference to OPENSSL_cleanse somewhere in your code, even if it's not used. That will fix up the link-time reference.

What's actually happening is that the symbol is being referenced in some assembly code.

The assembly code simply says that _OPENSSL_ia32cap_P is an extern symbol, without making the cross-link to state that it needs to be linked in. This works for libcrypto.dylib because the reference is resolved when generating the .dylib file; however the reference is never resolved in the .a case because the only code that actually contains the symbol is x86_64cpuid.o, which only gets linked in if you use any of the routines provided by that .o.

Symbols in this file includes OPENSSL_cleanse, so if you reference this routine, the link works.

like image 141
Petesh Avatar answered Sep 28 '22 17:09

Petesh