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

6

我正在尝试使用OpenSSL在C程序中计算sha1哈希值。我正在Mac OS X Yosemite上使用clang进行编译,使用Intel i7(因此是64位)。

相关的代码大致如下:

#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”函数未定义)。有什么解决方法吗?
编辑:事实证明,我试图使用一个不存在的函数(“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)

1
你的编译和链接命令是什么? - jww
目前只有"clang -Wall main.c"。我在/opt/local/include/openssl下安装了openssl。我需要以某种方式让clang知道这个吗? - orcaman
哦,如果我使用 -v 参数运行编译器,我会发现 clang 正在 /usr/local/include 中查找包含文件,其中也包括 openssl 和 evp.h。所以很奇怪它仍然无法成功链接。 - orcaman
请查看更新后的回答。这是一个常见的疏忽。 - jww
1
我添加了静态链接的信息,以避免意外的运行时错误。我之前错过了这个细节,但在你的一个评论中看到了它。 - jww
2个回答

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(我过滤了DEPRECATED_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消息摘要接口。
将OpenSSL库链接到程序。您需要在编译命令的末尾添加 -lcrypto

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

你可能会遇到更多问题,因为你可能会运行时链接到错误版本的OpenSSL库。对于这个问题,请参见在XCode中静态链接OpenSSL。从命令行和Xcode中也存在同样的问题。

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

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

档案文件只是一组对象文件的集合,因此可以在需要对象文件的地方使用档案文件。

OS X不支持。另一种解决方案是使用构建OpenSSL和您的程序,以便在运行时加载正确版本的库。有关详细信息,请参见OpenSSL wiki上的Compilation and Installation | Using RPATHs和Stack Overflow上的Build OpenSSL with RPATH?


点赞。你是对的 - 没有哈希函数。但是,当尝试使用evp接口时,我仍然遇到相同的错误。我编辑了我的问题以反映我所学到的内容,感谢你的帮助。 - orcaman

1
你正在使用哪个SDK和Xcode的版本?OpenSSL在OS X 10.7中被弃用,并从附带Xcode 7 Beta的10.11 SDK中删除。单独下载OpenSSL应该可以工作,但你可能需要更改项目配置以适应新位置。

1
我在/opt/local/include/openssl下安装了openssl。我通过Mac Ports更新了它,所以我有最新版本。为了使链接过程正常工作,我需要让clang知道这个位置吗?关于Xcode/SDK - 我没有使用Xcode。关于SDK版本 - 你指的是哪个SDK? - orcaman
如果您不使用Xcode,那么您是否使用了苹果的命令行工具,或者是否构建了自己的Clang版本?无论哪种方式,请问您使用的是哪个版本,并且能否将失败的命令输出附上“-v”选项? - Flash Sheridan
Mac OS X和MacPorts是重要的细节。但只有在你使用这个平台一段时间后才会意识到它们的重要性。 - jww

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接