在工作过程中使用到了OPENSSL库,编译时出现如下错误:
test.c:(.text+0x33b): undefined reference to `EVP_MD_CTX_new'
test.c:(.text+0x3af): undefined reference to `EVP_MD_CTX_free'
collect2: error: ld returned 1 exit status
看这个报错原因是:没有 `EVP_MD_CTX_new'的定义。
我的Makefile部分内容如下:
${TARGET} : ${BUILD_OBJS}
${CC} $^ -o $@ ${C_FLAGS} -lssl -lcrypto
${OBJ_DIR}/%.o : %.c
${CC} -c $^ -o $@ -I ${INC_DIR} ${C_FLAGS}
编译错误中没有提示说找不到静态库,那就说明链接了静态库' -lssl -lcrypto',但静态库中没有函数EVP_MD_CTX_new 的定义。问题原因可能是系统目录下的静态库与我使用的代码版本不匹配。
解决步骤一: 安装对应的版本的openssl
我从github拉openssl源码,切换到指定tag:OpenSSL_1_1_1(我在代码中使用的是该版本的函数) ,然后进行编译和安转v1.1.1版本的openssl到 /usr/local/ssl 目录下
解决步骤二:修改Makefile,指定静态库的路径
${TARGET} : ${BUILD_OBJS}
${CC} $^ -o $@ ${C_FLAGS} -L /usr/local/ssl/lib -lssl -lcrypto
${OBJ_DIR}/%.o : %.c
${CC} -c $^ -o $@ -I ${INC_DIR} ${C_FLAGS}
编译时继续报错,错误如下:
gcc ../../build/test.o -o ../../bin/test -L /usr/local/ssl/lib -lssl -lcrypto
../../build/test.o: In function `verify_signature':
test.c:(.text+0x34d): undefined reference to `EVP_MD_CTX_init'
collect2: error: ld returned 1 exit status
make: *** [../../bin/test] Error 1
此时,还是报没有函数定义的错误,但是与之前的报错函数不一样。
解决步骤三:修改Makefile,指定openssl的头文件路径
步骤二虽然指定了新的静态库链接路径,但是在编译.o文件时,头文件还使用的系统目录的文件,这样子头文件与静态库中的内容不一致了。
${TARGET} : ${BUILD_OBJS}
${CC} $^ -o $@ ${C_FLAGS} -L /usr/local/ssl/lib -lssl -lcrypto
${OBJ_DIR}/%.o : %.c
${CC} -c $^ -o $@ -I ${INC_DIR} -I /usr/local/ssl/include ${C_FLAGS}
执行 make clean删除之前编译的.o文件,再执行make重新编译,编译ok!
# make clean; make
rm -rf ../../build/test.o ../../bin/test
gcc -c test.c -o ../../build/test.o -I ../../include -I /usr/local/ssl/include
gcc ../../build/test.o -o ../../bin/test -L /usr/local/ssl/lib -lssl -lcrypto
#
(无用内容)重新整理makefile,使其更美观,更具有阅读性
include ../../Makefile.conf
ROOT_DIR = ../..
TARGET = ${BIN_DIR}/${BIN}
# 所有头文件
INC_ALL += -I ${INC_DIR}
INC_ALL += -I ${SSL_INC_DIR}
# 所有静态库的路径
LIB_DIR_ALL += -L ${SSL_LIB_DIR}
# 所有要链接的静态库内容
LIBS_ALL += ${SSL_LIBS}
all: ${BUILD_OBJS} ${TARGET}
${TARGET} : ${BUILD_OBJS}
${CC} $^ -o $@ ${C_FLAGS} ${LIB_DIR_ALL} ${LIBS_ALL}
${OBJ_DIR}/%.o : %.c
${CC} -c $^ -o $@ ${INC_ALL} ${C_FLAGS}
clean:
rm -rf ${BUILD_OBJS} ${TARGET}