简介:在 Ubuntu 22.04 环境、gcc 11.4.0 工具链下编译 WonderTrader 的 C++ 开发者,可借助这份预编译的依赖库集合,跳过 Boost 等第三方依赖的下载、版本匹配与 include 路径配置等繁琐过程。压缩包采用 tgz 格式,共 2000 个文件,其中 1856 个 hpp 头文件、144 个 h 头文件,整体仅 14.5MB,属于 header-only 依赖形式,无需额外编译链接;头文件按功能分类,拷贝到工程后即可通过设置依赖环境变量引用。内容覆盖数据模式校验、文档解析、格式化输出与核心容器等通用模块,并提供日志格式定制相关实现,便于在 WonderTrader 的行情、交易、回测模块中直接引用。作者基于 gcc 11.4.0 完成整理,集成时只需设置环境变量 MyDependsGcc 指向解压目录,对应修改 src/CMakeLists.txt 中的依赖路径即可完成接入,避免硬编码目录,方便环境迁移与团队复用。目前已有 236 人学习下载,适合正在搭建 WonderTrader 构建环境、希望减少依赖排错成本的量化开发与回测研究者。
1. 第一次编译WonderTrader,我卡在了依赖库上
先说个现象:很多第一次接触WonderTrader的朋友,在GitHub上看到源码的那一刻,第一反应都是这代码结构也太规整了,编译起来应该分分钟吧。真等到自己拉下代码一编译,才发现最耗时间的根本不是WonderTrader本身,而是它背后那一堆依赖库。WonderTrader作为一个用C++写的开源量化交易开发框架,功能确实完整,从行情接入、策略回测到实盘交易都有对应模块。但C++项目的通病它也一个没落下:第三方依赖多、编译环境敏感、版本稍微对不上就给你甩一脸报错。
我最初折腾WonderTrader,光是把依赖库装到能编译通过,就断断续续花了两天。回头复盘发现,真正花时间的不是库本身的安装,而是各种"我以为没问题"的细节:x64和x86混用了、boost版本和编译器版本不匹配、动态库路径没加进PATH、CMake找不到库目录。这些都是网上资料里一笔带过、但实际操作中必然会踩的地方。
这篇内容就是围绕WonderTrader依赖库的完整配置过程来写。适合两类人看:一是刚把源码拉下来、正准备动手编译的新手,照着做能少走很多弯路;二是已经编译过但被各种link错误、运行时DLL找不到搞到头疼的开发者。我会把依赖清单、版本匹配逻辑、Windows下的具体安装流程,以及我实际遇到过的报错排查过程都摊开来说。
1.1 WonderTrader为什么需要一堆依赖库,而不是尽量零依赖
很多纯C++项目为了降低使用门槛,会刻意减少第三方依赖,能自己写的就自己写。WonderTrader的思路不太一样,它把一些基础能力直接交给社区成熟库来处理,比如智能指针和日期时间处理用boost,数据库访问用mysql的客户端库,序列化相关的自己实现了一部分,也有部分场景会用到常见的基础库。这样做的好处是核心代码能保持精简,不需要从头造轮子;坏处就是编译环境必须把这些库先备齐,而且版本要卡在匹配范围内。
官方文档里有一份HowToBuild,里面写了依赖库的大致清单。实际编译时你会发现,有些库只是编译期需要,有些则必须跟着程序一起发布。搞清楚这两类库的区别,是后面排查运行期问题的基础。
1.2 "依赖库"三个字,坑在哪儿
很多人听到"依赖库",第一反应是"去官网下载个安装包装一下"。但WonderTrader的依赖库完全不同——它需要的是编译好的库文件(.lib和.dll),而不是那种带图形界面、双击Next的安装程序。以boost为例,理论上你当然可以去boost官网下载源码包,然后自己编译。但boost本身就很庞大,手动挑组件编译、配置include路径和lib路径,对不熟悉这套流程的人来说,两个小时可能都搞不定,而且出错了还不知道从哪里查起。
这也是为什么后来社区里大批人转向vcpkg这类C/C++包管理器。它一条命令就能把指定版本、指定平台的库帮你编译好并放到统一目录,省掉手工配置的繁琐步骤。具体怎么操作,我放在第三部分说。
2. 动手前先搞清楚依赖清单与版本匹配关系
2.1 WonderTrader主要依赖哪几类库
根据官方文档的说明,加上我实际编译时观察到的输出,WonderTrader的依赖大致可以分为三类:
- 基础库:最主要的是boost,涉及智能指针、asio、date_time等组件。boost在C++项目里属于"重武器",功能全但体积大,版本跨度大,不同版本之间接口差异明显。
- 数据库客户端:主要是mysql或者mariadb的C客户端库。WonderTrader在存储和读取某些数据时会用到数据库,所以这一项是编译时必须有的。
- 辅助库:包括JSON解析、日志处理之类的库。有些是WonderTrader源码里自带的,有些则是以第三方头文件方式引入的,这部分在编译时大多能自动处理,踩坑概率相对低。
这里我特别要说一句:不要凭感觉去下载最新版本的boost或mysql,而是先看一眼WonderTrader官方文档里推荐的版本区间。C++库的接口变化很频繁,boost的某个内部头文件路径换了、某个函数签名改了,编译报错有时是几百行起步的模板错误,新手根本看不懂。版本对齐是省时间的最大技巧。
2.2 版本匹配,这是整篇最重要的原则
编译WonderTrader时,版本匹配主要体现在三个层面:
第一个层面是编译器版本。VS2022对应的是v143工具集,VS2019是v142。boost在编译生成的库文件名里会带上这个标识,比如libboost_date_time-vc143-mt-x64-1_80.lib,这就表示是用VS2022编译的。如果你的项目用的是VS2019,链接器去找vc142的库,结果目录里只有vc143,会直接报LNK1104。
第二个层面是运行库方式。vcpkg默认的x64-windowstriplet编译出来的是动态链接、动态运行库(/MD),如果你的WonderTrader项目手工把运行库改成了/MT,那么编译时即使能找到库文件,链接时也会出现一堆重复符号或者无法解析的外部符号,这类问题最难排查,因为报错信息不会直接告诉你"你改了运行库"。
第三个层面是平台位数。x64和x86必须统一,装了一堆x86库,编译x64目标时会发现lib文件"无法打开"或者"模块计算机类型与目标计算机类型冲突"。
三个层面的匹配关系,我用一张表总结一下:
| 匹配项 | 推荐配置 | 常见错误表现 |
|---|---|---|
| 编译器工具集 | VS2022(v143) | LNK1104 找不到vc143相关库 |
| 运行库方式 | 动态运行库(/MD) | 无法解析的外部符号、重复定义 |
| 平台位数 | x64 | 模块计算机类型冲突、无法打开lib |
| boost版本 | 按官方文档要求,如1.80左右 | 模板编译报错、找不到头文件 |
| mysql客户端 | 与服务端版本匹配即可 | 编译时报缺少mysql.h |
3. Windows下用vcpkg搭建依赖环境的完整流程
3.1 为什么我推荐vcpkg而不是手动编译
我自己第一遍配置的时候,先尝试的是手动下载boost源码包来编译。结果光是bootstrap就要跑几分钟,编译完整boost更是一个小时起步,中间还因为VS环境变量没加载导致编译中断过一次。后来完全放弃了这条路,转向vcpkg,实际体验下来就是:把时间成本从半天压缩到一顿饭的功夫。
vcpkg是微软生态里的C/C++包管理器,它在Windows下特别好用的一点是,能够根据你指定的triplet自动编译出对应平台和运行库方式的库文件。比如x64-windows就是64位动态库,x64-windows-static是64位静态库。WonderTrader默认情况推荐动态库,省事,发布时带上一堆DLL就行。
3.2 从空目录到依赖就绪,一条命令的距离
vcpkg的安装很简单,找一个磁盘空间充足的目录,克隆vcpkg仓库然后执行bootstrap:
git clone https://github.com/microsoft/vcpkg.git cd vcpkg bootstrap-vcpkg.bat接着安装WonderTrader所需的依赖库。我实际使用时的命令大致如下:
vcpkg install boost --triplet x64-windows vcpkg install libmysql --triplet x64-windows如果你的数据库用的是MariaDB,也可以直接装libmariadb。这里有一个小技巧:如果你不知道WonderTrader到底需要boost的哪些组件,最简单粗暴的方式就是装完整版boot。
vcpkg install boost --triplet x64-windows --recurse--recurse参数的作用是连同依赖子包一起处理,确保boost的date_time、asio这些组件都完整编译出来。第一次装boost的时候,我因为没用这个参数,编译到后面发现缺少某个boost组件,又回头补装,反而耽误了时间。
安装完成后,vcpkg会把生成的库文件放到vcpkg/installed/x64-windows目录下,头文件在include子目录,库文件在lib子目录,DLL在bin子目录。这个目录结构后面配置环境变量时会用到。
3.3 配置WT_HOME并编译WonderTrader源码
依赖库装完后,接下来就是让WonderTrader编译时能找到它们。官方文档里提到可以用WT_HOME环境变量来统一指定依赖库的位置。你不需要把这个变量指向vcpkg的目录,而是建议把vcpkg装好的依赖整理到一个独立的目录里,比如D:\wt-deps,里面建好include、lib、bin三个子目录,然后把vcpkg里对应的内容复制过来。
这样做的目的是让依赖库和vcpkg自身解耦。vcpkg以后要升级、要清理缓存,都不会影响WonderTrader的编译环境。我的实际操作是先复制,再设置环境变量:
setx WT_HOME "D:\wt-deps"然后下载WonderTrader源码,用CMake图形工具打开源码目录,在配置项里填上:
CMAKE_TOOLCHAIN_FILE:指向vcpkg的scripts/buildsystems/vcpkg.cmakeBOOST_ROOT:指向D:\wt-depsMYSQL_DIR:指向mysql客户端库的目录
配置成功后,CMake会生成VS解决方案,直接打开编译即可。如果是命令行编译,也可以用:
cmake --build build --config Release第一次编译时间会比想象中长,主要是boost头文件展开量大,CPU占用率会拉满。这个过程不要中途关,等着就行。
4. 编译期和运行期报错的排查链路:一次真实的Debug记录
4.1 编译时LNK1104:link.exe找不到boost库
我这里整理一次我自己实际排查过的报错链路,作为参考。当时用VS2022打开WonderTrader解决方案后,编译其中一个模块,出现类似下面的错误:
LNK1104: cannot open file 'libboost_date_time-vc143-mt-x64-1_80.lib'这类错误信息很有迷惑性,表面看是"文件不存在",但真正原因不一定是文件没有。我当时的vcpkg依赖目录里确实有boost库,而且文件名就是libboost_date_time-vc143-mt-x64-1_80.lib,那为什么链接器找不到?
逐个排查之后,定位到问题是VC++目录里的库路径配置。CMake生成的解决方案,默认会从BOOST_ROOT环境变量找库目录,但我当时把BOOST_ROOT指向了D:\wt-deps\lib。问题的关键在于,CMake用它自己找到的路径生成了配置,后续我又改了环境变量,导致VS里缓存的路径还是旧的。
4.2 排查的完整过程
我的排查顺序是这样的:
- 在VS的"项目属性 -> VC++目录 -> 库目录"里,看链接器实际搜索了哪些路径。
- 确认
libboost_date_time-vc143-mt-x64-1_80.lib这个文件真实的存放位置。 - 把库目录指向实际路径,重新编译。
- 依然报错,但在错误列表里发现链接参数里多了一段旧路径,排查发现是CMakeCache.txt里缓存了旧配置。
- 删除build目录,重新用CMake配置,问题解决。
这个过程的经验就是:改环境变量之后,一定要清理CMake缓存重新生成,否则它很可能还拿着旧的路径。很多"为什么我改了配置还是报错"的问题,其实都是CMakeCache在作怪。
4.3 编译过了,运行又报错找不到DLL
编译通过只是第一关,运行时错误更让人头疼。我第一次跑起WonderTrader的某个demo时,程序启动直接弹窗提示找不到libboost_date_time-vc143-mt-x64-1_80.dll。
这个就好理解了:boost作为动态库,运行时需要DLL在搜索路径中。我当时的解决方式有两种,都可行:
- 把
D:\wt-deps\bin目录加到系统PATH里。 - 把
D:\wt-deps\bin下的DLL全部复制到exe所在目录。
推荐第二种,因为发布给别人使用时,系统PATH不一定有你的路径,放到exe同目录最保险。但要注意,如果DLL文件很多,复制操作容易漏。
4.4 用工具验证DLL依赖是否完整
还有一种情况是运行时报错找不到libmysql.dll,但明明exe目录里有。这就可能是exe依赖的不是这个DLL,而是另一个版本的libmysql.dll。遇到这种问题,用dumpbin工具可以看exe到底依赖了哪些DLL:
dumpbin /dependents WtBtRunner.exe输出详细列出exe依赖的DLL名称和入口库文件,照着这个清单逐一核对是否存在缺口,比自己瞎猜效率高得多。类似命令还可以用/headers看exe是x64还是x86,排查位数不匹配的问题。
5. 可直接照抄的最终配置清单
5.1 环境变量与目录结构
折腾完一轮之后,我把自己机器上的最终配置固定了下来,后面重新搭建环境时直接照做,基本一遍通过。
D:\wt-deps ├── include # 所有头文件 ├── lib # 所有.lib文件 └── bin # 所有.dll文件环境变量配置:
WT_HOME = D:\wt-deps BOOST_ROOT = D:\wt-deps CMAKE_TOOLCHAIN_FILE = D:\vcpkg\scripts\buildsystems\vcpkg.cmake PATH += D:\wt-deps\bin这个方案的核心思路是:所有依赖库统一放在一个地方,通过三个环境变量指向它,不再让CMake去各个默认路径瞎猜。编译WonderTrader时,只要在CMake里确认这三项配置正确,剩下的都是顺理成章的事。
5.2 自检清单
我在帮朋友排查WonderTrader编译问题时,发现大多数情况都能用下面这张表快速定位:
| 现象 | 检查项 | 解决方式 |
|---|---|---|
| CMake提示找不到Boost | BOOST_ROOT是否指向include上级目录 | 把BOOST_ROOT指到D:\wt-deps |
| 编译报LNK1104 | 链接参数里的lib路径 | 清空build目录重新CMake |
| 运行时报缺少DLL | PATH或exe目录是否有所有DLL | 统一从D:\wt-deps\bin复制 |
| 报错x86与x64不匹配 | 检查triplet和VS平台 | 统一使用x64-windows和x64 |
| 报一堆模板编译错误 | boost版本与编译器不匹配 | 换用官方文档推荐的boost版本 |
5.3 首次跑通建议:尽量别加戏
如果你是在学习阶段,我的建议是先跑通官方自带的最小demo,再用自己的策略或接入文件去改。原因很简单:WonderTrader依赖库配置好之后,编译本身的变量已经够多了,如果再叠加上自己写的代码问题、官方demo里没有的额外依赖,出问题你真的不知道是环境问题还是代码问题。
我遇到过不少人在群里提问,说编译WonderTrader报错,结果发出来的代码是自己改过的模块,里面新增了一个第三方头文件。这种问题已经不属于"依赖库配置"的范畴了,排查起来特别费劲。先把原版编译通过,再逐步往里面加自己的东西,这是最稳的路径。
6. 老手才会注意的几个细节
6.1 用版本记录文件把依赖固定下来
vcpkg的installed/x64-windows目录下有一个vcpkg_installed.txt或者类似版本记录文件,记录了所有已安装库的精确版本号。这个文件建议保留在项目文档里。以后要换机器、换同事、换CI环境,直接按照文件里的版本逐一安装,就不会出现"我本地能编过,别人那边编不过"的尴尬情况。
6.2 不要混用不同triplet编出来的库
vcpkg的triplet一旦换了,比如从x64-windows换成x64-windows-static,整个依赖库都需要重新编译,不能只重编其中一部分。我试过只把boost换成静态库版本,其他库还用动态库,结果链接时报了一批"无法解析的外部符号"。后来统一重建,一次通过。
6.3 数据库连接库的小坑
如果你不是用本机的MySQL服务端,而是连远程数据库,也要确保客户端库版本不能比服务端版本新太多。数据库客户端库的兼容性虽然做得不错,但太老的客户端连太新的服务端偶尔会出现认证协议不支持的报错。建议客户端库与服务端保持同一个大版本,比如都用8.x或者都用10.x系列。
6.4 最后再分享一个小技巧
编译和调试WonderTrader时,我习惯在环境变量里临时把PATH中的vs路径和依赖库路径都显式列出来,用echo %PATH%看一眼顺序。DLL搜索顺序里,exe目录优先于PATH,但PATH里前面的路径优先于后面的。如果你机器上同时装了多个版本的boost(比如Python的某个包也带了boost DLL),很有可能运行时加载了错误的DLL,表现就是莫名崩溃。这时用dumpbin /dependents加where命令定位到底加载了哪个路径下的DLL,比瞎试快得多。
依赖库这东西,第一次配置确实烦,但理解清楚编译器、库版本、路径三者的关系之后,你会发现后面所有类似的项目都一通百通。希望这篇记录能帮你少熬一个夜。
本文还有配套的精品资源,点击获取