Добавление зависимостей к Bitcoin Core

В настоящее время я редактирую форк Bitcoin Core. У меня есть три библиотеки, которые я хотел бы добавить в качестве зависимостей. Одна из них — мое собственное творение (CPISync), и она зависит от второй библиотеки (NTL), которая, в свою очередь, зависит от третьей (GMP).

Я искал здесь и здесь способы добавления библиотек в Bitcoin Core, но ни один из них не оказался полезным. Как и в первом посте, я все еще каждый раз вижу Undefined reference toошибки (и я пробовал каждую перестановку в Makefile.am, обсуждавшуюся там). Аналогично, я добавил файлы ntl.mk и gmp.mk (и успешно запустил make), как советует второй, но безрезультатно.

Мой вопрос: какова стандартная процедура добавления библиотек в Bitcoin Core? Я имею в виду это как конкретно для моего случая, так и вообще для Bitcoin Core, так как мои многочисленные поиски за последнюю неделю не выявили никакого подобия проторенного пути.

Моя ошибка выглядит так:

libbitcoin_server.a(libbitcoin_server_a-net_processing.o): In function `ProcessMessage(CNode*, std::__cxx11::basic_string, std::allocator > const&, CDataStream&, long, CChainParams const&, CConnman*, std::atomic const&)':
/home/hummus/bitcoin/src/net_processing.cpp:1858: undefined reference to `IBLTSync::IBLTSync(unsigned long, unsigned long)'
/home/hummus/bitcoin/src/net_processing.cpp:1863: undefined reference to `DataObject::DataObject(std::__cxx11::basic_string, std::allocator >)'
/home/hummus/bitcoin/src/net_processing.cpp:1864: undefined reference to `IBLTSync::addElem(DataObject*)'
/home/hummus/bitcoin/src/net_processing.cpp:1875: undefined reference to `CommString::CommString(std::__cxx11::basic_string, std::allocator >, bool)'
/home/hummus/bitcoin/src/net_processing.cpp:1879: undefined reference to `IBLTSync::SyncServer(Communicant*, std::__cxx11::list >&, std::__cxx11::list >&)'
/home/hummus/bitcoin/src/net_processing.cpp:1886: undefined reference to `DataObject::to_string[abi:cxx11]() const'
/home/hummus/bitcoin/src/net_processing.cpp:1875: undefined reference to `CommString::~CommString()'
/home/hummus/bitcoin/src/net_processing.cpp:1858: undefined reference to `IBLTSync::~IBLTSync()'
libbitcoin_server.a(libbitcoin_server_a-net_processing.o): In function `ProcessMessage(CNode*, std::__cxx11::basic_string, std::allocator > const&, CDataStream&, long, CChainParams const&, CConnman*, std::atomic const&)':
/usr/include/c++/7/bits/list.tcc:70: undefined reference to `CommString::~CommString()'
/usr/include/c++/7/bits/list.tcc:70: undefined reference to `IBLTSync::~IBLTSync()'
libbitcoin_server.a(libbitcoin_server_a-net_processing.o): In function `ProcessMessage(CNode*, std::__cxx11::basic_string, std::allocator > const&, CDataStream&, long, CChainParams const&, CConnman*, std::atomic const&)':
/home/hummus/bitcoin/src/net_processing.cpp:1858: undefined reference to `IBLTSync::~IBLTSync()'
/home/hummus/bitcoin/src/net_processing.cpp:1875: undefined reference to `CommString::~CommString()'
libntl.a(lip.o): In function `redc(_ntl_gbigint_body*, _ntl_gbigint_body*, long, unsigned long, _ntl_gbigint_body*)':
(.text+0x2a3): undefined reference to `__gmpn_addmul_1'
(.text+0x368): undefined reference to `__gmpn_sub_n'
libntl.a(lip.o): In function `_ntl_rem_struct_basic::eval(long*, _ntl_gbigint_body*, _ntl_tmp_vec*)':
(.text+0x46b): undefined reference to `__gmpn_mod_1'
libntl.a(lip.o): In function `_ntl_reduce_struct_montgomery::eval(_ntl_gbigint_body**, _ntl_gbigint_body**)':
(.text+0xfcb): undefined reference to `__gmpn_addmul_1'
(.text+0x1096): undefined reference to `__gmpn_sub_n'
libntl.a(lip.o): In function `_ntl_crt_struct_basic::eval(_ntl_gbigint_body**, long const*, _ntl_tmp_vec*)':
(.text+0x11df): undefined reference to `__gmpn_addmul_1'
libntl.a(lip.o): In function `gmod_simple(_ntl_gbigint_body*, _ntl_gbigint_body*, _ntl_gbigint_body**)':
(.text+0x1c56): undefined reference to `__gmpn_tdiv_qr'
libntl.a(lip.o): In function `_ntl_rem_struct_fast::eval(long*, _ntl_gbigint_body*, _ntl_tmp_vec*)':
(.text+0x1f5d): undefined reference to `__gmpn_mod_1'
libntl.a(lip.o): In function `_ntl_rem_struct_medium::eval(long*, _ntl_gbigint_body*, _ntl_tmp_vec*)':
(.text+0x21bd): undefined reference to `__gmpn_mod_1'
libntl.a(lip.o): In function `_ntl_grshift(_ntl_gbigint_body*, long, _ntl_gbigint_body**)':
(.text+0x31e1): undefined reference to `__gmpn_rshift'
libntl.a(lip.o): In function `_ntl_glshift(_ntl_gbigint_body*, long, _ntl_gbigint_body**)':
(.text+0x34a1): undefined reference to `__gmpn_lshift'
libntl.a(lip.o): In function `_ntl_gadd(_ntl_gbigint_body*, _ntl_gbigint_body*, _ntl_gbigint_body**)':
(.text+0x3a12): undefined reference to `__gmpn_add_n'
(.text+0x3ab7): undefined reference to `__gmpn_sub_n'
(.text+0x3bda): undefined reference to `__gmpn_sub_n'
(.text+0x3c47): undefined reference to `__gmpn_sub_n'
libntl.a(lip.o): In function `_ntl_gsub(_ntl_gbigint_body*, _ntl_gbigint_body*, _ntl_gbigint_body**)':
(.text+0x3f13): undefined reference to `__gmpn_add_n'
(.text+0x40f7): undefined reference to `__gmpn_sub_n'
(.text+0x41da): undefined reference to `__gmpn_sub_n'
(.text+0x4247): undefined reference to `__gmpn_sub_n'
libntl.a(lip.o): In function `_ntl_gsubpos(_ntl_gbigint_body*, _ntl_gbigint_body*, _ntl_gbigint_body**)':
(.text+0x439c): undefined reference to `__gmpn_sub_n'
libntl.a(lip.o): In function `_ntl_gmul(_ntl_gbigint_body*, _ntl_gbigint_body*, _ntl_gbigint_body**)':
(.text+0x46ba): undefined reference to `__gmpn_mul'
(.text+0x475d): undefined reference to `__gmpn_mul'
libntl.a(lip.o): In function `_ntl_gsmul(_ntl_gbigint_body*, long, _ntl_gbigint_body**)':
(.text+0x48ba): undefined reference to `__gmpn_mul_1'
(.text+0x48f4): undefined reference to `__gmpn_lshift'
libntl.a(lip.o): In function `_ntl_gsdiv(_ntl_gbigint_body*, long, _ntl_gbigint_body**)':
(.text+0x49fd): undefined reference to `__gmpn_divrem_1'
(.text+0x4ab5): undefined reference to `__gmpn_rshift'
libntl.a(lip.o): In function `_ntl_gsmod(_ntl_gbigint_body*, long)':
(.text+0x4ba6): undefined reference to `__gmpn_mod_1'
libntl.a(lip.o): In function `_ntl_gdiv(_ntl_gbigint_body*, _ntl_gbigint_body*, _ntl_gbigint_body**, _ntl_gbigint_body**)':
(.text+0x5052): undefined reference to `__gmpn_tdiv_qr'
libntl.a(lip.o): In function `_ntl_crt_struct_fast::eval(_ntl_gbigint_body**, long const*, _ntl_tmp_vec*)':
(.text+0x55c7): undefined reference to `__gmpn_addmul_1'
libntl.a(lip.o): In function `_ntl_gsqrts(long)':
(.text+0x5856): undefined reference to `__gmpn_sqrtrem'
libntl.a(lip.o): In function `_ntl_gsqrt(_ntl_gbigint_body*, _ntl_gbigint_body**)':
(.text+0x5928): undefined reference to `__gmpn_sqrtrem'
libntl.a(lip.o): In function `_ntl_ggcd(_ntl_gbigint_body*, _ntl_gbigint_body*, _ntl_gbigint_body**)':
(.text+0x5e00): undefined reference to `__gmpn_gcd'
(.text+0x5ec2): undefined reference to `__gmpn_gcd'
libntl.a(lip.o): In function `_ntl_gexteucl(_ntl_gbigint_body*, _ntl_gbigint_body**, _ntl_gbigint_body*, _ntl_gbigint_body**, _ntl_gbigint_body**)':
(.text+0x622a): undefined reference to `__gmpn_gcdext'
libntl.a(lip.o): In function `_ntl_ginv(_ntl_gbigint_body*, _ntl_gbigint_body*, _ntl_gbigint_body**)':
(.text+0x6b64): undefined reference to `__gmpn_gcdext'
libntl.a(lip.o): In function `_ntl_gaorsmul_1(_ntl_gbigint_body*, long, long, _ntl_gbigint_body**)':
(.text+0xa181): undefined reference to `__gmpn_submul_1'
(.text+0xa2fe): undefined reference to `__gmpn_addmul_1'
(.text+0xa43f): undefined reference to `__gmpn_mul_1'
(.text+0xa599): undefined reference to `__gmpn_mul_1'
libntl.a(lip.o): In function `_ntl_quick_accum_muladd(_ntl_gbigint_body*, _ntl_gbigint_body*, long)':
(.text+0xc02b): undefined reference to `__gmpn_addmul_1'
collect2: error: ld returned 1 exit status
Makefile:3643: recipe for target 'bitcoind' failed
make[2]: \*** [bitcoind] Error 1
make[2]: Leaving directory '/home/hummus/bitcoin/src'
Makefile:9297: recipe for target 'all-recursive' failed
make[1]: \*** [all-recursive] Error 1
make[1]: Leaving directory '/home/hummus/bitcoin/src'
Makefile:746: recipe for target 'all-recursive' failed
make: *** [all-recursive] Error 1
Правильно ли вы включили заголовочные файлы (т.е. #include something.h) в свой код?
Если это библиотеки (статические или динамические), то вам также необходимо добавить файлы .a или .so в скрипт компоновщика в make-файлах.
@AndrewChow Думаю, да.
@JBaczuk Я тоже так сделал. LIBCPISYNC=CPISync.a, и т.д. Я добавлял эти библиотеки в разные части Makefile.am и каждый раз выходил сухим.
Можете ли вы опубликовать свой Makefile.am? В make-файлах есть кое-какой порядок вещей, из-за которого добавление библиотек раздражает. Как правило, порядок будет отличаться в зависимости от того, где используются добавляемые вами библиотеки.
@AndrewChow Вот мой текущий Makefile (хотя он немного изменился во время моих невзгод): drive.google.com/open?id=1DkRssXfPM0eNqvYVa3B4oiMNKF7dY1_N
Где находятся файлы libcpisynclib.a, libntl.aи ibgmp.a? Они не компилируются Makefile. Если вы ожидаете, что они будут скомпилированы make-файлом, вам нужно добавить цели для этих библиотек. Чтобы узнать, как это сделать, посмотрите, как это делается для LIBSECP256K1. В противном случае, если вы сами скомпилировали эти библиотеки, они должны быть в формате src/.
@AndrewChow Увы, это я тоже уже пробовал. Все три (скомпилированных) файла уже находятся в src/. Но даже это казалось странным: почему я должен перемещать файлы *.a из usr/libв src? Разве Bitcoin Core не может найти их в обычном месте?
Вы пробовали не добавлять исходный код вашей библиотеки в компиляцию? т.е. просто используйте библиотеку, когда она связана, вместо того, чтобы компилировать ее в биткойн. Кажется, это вызовет проблемы.
Можете ли вы опубликовать исходный код, чтобы я мог попытаться его скомпилировать? Make — это одна из тех вещей, которые обычно нужно делать в каждом конкретном случае, и на самом деле нет общего ответа, который можно было бы дать без создания самого кода.
@AndrewChow Я делаю это и в текущем Makefile. Если вы хотите попробовать запустить его самостоятельно (что было бы очень мило), вы можете найти код здесь .
Я вижу, вы пытаетесь связать cpisync с биткойнами, вас может заинтересовать Minisketch ( github.com/sipa/minisketch ), который не зависит от зависимостей, имеет совместимую лицензию и намного быстрее.

Ответы (1)

Мне удалось получить код для компиляции со следующим diff:

diff --git a/src/Makefile.am b/src/Makefile.am
index 6bb19d9bf..aab8ab458 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -33,9 +33,8 @@ LIBBITCOIN_CRYPTO=crypto/libbitcoin_crypto.a
 LIBBITCOINQT=qt/libbitcoinqt.a
 LIBSECP256K1=secp256k1/libsecp256k1.la
 #My personal libaries
-LIBCPISYNCLIB=libcpisynclib.a
-LIBNTL=libntl.a
-LIBGMP=libgmp.a
+LIBNTL=-lntl
+LIBGMP=-lgmp


 if ENABLE_ZMQ
@@ -442,7 +441,7 @@ bitcoind_LDADD = \
   $(LIBMEMENV) \
   $(LIBSECP256K1)

-bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(LIBCPISYNCLIB) $(LIBNTL) $(LIBGMP)
+bitcoind_LDADD += $(BOOST_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(ZMQ_LIBS) $(LIBNTL) $(LIBGMP)

 # bitcoin-cli binary #
 bitcoin_cli_SOURCES = bitcoin-cli.cpp
@@ -460,7 +459,7 @@ bitcoin_cli_LDADD = \
   $(LIBBITCOIN_UTIL) \
   $(LIBBITCOIN_CRYPTO)

-bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) $(LIBCPISYNCLIB) $(LIBNTL) $(LIBGMP)
+bitcoin_cli_LDADD += $(BOOST_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(EVENT_LIBS) $(LIBNTL) $(LIBGMP)
 #

 # bitcoin-tx binary #
@@ -481,7 +480,7 @@ bitcoin_tx_LDADD = \
   $(LIBBITCOIN_CRYPTO) \
   $(LIBSECP256K1)

-bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) $(LIBCPISYNCLIB) $(LIBNTL) $(LIBGMP)
+bitcoin_tx_LDADD += $(BOOST_LIBS) $(CRYPTO_LIBS) $(LIBNTL) $(LIBGMP)
 #

 # bitcoinconsensus library #
diff --git a/src/Makefile.bench.include b/src/Makefile.bench.include
index 2b1f70b25..796348338 100644
--- a/src/Makefile.bench.include
+++ b/src/Makefile.bench.include
@@ -45,7 +45,7 @@ bench_bench_bitcoin_LDADD = \
   $(LIBUNIVALUE)

 if ENABLE_ZMQ
-bench_bench_bitcoin_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
+bench_bench_bitcoin_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS) $(LIBNTL) $(LIBGMP)
 endif

 if ENABLE_WALLET
