1,进入比特币源码目录,先读读编译doc/build-unix.md,查看比特币源码如何编译,了解比特币的依赖库,能大概知道比特币用到哪些,好让心里有个谱!
必须依赖的库:
Library | Purpose | Description
------------|------------------|----------------------
libssl | Crypto | Random Number Generation, Elliptic Curve Cryptography(毕竟是加密货币,猜都猜到用openssl)
libboost | Utility | Library for threading, data structures, etc(武器弹药库)
libevent | Networking | OS independent asynchronous networking(异步网络编程必备,为什么还用这么老的库)
Optional dependencies:
Library | Purpose | Description
------------|------------------|----------------------
miniupnpc | UPnP Support | Firewall-jumping support(用于P2P吗)
libdb4.8 | Berkeley DB | Wallet storage (only needed when wallet enabled)(钱包存储用的berkeley DB)
qt | GUI | GUI toolkit (only needed when GUI enabled)(qt,gui编程的老相好)
protobuf | Payments in GUI | Data interchange format used for payment protocol (only needed when GUI enabled)(用于支付协议,不是json吗,gui内部数据传输格式?)
libqrencode | QR codes in GUI | Optional for generating QR codes (only needed when GUI enabled)(二维码库)
univalue | Utility | JSON parsing and encoding (bundled version will be used unless --with-system-univalue passed to configure)(json解析和编码)
libzmq3 | ZMQ notification | Optional, allows generating ZMQ notifications (requires ZMQ version >= 4.x)(用于通知,哪些消息需要用通知的方式?)
2,分析src/bitcoind.cpp的main函数
int main(int argc, char* argv[])
{
SetupEnvironment();
// Connect bitcoind signal handlers
noui_connect();
return (AppInit(argc, argv) ? EXIT_SUCCESS : EXIT_FAILURE);
}
初始化环境SetupEnvironment函数在src/util.cpp中实现
void SetupEnvironment()
{
#ifdef HAVE_MALLOPT_ARENA_MAX
// glibc-specific: On 32-bit systems set the number of arenas to 1.
// By default, since glibc 2.10, the C library will create up to two heap
// arenas per core. This is known to cause excessive virtual address space
// usage in our usage. Work around it by setting the maximum number of
// arenas to 1.
if (sizeof(void*) == 4) {
mallopt(M_ARENA_MAX, 1);
}
#endif
// On most POSIX systems (e.g. Linux, but not BSD) the environment's locale
// may be invalid, in which case the "C" locale is used as fallback.
#if !defined(WIN32) && !defined(MAC_OSX) && !defined(__FreeBSD__) && !defined(__OpenBSD__)
try {
std::locale(""); // Raises a runtime error if current locale is invalid
} catch (const std::runtime_error&) {
setenv("LC_ALL", "C", 1);
}
#endif
// The path locale is lazy initialized and to avoid deinitialization errors
// in multithreading environments, it is set explicitly by the main thread.
// A dummy locale is used to extract the internal default locale, used by
// fs::path, which is then used to explicitly imbue the path.
std::locale loc = fs::path::imbue(std::locale::classic());
fs::path::imbue(loc);
}
glibc库会为每个核创建2个arena,而这会对32为系统造成虚拟地址空间不足的问题,所以这里设为1。下面locale(即系统区域设置,即国家或地区设置)将决定程序所使用的当前语言编码、日期格式、数字格式及其它与区域有关的设置,设置的正确与否将影响到程序中字符串处理(wchar_t如何输出、strftime()的格式等)。最后两行是文件路径的本地化设置,std::locale::classic() 得到一个表示C locale 的 locale 对象,主要设计宽字符(Wide char)和多字节(Multi bytes)之间的转换问题。
接下来是noui_connect()函数,在src/noui.cpp文件中实现,
void noui_connect()
{
// Connect bitcoind signal handlers
uiInterface.ThreadSafeMessageBox.connect(noui_ThreadSafeMessageBox);
uiInterface.ThreadSafeQuestion.connect(noui_ThreadSafeQuestion);
uiInterface.InitMessage.connect(noui_InitMessage);
}
连接到noui_ThreadSafeMessageBox,noui_ThreadSafeQuestion和noui_InitMessage信号对象,信号触发的时候,这些连接的函数都会被调用.
接下来调用的是AppInit,其中AppInitMain是应用程序主函数,后面再具体展开!