架构的未定义符号x86_64(clang)

时间:2015-06-19 13:02:15

标签: c macos openssl clang llvm

我正在尝试使用OpenSSL从c程序计算sha1哈希值。我正在使用Intel i7(64位)在Mac OS X Yosemite上编译clang。

相关的代码大致如此:

#include <openssl/evp.h>
...
unsigned char outHash[20]; 
hash("SHA1","abcd", 20, outHash);

问题是,当使用openssl/evp.h中的“哈希”函数时,使用clang进行编译会产生以下错误:

Undefined symbols for architecture x86_64:
  "_hash", referenced from:
      _getRandomSHA1 in main-68ccd6.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

因此看起来连接器找不到OpenSSL(“哈希”功能未被识别)。有想法该怎么解决这个吗?

修改

事实证明我试图使用一个不存在的函数(“hash”) - 抱歉误导了你。

但是我仍然遇到了同样的问题:包括openssl/evp.h似乎不起作用。

这是我正在使用的哈希函数,它使用evp来执行sha1编码:

unsigned int hash(const char *mode, const char* dataToHash, size_t dataSize, unsigned char* outHashed) {
    unsigned int md_len = -1;
    const EVP_MD *md = EVP_get_digestbyname(mode);
    if(NULL != md) {
        EVP_MD_CTX mdctx;
        EVP_MD_CTX_init(&mdctx);
        EVP_DigestInit_ex(&mdctx, md, NULL);
        EVP_DigestUpdate(&mdctx, dataToHash, dataSize);
        EVP_DigestFinal_ex(&mdctx, outHashed, &md_len);
        EVP_MD_CTX_cleanup(&mdctx);
    }
    return md_len;
}

然后我打电话给:

hash("SHA1","abcd", 20, outHash);

我和以前一样编译,这是我的编译命令(非常简单):

 clang main.c

我从链接器收到以下错误:

Undefined symbols for architecture x86_64:
  "_EVP_DigestFinal_ex", referenced from:
      _hash in main-935849.o
  "_EVP_DigestInit_ex", referenced from:
      _hash in main-935849.o
  "_EVP_DigestUpdate", referenced from:
      _hash in main-935849.o
  "_EVP_MD_CTX_cleanup", referenced from:
      _hash in main-935849.o
  "_EVP_MD_CTX_init", referenced from:
      _hash in main-935849.o
  "_EVP_get_digestbyname", referenced from:
      _hash in main-935849.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

2 个答案:

答案 0 :(得分:4)

#include <openssl/evp.h>
...
unsigned char outHash[20]; 
hash("SHA1","abcd", 20, outHash);

OpenSSL没有int hash(...)char* hash(...)功能。

$ cat /usr/include/openssl/evp.h | grep hash返回0次点击。 man 3 hash返回BSD的“哈希数据库访问方法”

Undefined symbols for architecture x86_64:
  "_hash", referenced from:
      _getRandomSHA1 in main-68ccd6.o

锁定到_getRandomSHA1,有一个SHA功能,但可以从sha.h获取,而不是evp.h(我过滤了DEPRECTAED_IN...宏):

$ cat /usr/include/openssl/sha.h | grep SHA | grep char
...
unsigned char *SHA(const unsigned char *d, size_t n, unsigned char *md);
...

我认为它使用静态缓冲区,不鼓励使用它。

项目建议现在使用EVP Message Digests界面。

  

EDIT ):我和以前一样编译,这是我的编译命令   (很简单):
       clang main.c

Linking OpenSSL libraries to a program。您需要将 -lcrypto 添加到编译命令的 end

  

编辑,来自评论):我在/ opt / local / include / openssl上有openssl ....

您将遇到更多问题,因为您可能正在运行时链接到错误的版本的OpenSSL库。对于该问题,请参阅Statically link OpenSSL in XCode。命令行和Xcode存在同样的问题。

这是最简单的解决方案。请注意, 使用-lcrypto-lfoo通常是解决方案,除非运行时链接到错误的共享对象成为问题):

 clang main.c -I /opt/local/include /opt/local/lib/libcrypto.a -o my_hash.exe 

存档只是目标文件的集合,因此可以在需要目标文件的位置使用存档。

OX S不尊重RPATHs 另一个解决方案是使用RPATH构建OpenSSL和您的程序,以便在运行时加载正确的库版本。为此,请参阅OpenSSL wiki上的Compilation and Installation | Using RPATHs和Stack Overflow上的Build OpenSSL with RPATH?

答案 1 :(得分:1)

您使用的是哪个SDK,以及哪个版本的Xcode? OpenSSL在OS X 10.7中已被弃用,并从10.11 SDK中删除,后者随Xcode 7 Beta一起提供。单独下载OpenSSL应该可以工作,但您可能需要更改新位置的项目配置。