Как исправить makefile для правильного включения -lcrypto, чтобы избежать ошибки компоновщика: неопределенная ссылка на `EVP_CIPHER_CTX_new’

#c #makefile #openssl

#c #makefile #openssl

Вопрос:

Прежде всего, я пытаюсь использовать

 #include <openssl/evp.h>
  

Я получаю общую ошибку компоновщика:

 undefined reference to `EVP_CIPHER_CTX_new'
  

которую, я знаю, можно решить, используя -lcrypto при компиляции. Я могу сделать это при компиляции вручную, т.е

 g   encrv2.cpp -o encrv2 -lcrypto 
  

хотя я пытаюсь создать Makefile и помещаю свои функции шифрования / дешифрования в отдельный заголовочный файл (AesGcm) и не могу обойти проблему компоновщика. Ниже приведен мой Makefile на данный момент и вывод, когда я пытаюсь сделать все.

 CXX = g  
CXXFLAGS = -std=c  14
LDFLAGS= -lcrypto

all: encrv2

AesGcm.o: AesGcm.cpp AesGcm.h
    $(CXX) $(CXXFLAGS) -c AesGcm.cpp $(LDFLAGS)

encrv2.o: encrv2.cpp AesGcm.h
    $(CXX) $(CXXFLAGS) -c encrv2.cpp $(LDFLAGS)

encrv2: encrv2.o AesGcm.o

clean:
    rm -f *~ *.o encrv2 
  

Выдает следующую ошибку:

 cc -lcrypto  encrv2.o AesGcm.o   -o encrv2
AesGcm.o: In function `AesGcm::encrypt(unsigned char*, int, unsigned char*, int, unsigned char*, unsigned char*, unsigned char*, unsigned char*)':
AesGcm.cpp:(.text 0x3e): undefined reference to `EVP_CIPHER_CTX_new'
AesGcm.cpp:(.text 0x58): undefined reference to `EVP_aes_256_gcm'
AesGcm.cpp:(.text 0x77): undefined reference to `EVP_EncryptInit_ex'
AesGcm.cpp:(.text 0xae): undefined reference to `EVP_EncryptInit_ex'
AesGcm.cpp:(.text 0xe0): undefined reference to `EVP_EncryptUpdate'
AesGcm.cpp:(.text 0x111): undefined reference to `EVP_EncryptUpdate'
AesGcm.cpp:(.text 0x148): undefined reference to `EVP_EncryptFinal_ex'
AesGcm.cpp:(.text 0x17b): undefined reference to `EVP_CIPHER_CTX_ctrl'
AesGcm.cpp:(.text 0x197): undefined reference to `EVP_CIPHER_CTX_free'
AesGcm.o: In function `AesGcm::decrypt(unsigned char*, int, unsigned char*, int, unsigned char*, unsigned char*, unsigned char*, unsigned char*)':
AesGcm.cpp:(.text 0x30a): undefined reference to `EVP_CIPHER_CTX_new'
AesGcm.cpp:(.text 0x324): undefined reference to `EVP_aes_256_gcm'
AesGcm.cpp:(.text 0x343): undefined reference to `EVP_DecryptInit_ex'
AesGcm.cpp:(.text 0x37a): undefined reference to `EVP_DecryptInit_ex'
AesGcm.cpp:(.text 0x3ac): undefined reference to `EVP_DecryptUpdate'
AesGcm.cpp:(.text 0x3dd): undefined reference to `EVP_DecryptUpdate'
AesGcm.cpp:(.text 0x410): undefined reference to `EVP_CIPHER_CTX_ctrl'
AesGcm.cpp:(.text 0x441): undefined reference to `EVP_DecryptFinal_ex'
AesGcm.cpp:(.text 0x450): undefined reference to `EVP_CIPHER_CTX_free'
collect2: error: ld returned 1 exit status
<builtin>: recipe for target 'encrv2' failed
make: *** [encrv2] Error 1
  

Ответ №1:

Вы используете неправильную переменную.

LDFLAGS предназначены для использования для флагов компоновщика, таких как -L , и т.д., Которые должны быть «раньше» в строке ссылки. Эта переменная не предназначена для библиотек, которые добавляются в строку ссылки.

Для этого вы должны использовать LDLIBS переменную:

 LDLIBS = -lcrypto
  

Правило по умолчанию для связывания, которое вы используете, поскольку вы сами его не пишете, выглядит примерно так:

 %: %.o
#  recipe to execute (built-in):
        $(CC) $(LDFLAGS) $(TARGET_ARCH) $^ $(LDLIBS) -o $@
  

Обратите внимание, что это LDLIBS следует за вашими объектными файлами, что вам нужно, чтобы избежать этой ошибки компоновщика. Порядок объектных файлов по сравнению с библиотеками и между самими библиотеками очень важен для компоновщика.

Комментарии:

1. На самом деле я не знал, что существует правило по умолчанию для связывания, я смотрел на make-файл OPs и спрашивал себя, как он вообще пытается связать, спасибо: D