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

orc*_*man 5 c macos openssl llvm clang

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

相关的一段代码大致如下:

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

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

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

所以看起来链接器没有找到 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;
}
Run Code Online (Sandbox Code Playgroud)

然后我打电话:

hash("SHA1","abcd", 20, outHash);
Run Code Online (Sandbox Code Playgroud)

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

 clang main.c
Run Code Online (Sandbox Code Playgroud)

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

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)
Run Code Online (Sandbox Code Playgroud)

jww*_*jww 4

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

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
Run Code Online (Sandbox Code Playgroud)

锁定_getRandomSHA1,有一个SHA函数,但它可以从sha.h,而不是evp.h(我过滤掉了DEPRECATED_IN...宏):

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

我相信它使用静态缓冲区,并且不鼓励使用它。

项目现在推荐使用EVP Message Digests接口。


编辑):我的编译与以前相同,这是我的编译命令(非常简单):
clang main.c

请参阅将 OpenSSL 库链接到程序。您需要添加-lcrypto到编译命令的末尾。


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

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

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

 clang main.c -I /opt/local/include /opt/local/lib/libcrypto.a -o my_hash.exe 
Run Code Online (Sandbox Code Playgroud)

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

OS X 不支持RPATHs。另一个解决方案是构建 OpenSSL 和您的程序,以便RPATH在运行时加载正确版本的库。为此,请参阅编译和安装 | 在 OpenSSL wiki 上使用 RPATH并使用 RPATH 构建 OpenSSL?在堆栈溢出上。