LLVM 6 errors linking OpenSSL

1.8k views Asked by At

Xcode 6 GM and its LLVM 6 give this linking error:

Undefined symbols for architecture i386:
"_fopen$UNIX2003", referenced from:
  _BIO_new_file in libcrypto.a(bss_file.o)
  _file_ctrl in libcrypto.a(bss_file.o)
  _open_console in libcrypto.a(ui_openssl.o)
"_fputs$UNIX2003", referenced from:
  _write_string in libcrypto.a(ui_openssl.o)
  _read_string in libcrypto.a(ui_openssl.o)
"_fwrite$UNIX2003", referenced from:
  _send_fp_chars in libcrypto.a(a_strex.o)
  _write_fp in libcrypto.a(b_dump.o)
  _file_write in libcrypto.a(bss_file.o)
  _file_puts in libcrypto.a(bss_file.o)
"_strerror$UNIX2003", referenced from:
  _ERR_load_ERR_strings in libcrypto.a(err.o)
ld: symbol(s) not found for architecture i386
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Now, this answer suggests adding an ad-hoc .c file which, for the case above, would be:

#include <stdio.h>
#include <string.h>

FILE *fopen$UNIX2003( const char *filename, const char *mode )
{
    return fopen(filename, mode);
}

size_t fwrite$UNIX2003( const void *a, size_t b, size_t c, FILE *d )
{
    return fwrite(a, b, c, d);
}

void fputs$UNIX2003(const char *restrict c, FILE *restrict f)
{
    fputs(c, f);
}

char *strerror$UNIX2003(int errnum)
{
    return strerror(errnum);
}

It 'works', but is this the best (or even advisable) approach?

2

There are 2 answers

0
Jon G. On BEST ANSWER

As you guessed, no, that would not be an advisable approach to fix your LLVM linker woes in Xcode 6. Instead, assuming you're developing for iOS, what you need to do is rebuild OpenSSL for the new iOS 8 SDK. Here's a good project that will help you do that.

0
Adeel Ishaq On

in case this can save anyone some time, there's I've found to fix this specific linkers issues (adding this to any any cpp file):

extern "C"{
    size_t fwrite$UNIX2003( const void *a, size_t b, size_t c, FILE *d )
    {
        return fwrite(a, b, c, d);
    }
    char* strerror$UNIX2003( int errnum )
    {
        return strerror(errnum);
    }
    time_t mktime$UNIX2003(struct tm * a)
    {
        return mktime(a);
    }
    double strtod$UNIX2003(const char * a, char ** b) {
        return strtod(a, b);
    }
}