diff --git a/src/Makefile.qt.include b/src/Makefile.qt.include
index 7b44ce038..59e250539 100644
--- a/src/Makefile.qt.include
+++ b/src/Makefile.qt.include
@@ -424,7 +424,7 @@ qt_bitcoin_qt_LDADD += $(LIBBITCOIN_ZMQ) $(ZMQ_LIBS)
 endif
 qt_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) \
   $(BOOST_LIBS) $(QT_LIBS) $(QT_DBUS_LIBS) $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
-  $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
+  $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBNTL) $(LIBGMP)
 qt_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 qt_bitcoin_qt_LIBTOOLFLAGS = --tag CXX

diff --git a/src/Makefile.qttest.include b/src/Makefile.qttest.include
index ea2ed1747..a322fbf39 100644
--- a/src/Makefile.qttest.include
+++ b/src/Makefile.qttest.include
@@ -60,7 +60,7 @@ endif
 qt_test_test_bitcoin_qt_LDADD += $(LIBBITCOIN_CLI) $(LIBBITCOIN_COMMON) $(LIBBITCOIN_UTIL) $(LIBBITCOIN_CONSENSUS) $(LIBBITCOIN_CRYPTO) $(LIBUNIVALUE) $(LIBLEVELDB) \
   $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(QT_DBUS_LIBS) $(QT_TEST_LIBS) $(QT_LIBS) \
   $(QR_LIBS) $(PROTOBUF_LIBS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBSECP256K1) \
