【问题标题】:Undefined symbols for architecture x86_64 (clang)架构 x86_64 (clang) 的未定义符号
【发布时间】:2015-06-19 13:02:15
【问题描述】:

我正在尝试使用 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 中的“hash”函数时,使用 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(“哈希”函数无法识别)。有想法该怎么解决这个吗?

编辑:

事实证明,我试图使用一个不存在的函数(“哈希”) - 很抱歉在这方面误导了您。

但是我仍然遇到同样的问题:包括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)

【问题讨论】:

  • 你的编译链接命令是什么?
  • 目前只是“clang -Wall main.c”。我在 /opt/local/include/openssl 下有 openssl。我需要以某种方式让 clang 知道这件事吗?
  • 嗯,如果我用 -v 运行编译,我看到 clang 正在寻找 /usr/local/include 上的包含,它下面还有 openssl 和 evp.h。所以很奇怪,它仍然无法成功链接
  • 查看更新后的答案。这是一个常见的疏忽。
  • 我添加了关于静态链接的信息以避免意外的运行时错误。我之前错过了细节,但在你的一个 cmets 中看到了。

标签: c macos openssl clang llvm


【解决方案1】:
#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 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 

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

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

【讨论】:

  • 赞成。你是对的 - 没有哈希函数。仍然,当尝试使用 evp 接口时,我得到了同样的错误。我编辑了我的问题以反映我所学到的知识,感谢您的帮助。
【解决方案2】:

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

【讨论】:

  • 我在 /opt/local/include/openssl 有 openssl。我通过 Mac Ports 更新了它,所以我有最新版本。我是否需要让 clang 知道这个位置才能使链接过程正常工作?关于 Xcode/SDK - 不使用 Xcode。关于 SDK 版本 - 你的意思是什么 SDK?
  • 如果您不使用 Xcode,您是使用 Apple 的命令行工具,还是构建了自己的 Clang 版本?无论哪种方式,哪个版本,您可以使用 -v 选项发布失败命令的输出吗?
  • Mac OS X 和 MacPorts 是重要的细节。 (但您只有在使用该平台一段时间后才会意识到这一点)。
猜你喜欢
  • 2014-09-08
  • 1970-01-01
  • 2015-10-09
  • 1970-01-01
  • 2014-08-07
  • 2012-07-20
  • 1970-01-01
  • 2015-08-23
  • 2014-05-27
相关资源
最近更新 更多