前言

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版本不一致导致的问题

[THRIFT-3878] Compile error in TSSLSocket.cpp with new OpenSSL [CRYPTO_num_locks] - ASF JIRA (apache.org)

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