简体   繁体   English

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

[英]Undefined symbols for architecture x86_64 (clang)

I'm trying to use OpenSSL to compute sha1 hash from ac program.我正在尝试使用 OpenSSL 从 ac 程序计算 sha1 哈希。 I am compiling with clang on Mac OS X Yosemite with an Intel i7 (so 64 bit).我正在 Mac OS X Yosemite 上使用 Intel i7(所以 64 位)使用 clang 进行编译。

The relevant piece of code is roughly like so:相关的一段代码大致如下:

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

The thing is, when using the "hash" function from openssl/evp.h , compiling with clang yields the following error:问题是,当使用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)

So it looks like OpenSSL is not found by the linker (the "hash" function is unidentified).所以看起来链接器没有找到 OpenSSL(“哈希”函数未识别)。 Any ideas on how to fix this?有想法该怎么解决这个吗?

EDIT:编辑:

It turns out that I was trying to use a function that does not exist ("hash") - sorry for misleading you about that.事实证明,我试图使用一个不存在的函数(“哈希”) - 抱歉误导您。

However I'm still having quite the same problem: including openssl/evp.h does not seem to work.但是我仍然遇到同样的问题:包括openssl/evp.h似乎不起作用。

This is the hash function that I am using, it uses evp to perform sha1 encoding:这是我正在使用的哈希函数,它使用 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;
}

And then I call:然后我打电话:

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

I am compiling same as before, this is my compile command (pretty simple):我和以前一样编译,这是我的编译命令(很简单):

 clang main.c

And I'm getting the following error from the linker:我从链接器收到以下错误:

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)
#include <openssl/evp.h> ... unsigned char outHash[20]; hash("SHA1","abcd", 20, outHash);

OpenSSL does not have a int hash(...) or char* hash(...) function. OpenSSL 没有int hash(...)char* hash(...)函数。

$ cat /usr/include/openssl/evp.h | grep hash $ cat /usr/include/openssl/evp.h | grep hash returns 0 hits. $ cat /usr/include/openssl/evp.h | grep hash返回 0 个命中。 man 3 hash returns BSD's "hash database access method" . man 3 hash返回 BSD 的“哈希数据库访问方法”


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

Latching on to _getRandomSHA1 , there is a SHA function, but it's available from sha.h , and not evp.h (I filtered out the DEPRECATED_IN... macro):锁定到_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);
...

I believe it uses a static buffer, and its use is discouraged.我相信它使用静态缓冲区,不鼓励使用它。

The project recommends using EVP Message Digests interface now.项目现在推荐使用EVP Message Digests接口。


( EDIT ): I am compiling same as before, this is my compile command (pretty simple): (编辑):我和以前一样编译,这是我的编译命令(非常简单):
clang main.c叮当主.c

See Linking OpenSSL libraries to a program .请参阅将 OpenSSL 库链接到程序 You need to add -lcrypto to the end of the compile command.您需要将-lcrypto添加到编译命令的末尾


( EDIT , from comment): I have openssl at /opt/local/include/openssl.... 编辑,来自评论):我在 /opt/local/include/openssl 有 openssl ....

You are going to have more problems because you are probably runtime linking against the wrong version of the OpenSSL library.您将遇到更多问题,因为您可能正在运行时链接到错误版本的 OpenSSL 库。 For that problem, see Statically link OpenSSL in XCode .对于该问题,请参阅XCode 中的静态链接 OpenSSL The same problem exists from the command line and Xcode.命令行和 Xcode 也存在同样的问题。

Here's the easiest solution.这是最简单的解决方案。 Notice that it does not use -lcrypto ( -lfoo is usually the solution, except when runtime linking to the wrong shared object becomes a problem):请注意,它使用-lcrypto-lfoo通常是解决方案,除非运行时链接到错误的共享对象成为问题):

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

An archive is just a collection of object files, so an archive can be used in place where an object file is required.档案只是目标文件的集合,因此可以在需要目标文件的地方使用档案。

OS X does not honor RPATH s. OS X 不支持RPATH Another solution is to build OpenSSL and your program with an RPATH so the correct version of the library is loaded at runtime. 另一种解决方案是使用 RPATH构建 OpenSSL 和您的程序,以便在运行时加载正确版本的库。 For that, see Compilation and Installation | 为此,请参阅 编译和安装 | Using RPATHs on the OpenSSL wiki and Build OpenSSL with RPATH? 在 OpenSSL wiki 上 使用 RPATHs使用 RPATH 构建 OpenSSL? on Stack Overflow. 在堆栈溢出上。

Which SDK are you using, and which version of Xcode?您使用的是哪个 SDK,哪个版本的 Xcode? OpenSSL was deprecated in OS X 10.7 and removed from the 10.11 SDK, which ships with the Xcode 7 Beta. OpenSSL 在 OS X 10.7 中被弃用,并从 Xcode 7 Beta 附带的 10.11 SDK 中删除。 Downloading OpenSSL separately should work, though you may need to change your project configuration for the new location.单独下载 OpenSSL 应该可以工作,但您可能需要更改新位置的项目配置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM