前言
Thrift依赖OpenSSL,低版本的Thrift在高版本的OpenSSL下链接编译提示出错
Thrift依赖Boost,暂时没有发现版本的要求
0.20.0源码编译
0.20.0版本搭配OpenSSL 1.1.1l ,直接编译通过
./configure --with-cpp --without-python --without-java --without-lua --without-csharp --without-erlang --without-php --without-php_extension --without-haskell --without-perl --without-go --with-boost=/opt/cmms/3thrdparty/boost --prefix=/home/dong/out
./configure --with-cpp --without-python --without-java --without-lua --without-csharp --without-erlang --without-php --without-php_extension --without-haskell --without-perl --without-go --with-boost=/opt/cmms/3thrdparty/boost --prefix=/home/dong/out
0.9.0源码编译
当前测试版本OpenSSL1.0.2h
./configure --with-cpp --without-python --without-java --without-lua --without-csharp --without-erlang --without-php --without-php_extension --without-haskell --without-perl --without-go --with-boost=/opt/cmms/3thrdparty/boost --prefix=/home/dong/out LDFLAGS="-L/opt/cmms/3thrdparty/openssl/lib" CPPFLAGS="-I/opt/cmms/3thrdparty/openssl/include"
./configure --with-cpp --without-python --without-java --without-lua --without-csharp --without-erlang --without-php --without-php_extension --without-haskell --without-perl --without-go --with-boost=/opt/cmms/3thrdparty/boost --prefix=/home/dong/out LDFLAGS="-L/opt/cmms/3thrdparty/openssl/lib" CPPFLAGS="-I/opt/cmms/3thrdparty/openssl/include"
LDFLAGS和CPPFLAGS指定OpenSSL头文件和库文件目录
备注:只拷贝代码中LDFLAGS和CPPFLAGS,而不是文本中的,空格会被编码成其他字符
checking for BN_init in -lcrypto... no
Kylin Linux Advanced Server V10 (SP3)编译thrift-0.9.0,指定with-boost参数以后,编译提示出错:
checking for BN_init in -lcrypto... no
configure: error: "Error: libcrypto required."
编译指令
./configure --with-go=no --prefix=/home/test --with-boost=/home/boost
下载更新的thrift-0.20.0版本没有相关问题
通过man手册查看相关函数
[root@localhost dong]# man BN_init
没有 BN_init 的手册页条目
[root@localhost dong]# man BN_NEW
SYNOPSIS
#include <openssl/bn.h>
BIGNUM *BN_new(void);
BIGNUM *BN_secure_new(void);
void BN_clear(BIGNUM *a);
void BN_free(BIGNUM *a);
void BN_clear_free(BIGNUM *a);
DESCRIPTION
BN_new() allocates and initializes a BIGNUM structure. BN_secure_new() does the same except that the secure
heap OPENSSL_secure_malloc(3) is used to store the value.
BN_clear() is used to destroy sensitive data such as keys when they are no longer needed. It erases the
void BN_clear(BIGNUM *a);
void BN_free(BIGNUM *a);
void BN_clear_free(BIGNUM *a);
DESCRIPTION
BN_new() allocates and initializes a BIGNUM structure. BN_secure_new() does the same except that the secure
heap OPENSSL_secure_malloc(3) is used to store the value.
BN_clear() is used to destroy sensitive data such as keys when they are no longer needed. It erases the
memory used by a and sets it to the value 0. If a is NULL, nothing is done.
BN_free() frees the components of the BIGNUM, and if it was created by BN_new(), also the structure itself.
BN_clear_free() additionally overwrites the data before the memory is returned to the system. If a is NULL,
nothing is done.
RETURN VALUES
BN_new() and BN_secure_new() return a pointer to the BIGNUM initialised to the value 0. If the allocation
fails, they return NULL and set an error code that can be obtained by ERR_get_error(3).
BN_clear(), BN_free() and BN_clear_free() have no return values.
SEE ALSO
ERR_get_error(3), OPENSSL_secure_malloc(3)
HISTORY
BN_init() was removed in OpenSSL 1.1.0; use BN_new() instead.
SSLeay 0.9.1b 新增BN_init函数
相关头文件#include <openssl/bn.h>
OpenSSL 1.1.0已经移除了BN_init函数,采用BN_new函数代替
解决
删除configure文件中的相关检测
20200 if test "$have_cpp" = "yes" ; then
20201 # mingw toolchain used to build "Thrift Compiler for Windows"
20202 # does not support libcrypto, so we just check if we building the cpp library
20203 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for BN_init in -lcrypto" >&5
20204 $as_echo_n "checking for BN_init in -lcrypto... " >&6; }
20205 if ${ac_cv_lib_crypto_BN_init+:} false; then :
20206 $as_echo_n "(cached) " >&6
20207 else
20208 ac_check_lib_save_LIBS=$LIBS
20209 LIBS="-lcrypto $LIBS"
20210 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
20211 /* end confdefs.h. */
20212
20213 /* Override any GCC internal prototype to avoid an error.
20214 Use char because int might match the return type of a GCC
20215 builtin and then its argument prototype would still apply. */
20216 #ifdef __cplusplus
20217 extern "C"
20218 #endif
20219 char BN_init ();
20220 int
20221 main ()
20222 {
20223 return BN_init ();
20224 ;
20225 return 0;
20226 }
20227 _ACEOF
20228 if ac_fn_cxx_try_link "$LINENO"; then :
20229 ac_cv_lib_crypto_BN_init=yes
20230 else
20231 ac_cv_lib_crypto_BN_init=no
20232 fi
20233 rm -f core conftest.err conftest.$ac_objext \
20234 conftest$ac_exeext conftest.$ac_ext
20235 LIBS=$ac_check_lib_save_LIBS
20236 fi
20237 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_crypto_BN_init" >&5
20238 $as_echo "$ac_cv_lib_crypto_BN_init" >&6; }
20239 if test "x$ac_cv_lib_crypto_BN_init" = xyes; then :
20240 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for SSL_ctrl in -lssl" >&5
20241 $as_echo_n "checking for SSL_ctrl in -lssl... " >&6; }
20242 if ${ac_cv_lib_ssl_SSL_ctrl+:} false; then :
20243 $as_echo_n "(cached) " >&6
20244 else
20245 ac_check_lib_save_LIBS=$LIBS
20246 LIBS="-lssl -lcrypto
20247 $LIBS"
20248 cat confdefs.h - <<_ACEOF >conftest.$ac_ext
20249 /* end confdefs.h. */
20200 /* Override any GCC internal prototype to avoid an error.
20201 Use char because int might match the return type of a GCC
20202 builtin and then its argument prototype would still apply. */
20203 #ifdef __cplusplus
20204 extern "C"
20205 #endif
20206 char SSL_ctrl ();
20207 int
20208 main ()
20209 {
20210 return SSL_ctrl ();
20211 ;
20212 return 0;
20213 }
20214 _ACEOF
20215 if ac_fn_cxx_try_link "$LINENO"; then :
20216 ac_cv_lib_ssl_SSL_ctrl=yes
20217 else
20218 ac_cv_lib_ssl_SSL_ctrl=no
20219 fi
20220 rm -f core conftest.err conftest.$ac_objext \
20221 conftest$ac_exeext conftest.$ac_ext
20222 LIBS=$ac_check_lib_save_LIBS
20223 fi
20224 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_ssl_SSL_ctrl" >&5
20225 $as_echo "$ac_cv_lib_ssl_SSL_ctrl" >&6; }
20226 if test "x$ac_cv_lib_ssl_SSL_ctrl" = xyes; then :
20227 LIBS="-lssl -lcrypto $LIBS"
20228 else
20229 as_fn_error $? "\"Error: libssl required\"" "$LINENO" 5
20230 fi
20231
20232 else
20233 as_fn_error $? "\"Error: libcrypto required.\"" "$LINENO" 5
20234
20235 fi
20236
20237 fi
替换为
LIBS="-lssl -lcrypto $LIBS"
configure: error: "Error: libcrypto required."
说明没有找到相匹配的OpenSSL版本库
mutexes = shared_array<Mutex>(new Mutex[::CRYPTO_num_locks()]);
src/thrift/transport/TSSLSocket.cpp: In static member function 'static void apache::thrift::transport::TSSLSocketFactory::initializeOpenSSL()':
src/thrift/transport/TSSLSocket.cpp:535:32: error: expected primary-expression before '(' token
mutexes = shared_array<Mutex>(new Mutex[::CRYPTO_num_locks()]);
^
In file included from /usr/include/openssl/bio.h:20:0,
from /usr/include/openssl/err.h:21,
from src/thrift/transport/TSSLSocket.cpp:34:
src/thrift/transport/TSSLSocket.cpp:535:45: error: expected id-expression before '(' token
mutexes = shared_array<Mutex>(new Mutex[::CRYPTO_num_locks()]);
网上提示修改为:
#ifdef CRYPTO_num_locks
mutexes = boost::shared_array<Mutex>(new Mutex[CRYPTO_num_locks()]);
#else
mutexes = boost::shared_array<Mutex>(new Mutex[ ::CRYPTO_num_locks()]);
#endif
实际上该问题主要是OpenSSL版本不一致导致的问题
error: '::malloc' has not been declared
error: '::realloc' has not been declared
/usr/include/c++/7.3.0/cstdlib:145:11: error: '::malloc' has not been declared
using ::malloc;
^~~~~~
/usr/include/c++/7.3.0/cstdlib:158:11: error: '::realloc' has not been declared
using ::realloc;
^~~~~~~
In file included from ./src/thrift/TLogging.h:24:0,
from ./src/thrift/Thrift.h:51,
from src/thrift/Thrift.cpp:20:
../../config.h:374:16: error: 'std::rpl_malloc' has not been declared
#define malloc rpl_malloc
^
../../config.h:386:17: error: 'std::rpl_realloc' has not been declared
#define realloc rpl_realloc
^
src/thrift/Thrift.cpp: In static member function 'static std::__cxx11::string apache::thrift::TOutput::strerror_s(int)':
src/thrift/Thrift.cpp:78:22: error: invalid conversion from 'char*' to 'int' [-fpermissive]
int rv = strerror_r(errno_copy, b_errbuf, sizeof(b_errbuf));
遇到这种情况,修改源码最顶层目录下的configure.ac,去掉 AC_FUNC_MALLOC AC_FUNC_REALLOC
yacc Debian 安装
root@cvos:/opt/cmms/3thrdparty# apt-cache policy yacc
yacc:
Installed: (none)
Candidate: (none)
Version table:
root@cvos:/opt/cmms/3thrdparty# yacc --version
Command 'yacc' not found, but can be installed with:
apt install bison # version 2:3.8.2+dfsg-1build1, or
apt install bison++ # version 1.21.11-5
apt install btyacc # version 3.0+dfsg-1
apt install byacc # version 1:2.0.20220114-1
apt install byacc-j # version 1.15-1build3
apt install perl-byacc # version 2.0-8
root@cvos:/opt/cmms/3thrdparty# apt install bison