-  $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS)
+  $(EVENT_PTHREADS_LIBS) $(EVENT_LIBS) $(LIBNTL) $(LIBGMP)
 qt_test_test_bitcoin_qt_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(QT_LDFLAGS) $(LIBTOOL_APP_LDFLAGS)
 qt_test_test_bitcoin_qt_CXXFLAGS = $(AM_CXXFLAGS) $(QT_PIE_FLAGS)

diff --git a/src/Makefile.test.include b/src/Makefile.test.include
index b48bfc76b..0ac10dece 100644
--- a/src/Makefile.test.include
+++ b/src/Makefile.test.include
@@ -103,7 +103,7 @@ test_test_bitcoin_LDADD += $(LIBBITCOIN_SERVER) $(LIBBITCOIN_CLI) $(LIBBITCOIN_C
   $(LIBLEVELDB) $(LIBLEVELDB_SSE42) $(LIBMEMENV) $(BOOST_LIBS) $(BOOST_UNIT_TEST_FRAMEWORK_LIB) $(LIBSECP256K1) $(EVENT_LIBS) $(EVENT_PTHREADS_LIBS)
 test_test_bitcoin_CXXFLAGS = $(AM_CXXFLAGS) $(PIE_FLAGS)

-test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS)
+test_test_bitcoin_LDADD += $(LIBBITCOIN_CONSENSUS) $(BDB_LIBS) $(SSL_LIBS) $(CRYPTO_LIBS) $(MINIUPNPC_LIBS) $(LIBNTL) $(LIBGMP)
 test_test_bitcoin_LDFLAGS = $(RELDFLAGS) $(AM_LDFLAGS) $(LIBTOOL_APP_LDFLAGS) -static

 if ENABLE_ZMQ

Здесь следует отметить несколько важных вещей. Во-первых, я удалил LIBCPISYNCLIB. В этом нет необходимости, поскольку исходный код библиотеки уже компилируется в двоичный файл.

Во-вторых, я поменял LIBNTLи LIBGMPна -lntlи -lgmpсоответственно. Это говорит компоновщику искать библиотеки, установленные системой, а не определенные .aфайлы в исходном коде.

Наконец, $(LIBNTL) $(LIBGMP)были добавлены другие Makefile.am.*.includeфайлы. Эти библиотеки должны быть добавлены везде, где libbitcoin_serverони используются, так как существует больше, чем просто bitcoindсозданные двоичные файлы bitcoin-cli, и bitcoin-tx. Есть бинарники для тестов, бенчмарков, биткойн-qt и тесты биткойн-qt.

Хм... Этот код выглядит логично, но когда я изменил файлы, как вы указали, я получил ту же ошибку, что и раньше (хотя теперь неопределенные ссылки относятся к NTL). На всякий случай я загрузил свой исходный код во второй раз и столкнулся с той же проблемой. Любые другие предложения?
Вам необходимо установить NTL в вашу систему. Я предлагаю перекомпилировать его, а затем сделатьsudo make install