使用 OpenSSL 编译时的 qtum-core 构建问题

qtum-core build issue when compiling with OpenSSL

我在尝试构建 qtum-core 时遇到错误。错误是:

make
...

  CXX      libbitcoin_common_a-key.o
key.cpp: In function ‘bool EnsureLowS(std::vector<unsigned char>&)’:
key.cpp:149:19: error: invalid use of incomplete type ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
     if (BN_cmp(sig->s, halforder) > 0) {
                   ^
In file included from /usr/include/openssl/ecdsa.h:10:0,
                 from key.cpp:17:
/usr/include/openssl/ec.h:1039:16: error: forward declaration of ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
 typedef struct ECDSA_SIG_st ECDSA_SIG;
                ^
key.cpp:151:19: error: invalid use of incomplete type ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
         BN_sub(sig->s, order, sig->s);
                   ^
In file included from /usr/include/openssl/ecdsa.h:10:0,
                 from key.cpp:17:
/usr/include/openssl/ec.h:1039:16: error: forward declaration of ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
 typedef struct ECDSA_SIG_st ECDSA_SIG;
                ^
key.cpp:151:34: error: invalid use of incomplete type ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
         BN_sub(sig->s, order, sig->s);
                                  ^
In file included from /usr/include/openssl/ecdsa.h:10:0,
                 from key.cpp:17:
/usr/include/openssl/ec.h:1039:16: error: forward declaration of ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
 typedef struct ECDSA_SIG_st ECDSA_SIG;
                ^
make[2]: *** [libbitcoin_common_a-key.o] Error 1
make[2]: Leaving directory `/home/qtum_data/qtum/src'
make[1]: *** [all-recursive] Error 1
make[1]: Leaving directory `/home/qtum_data/qtum/src'
make: *** [all-recursive] Error 1

这是什么问题,我该如何解决?


  1. git clone --recursive https://github.com/qtumproject/qtum.git
  2. cd qtum
  3. 运行 autogen

    ./autogen.sh
    libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, `build-aux'.
    libtoolize: copying file `build-aux/ltmain.sh'
    libtoolize: putting macros in AC_CONFIG_MACRO_DIR, `build-aux/m4'.
    libtoolize: copying file `build-aux/m4/libtool.m4'
    libtoolize: copying file `build-aux/m4/ltoptions.m4'
    libtoolize: copying file `build-aux/m4/ltsugar.m4'
    libtoolize: copying file `build-aux/m4/ltversion.m4'
    ...
    configure.ac:32: installing 'build-aux/missing'
    Makefile.am:12: warning: user variable 'GZIP_ENV' defined here ...
    /usr/share/automake-1.14/am/distdir.am: ... overrides Automake variable 'GZIP_ENV' defined here
    src/Makefile.am: installing 'build-aux/depcomp'
    src/Makefile.am:703: warning: user target '.mm.o' defined here ...
    /usr/share/automake-1.14/am/depend2.am: ... overrides Automake target '.mm.o' defined here
    parallel-tests: installing 'build-aux/test-driver'
    
  4. 配置

    ./configure --without-gui
    checking build system type... x86_64-unknown-linux-gnu
    checking host system type... x86_64-unknown-linux-gnu
    checking for a BSD-compatible install... /usr/bin/install -c
    checking whether build environment is sane... yes
    checking for a thread-safe mkdir -p... /bin/mkdir -p
    checking for gawk... no
    checking for mawk... mawk
    checking whether make sets $(MAKE)... yes
    checking whether make supports nested variables... yes
    checking whether to enable maintainer-specific portions of Makefiles... yes
    checking whether make supports nested variables... (cached) yes
    checking for g++... g++
    ...
    
    configure: Using jni: no
    configure: ******
    configure: WARNING: experimental build
    configure: Experimental features do not have stable APIs or properties, and may not be safe for production use.
    configure: Building ECDH module: yes
    configure: ******
    checking that generated files are newer than configure... done
    configure: creating ./config.status
    config.status: creating Makefile
    config.status: creating libsecp256k1.pc
    config.status: creating src/libsecp256k1-config.h
    config.status: executing depfiles commands
    config.status: executing libtool commands
    Fixing libtool for -rpath problems.
    
    Options used to compile and link:
      with wallet   = yes
      with gui / qt = no
      with zmq      = no
      with test     = yes
      with bench    = yes
      with upnp     = auto
      debug enabled = no
      werror        = no
    
      target os     = linux
      build os      =
    
      CC            = gcc
      CFLAGS        = -g -O2
      CPPFLAGS      =  -DQTUM_BUILD -DHAVE_BUILD_INFO -D__STDC_FORMAT_MACROS
      CXX           = g++ -std=c++11
      CXXFLAGS      = -g -O2 -Wall -Wextra -Wformat -Wvla -Wformat-security -Wno-unused-parameter -Wno-unknown-pragmas
      LDFLAGS       =
    
  5. 制作

    make    
    Making all in src
    make[1]: Entering directory `/home/qtum_data/qtum/src'
    make[2]: Entering directory `/home/qtum_data/qtum/src'
      CXX      crypto/libbitcoinconsensus_la-aes.lo
      CXX      crypto/libbitcoinconsensus_la-chacha20.lo
      CXX      crypto/libbitcoinconsensus_la-hmac_sha256.lo
      CXX      crypto/libbitcoinconsensus_la-hmac_sha512.lo
      CXX      crypto/libbitcoinconsensus_la-ripemd160.lo
      CXX      crypto/libbitcoinconsensus_la-sha1.lo
      CXX      crypto/libbitcoinconsensus_la-sha256.lo
      CXX      crypto/libbitcoinconsensus_la-sha512.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-b64.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-crypto-mcf.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-crypto_scrypt-check.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-crypto_scrypt-hash.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-crypto_scrypt-hexconvert.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-crypto_scrypt-nosse.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-crypto-scrypt-saltgen.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-sha256.lo
      CC       cpp-ethereum/utils/libscrypt/libbitcoinconsensus_la-slowequals.lo
      CXX      libbitcoinconsensus_la-arith_uint256.lo
      CXX      consensus/libbitcoinconsensus_la-merkle.lo
      CXX      libbitcoinconsensus_la-hash.lo
      CXX      primitives/libbitcoinconsensus_la-block.lo
      CXX      primitives/libbitcoinconsensus_la-transaction.lo
      CXX      libbitcoinconsensus_la-pubkey.lo
      CXX      script/libbitcoinconsensus_la-bitcoinconsensus.lo
      CXX      script/libbitcoinconsensus_la-interpreter.lo
      CXX      script/libbitcoinconsensus_la-script.lo
      CXX      script/libbitcoinconsensus_la-script_error.lo
      CXX      libbitcoinconsensus_la-uint256.lo
      CXX      libbitcoinconsensus_la-utilstrencodings.lo
    make[3]: Entering directory `/home/qtum_data/qtum/src/secp256k1'
    gcc -I. -g -O2 -Wall -Wextra -Wno-unused-function -c src/gen_context.c -o gen_context.o
    gcc gen_context.o -o gen_context
    ./gen_context
      CC       src/libsecp256k1_la-secp256k1.lo
      CCLD     libsecp256k1.la
    make[3]: Leaving directory `/home/qtum_data/qtum/src/secp256k1'
      CXXLD    libbitcoinconsensus.la
    copying selected object files to avoid basename conflicts...
      CXX      qtumd-bitcoind.o
      CXX      libbitcoin_server_a-addrman.o
      CXX      libbitcoin_server_a-addrdb.o
      CXX      libbitcoin_server_a-bloom.o
      CXX      libbitcoin_server_a-blockencodings.o
      CXX      libbitcoin_server_a-chain.o
      CXX      libbitcoin_server_a-checkpoints.o
      CXX      libbitcoin_server_a-httprpc.o
      CXX      libbitcoin_server_a-httpserver.o
      CXX      libbitcoin_server_a-init.o
      CXX      libbitcoin_server_a-dbwrapper.o
      CXX      libbitcoin_server_a-merkleblock.o
      CXX      libbitcoin_server_a-miner.o
      CXX      libbitcoin_server_a-net.o
      CXX      libbitcoin_server_a-net_processing.o
      CXX      libbitcoin_server_a-noui.o
      CXX      policy/libbitcoin_server_a-fees.o
      CXX      policy/libbitcoin_server_a-policy.o
      CXX      libbitcoin_server_a-pow.o
      CXX      libbitcoin_server_a-pos.o
      CXX      libbitcoin_server_a-rest.o
      CXX      rpc/libbitcoin_server_a-blockchain.o
      CXX      rpc/libbitcoin_server_a-mining.o
      CXX      rpc/libbitcoin_server_a-misc.o
      CXX      rpc/libbitcoin_server_a-net.o
      CXX      rpc/libbitcoin_server_a-rawtransaction.o
      CXX      rpc/libbitcoin_server_a-server.o
      CXX      script/libbitcoin_server_a-sigcache.o
      CXX      script/libbitcoin_server_a-ismine.o
      CXX      libbitcoin_server_a-timedata.o
      CXX      libbitcoin_server_a-torcontrol.o
      CXX      libbitcoin_server_a-txdb.o
      CXX      libbitcoin_server_a-txmempool.o
      CXX      libbitcoin_server_a-ui_interface.o
      CXX      libbitcoin_server_a-validation.o
      CXX      libbitcoin_server_a-validationinterface.o
      CXX      libbitcoin_server_a-versionbits.o
      CXX      qtum/libbitcoin_server_a-qtumstate.o
      CXX      qtum/libbitcoin_server_a-qtumtransaction.o
      CXX      qtum/libbitcoin_server_a-qtumDGP.o
      CXX      consensus/libbitcoin_server_a-consensus.o
      CXX      qtum/libbitcoin_server_a-storageresults.o
      AR       libbitcoin_server.a
      CXX      libbitcoin_common_a-amount.o
      CXX      libbitcoin_common_a-base58.o
      CXX      libbitcoin_common_a-chainparams.o
      CXX      libbitcoin_common_a-coins.o
      CXX      libbitcoin_common_a-compressor.o
      CXX      libbitcoin_common_a-core_read.o
      CXX      libbitcoin_common_a-core_write.o
      CXX      libbitcoin_common_a-key.o
    key.cpp: In function ‘bool EnsureLowS(std::vector<unsigned char>&)’:
    key.cpp:149:19: error: invalid use of incomplete type ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
         if (BN_cmp(sig->s, halforder) > 0) {
                       ^
    In file included from /usr/include/openssl/ecdsa.h:10:0,
                     from key.cpp:17:
    /usr/include/openssl/ec.h:1039:16: error: forward declaration of ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
     typedef struct ECDSA_SIG_st ECDSA_SIG;
                    ^
    key.cpp:151:19: error: invalid use of incomplete type ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
             BN_sub(sig->s, order, sig->s);
                       ^
    In file included from /usr/include/openssl/ecdsa.h:10:0,
                     from key.cpp:17:
    /usr/include/openssl/ec.h:1039:16: error: forward declaration of ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
     typedef struct ECDSA_SIG_st ECDSA_SIG;
                    ^
    key.cpp:151:34: error: invalid use of incomplete type ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
             BN_sub(sig->s, order, sig->s);
                                      ^
    In file included from /usr/include/openssl/ecdsa.h:10:0,
                     from key.cpp:17:
    /usr/include/openssl/ec.h:1039:16: error: forward declaration of ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
     typedef struct ECDSA_SIG_st ECDSA_SIG;
                    ^
    make[2]: *** [libbitcoin_common_a-key.o] Error 1
    make[2]: Leaving directory `/home/qtum_data/qtum/src'
    make[1]: *** [all-recursive] Error 1
    make[1]: Leaving directory `/home/qtum_data/qtum/src'
    make: *** [all-recursive] Error 1
    
  6. 我的服务器环境

    OS - Linux xxxxxxx-X10SLL-F 4.4.0-31-generic #50~14.04.1-Ubuntu SMP 7 月 13 日星期三 01:07:32 UTC 2016 x86_64 x86_64 x86_64 GNU/Linux openssl 版本 - OpenSSL 1.0.2g

  7. 如何解决这个问题?

  CXX      libbitcoin_common_a-key.o
key.cpp: In function ‘bool EnsureLowS(std::vector<unsigned char>&)’:
key.cpp:149:19: error: invalid use of incomplete type ‘ECDSA_SIG {aka struct ECDSA_SIG_st}’
     if (BN_cmp(sig->s, halforder) > 0) {
                   ^

看起来您的机器本地有 OpenSSL 1.1.0,但是 qtum-core 是为 OpenSSL 1.0.2 编写的。那是因为 incomplete type ECDSA_SIG 错误。 OpenSSL 1.1.0 使 OpenSSL 1.1.0 中的一些东西变得私有,这些东西曾经是 public 并且在 OpenSSL 1.0.2 中可以访问。

你可以做两件事。首先,降级到 OpenSSL 1.0.2,以便 qtum-core 可以再次访问数据成员。

其次,您可以将 qtum-core 升级到支持 OpenSSL 1.1.0 的版本。如果 qtum-core 不支持 OpenSSL 1.1.0,请提交错误报告让作者了解该问题。

您问的问题可能是Qtum Issue 382。如果是这样,那么您唯一的选择似乎是选项 (1),降级到 OpenSSL 1.0.2。


这里是如何配置不同的 OpenSSL(即,不同于发行版的)。

$ git clone https://github.com/qtumproject/qtum.git
$ cd qtum/
$ autoreconf -f -i
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.
libtoolize: copying file 'build-aux/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'build-aux/m4'.
libtoolize: copying file 'build-aux/m4/libtool.m4'
libtoolize: copying file 'build-aux/m4/ltoptions.m4'
libtoolize: copying file 'build-aux/m4/ltsugar.m4'
libtoolize: copying file 'build-aux/m4/ltversion.m4'
libtoolize: copying file 'build-aux/m4/lt~obsolete.m4'
...

这是重要的部分,在 运行ning make 之前:

$ ./configure --help | grep -i -E 'ssl|crypto'
  SSL_CFLAGS  C compiler flags for SSL, overriding pkg-config
  SSL_LIBS    linker flags for SSL, overriding pkg-config
  CRYPTO_CFLAGS
              C compiler flags for CRYPTO, overriding pkg-config
  CRYPTO_LIBS linker flags for CRYPTO, overriding pkg-config

没有 --with-XXX 控制 OpenSSL 的选项,但可以通过 pkg-config 选择。所以...

我在 /usr/local 中安装升级。 Headers 在 /usr/local/include 中,库在 /usr/local/lib64 中(因为它是 Fedora)。 OpenSSL本地版本为1.0.2:

$ cat /usr/local/lib64/pkgconfig/libssl.pc
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib64
includedir=${prefix}/include

Name: OpenSSL-libssl
Description: Secure Sockets Layer and cryptography libraries
Version: 1.0.2n
Requires.private: libcrypto
Libs: -L${libdir} -lssl
Libs.private: -Wl,-R,/usr/local/lib64 -Wl,--enable-new-dtags -ldl
Cflags: -I${includedir}

$ cat /usr/local/lib64/pkgconfig/libcrypto.pc
prefix=/usr/local
exec_prefix=${prefix}
libdir=${exec_prefix}/lib64
includedir=${prefix}/include
enginesdir=${libdir}/engines

Name: OpenSSL-libcrypto
Description: OpenSSL cryptography library
Version: 1.0.2n
Requires:
Libs: -L${libdir} -lcrypto
Libs.private: -Wl,-R,/usr/local/lib64 -Wl,--enable-new-dtags -ldl
Cflags: -I${includedir}

我准备好建造了。下一步是(--disable-wallet 因为我不想修复 Autools 错误):

$ PKG_CONFIG_PATH=/usr/local/lib64/pkgconfig/ ./configure --disable-wallet
configure: loading site script /usr/local/share/config.site
checking build system type... x86_64-pc-linux-gnu
checking host system type... x86_64-pc-linux-gnu
checking for a BSD-compatible install... /usr/local/bin/install -c
checking whether build environment is sane... yes
checking for a thread-safe mkdir -p... /usr/local/bin/mkdir -p
checking for gawk... gawk
...
checking for dynamic linked boost test... yes
checking for mismatched boost c++11 scoped enums... ok
checking for SSL... yes
checking for CRYPTO... yes
...

相关的,我在Noloader | Build-Scripts有一些安装OpenSSL和一些其他程序的脚本。克隆 repo,然后 运行:

./build-cacerts.sh  # install CA's needed for Wget downloads
./build-openssl.sh  # download, build and install OpenSSL in /usr/local

我将构建脚本用于下层客户端,例如 Fedora 7 和 Solaris 10。您不必使用构建脚本。但是您确实需要在本地安装 OpenSSL 1.0.2 的副本。