在 Windows 上用 Visual Studio 编译 c-toxcore 这件事,我第一次搞的时候连踩了三天坑,最后发现大部分问题不是代码的问题,而是工具链配合的问题。c-toxcore 是 Tox 协议的官方 C 实现库,负责端到端加密通信里的 DHT 网络、UDP/TCP 传输、会话加密这些底层能力,客户端 UI 是不带的。编译完成后你拿到的是 toxcore(核心)和 toxav(可选音视频)两组库,可以直接链接进自己的聊天客户端、加密消息中继测试程序或者协议学习原型里。这篇教程按我实际跑通的顺序来写:环境准备、依赖管理、CMake 配置、高频踩坑点、产物验证和工程接入,适合已经在 Windows 上写过 C/C++、但第一次碰 CMake + vcpkg 这套流程的同学。
1. 编译前先搞清楚:你要的是哪套产物
1.1 toxcore 与 toxav 的边界
c-toxcore 的源码仓库编译后主要出两大块。toxcore是核心库,负责 Tox 协议绝大部分逻辑:加密会话建立、好友关系管理、消息收发,以及文件传输的底层传输部分。toxav是音视频扩展,构建在核心库之上,处理音频(Opus 编解码)和视频(VP8 编解码)流。
如果你的客户端只需要文本消息,完全可以关掉toxav。这一下能省掉两个第三方依赖:opus 和 libvpx,连带着 NASM 也不用装了。很多人在 Windows 上编译失败,都是因为“全都要”的心态,实际上对纯协议应用来说,AV 那部分根本用不上。
1.2 三个 CMake 开关决定产物形态
编译前要在脑子里过一遍这几个开关,它们直接决定你后面要装多少依赖:
| CMake 选项 | 默认值 | 作用 |
|---|---|---|
ENABLE_AV | ON | 编译 toxav 音视频扩展;设为 OFF 就不需要 opus、libvpx 和 NASM |
ENABLE_SHARED | ON | 生成动态库toxcore.dll以及对应的导入库(import lib) |
ENABLE_STATIC | ON | 生成静态链接用的.lib |
CMAKE_INSTALL_PREFIX | 系统默认 | 指定最终include、lib、bin的安装位置 |
我建议第一次编译时明确选一条路线:全功能就三个依赖都装,ENABLE_AV=ON;只跑协议就ENABLE_AV=OFF,只装 libsodium。别两个都要,后面 DLL 部署会多一层麻烦。
1.3 为什么 Windows 上这货比 Linux 难伺候
在 Linux 上装 toxcore 依赖就是一条 apt 命令的事,macOS 也能用 brew 搞定。Windows 的麻烦来自四个方面:
- 依赖库不会随系统提供,libsodium、opus、libvpx 都得自己准备;
- 项目有不少从 POSIX 环境带过来的历史代码,在 MSVC 下要处理线程、socket、时间函数等多重移植问题;
- vcpkg、CMake、MSVC 三者版本必须能互相配合,错一个版本就出各种看不懂的报错;
- DLL 部署问题,编译成功往往只是第一步,运行起来可能还缺文件。
这四点贯穿整个教程,后面每一节都是在跟它们打交道。
2. 环境准备:四件套装齐,后面流程才顺
2.1 Visual Studio 2026:别装了 .NET 就以为完事
安装 VS2026 时,一定要选择“使用 C++ 的桌面开发”这个工作负载,而不是默认的 .NET 负载。勾选之后确认包含这几个组件:MSVC 编译器(v143 之后的版本)、最新 Windows SDK、C++ CMake 工具(这是 VS 的 CMake 集成组件,很多人漏掉)。
验证方法很直接:打开开始菜单里的“x64 Native Tools Command Prompt for VS2026”,执行cl。如果能看到编译器版本打印出来,说明 MSVC 工具链可用了。这个窗口比普通 PowerShell 多配好了编译环境和路径,后面所有命令行操作我都建议在这个窗口或者 Developer PowerShell 里做。
2.2 Git 与 CMake 的版本检查
VS 自带 CMake,但版本通常会滞后。为了命令行操作可控,我习惯用 winget 单独装最新版:
winget install Git.Git winget install CMake.CMake装完新开一个终端验证:
git --version cmake --version注意:PATH 修改后必须新开窗口,Windows 不会自动重新读取环境变量。这一条能帮你避开一半“我明明装了怎么还是找不到”的疑惑。
2.3 vcpkg:依赖管理的主角
把 vcpkg 放到一个固定路径,比如C:\dev\vcpkg:
git clone https://github.com/microsoft/vcpkg.git C:\dev\vcpkg cd C:\dev\vcpkg .\bootstrap-vcpkg.batbootstrap 结束后会生成vcpkg.exe。建议顺手设置VCPKG_ROOT环境变量:
setx VCPKG_ROOT C:\dev\vcpkg后面 CMake 工具链文件的地址会用到它。而且 VS 的 CMake 集成在检测到VCPKG_ROOT时会自动感知 vcpkg,省去手动填一堆路径的麻烦。
2.4 NASM:只有全功能路线需要
如果你决定ENABLE_AV=ON,那 libvpx 构建时要用 NASM 编译 SIMD 汇编优化,缺了它 vpx 直接失败。安装命令:
winget install NASM.NASM验证方法还是那句:新开终端跑nasm -v。如果安装器没把 NASM 加进 PATH,手动把安装目录(一般是C:\Program Files\NASM)加进系统环境变量。
3. 依赖库怎么进工程:我的建议是 vcpkg 一把梭
3.1 vcpkg 安装命令与每个包的作用
全功能路线下,核心命令只有一条:
vcpkg install libsodium opus libvpx --triplet x64-windows逐个说清楚:
libsodium:提供 Curve25519、ChaCha20、Poly1305 等加密原语,Tox 协议的所有加密都建立在它上面。这条路线的必需品;opus:音频编解码库,只有ENABLE_AV=ON才需要;libvpx:视频编解码库(VP8),同样只有 AV 才需要。
装完可以vcpkg list确认。这个过程会从源码编译,视机器性能大概 5 到 15 分钟,耐心等。网络不太稳的话,重跑几次,或者先执行一下vcpkg update再装,基本都能解决。
3.2 为什么推荐 vcpkg 而不是自己下源码编
Windows 上有大量“下载预编译包然后设置 CMake 变量”的古早教程,那种方式在现在很容易翻车:预编译包是哪个编译器编的、用的是哪个 CRT、x86 还是 x64、Debug 还是 Release,全部都要对上。只要错一个,链接阶段就是一堆莫名其妙的符号错误。
vcpkg 从源码统一编译,通过 toolchain 文件自动把 include 目录、库目录和依赖导出信息传给 CMake,跨编译器、跨 triplet 的问题会少一个数量级。这也是 c-toxcore 官方文档目前推荐的 Windows 依赖安装方式。
3.3 备用方案:c-toxcore 自带的依赖构建脚本
c-toxcore 的 CMake 在找不到系统或 vcpkg 依赖时,会尝试用仓库里的脚本自动拉源码构建。这个机制在 Linux 上很顺,在 Windows 上属于“能跑但看运气”:拉取源码的时机、版本、NASM 是否就位,都会影响结果。
我的建议是把它当兜底,别当主方案。真要试的话,等 configure 阶段出现“building from source”之类的提示后,盯紧 vpx 那一步,它最容易被 NASM 卡住。
4. 两种编译姿势:命令行和 VS2026 的 CMake 集成
4.1 命令行配置参数逐个讲清楚
先 clone 源码:
git clone --recurse-submodules https://github.com/TokTok/c-toxcore.git C:\dev\c-toxcore然后在“x64 Native Tools Command Prompt for VS2026”或者 PowerShell 里执行:
cmake -S C:\dev\c-toxcore -B C:\dev\c-toxcore-build ` -G "Visual Studio 17 2026" -A x64 ` -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_ROOT\scripts\buildsystems\vcpkg.cmake" ` -DVCPKG_TARGET_TRIPLET=x64-windows ` -DENABLE_AV=ON ` -DENABLE_SHARED=ON ` -DENABLE_STATIC=ON ` -DCMAKE_INSTALL_PREFIX=C:\dev\tox-install参数逐个说:
-G "Visual Studio 17 2026":VS2026 对应的 CMake 生成器。如果你机器上的 CMake 版本旧,可能不认识这个名字,先执行cmake --help看列表里有什么,以实际输出为准;也可以先把 CMake 升到最新再跑;-A x64:目标架构,和后面的 vcpkg triplet 必须一致;CMAKE_TOOLCHAIN_FILE:vcpkg 的灵魂。不传它,后面依赖全部找不到;VCPKG_TARGET_TRIPLET:指定 vcpkg 依赖的架构配置,x64-windows对应动态库形态;ENABLE_AV、ENABLE_SHARED、ENABLE_STATIC:按第一节的路线选;CMAKE_INSTALL_PREFIX:指定安装输出目录,后面找产物方便。
configure 成功之后,构建并安装:
cmake --build C:\dev\c-toxcore-build --config Release --parallel 8 cmake --install C:\dev\c-toxcore-build --config ReleaseVS 生成器是多配置的,--config Release必须写。不写的话默认 Debug,后面链接时容易和 Release 的 vcpkg 库打架。
4.2 VS2026 打开文件夹方式
不想敲命令行的话,VS2026 直接文件 → 打开 → 文件夹,选 c-toxcore 根目录。VS 会识别 CMakeLists.txt 并自动开始配置。
推荐在根目录放一份CMakePresets.json,让 VS 和命令行共用同一套配置,避免两边参数不一致:
{ "version": 6, "cmakeMinimumRequired": { "major": 3, "minor": 25, "patch": 0 }, "configurePresets": [ { "name": "vs2026-x64", "displayName": "VS2026 x64 Release", "generator": "Visual Studio 17 2026", "architecture": "x64", "binaryDir": "${sourceDir}/out/build/vs2026-x64", "cacheVariables": { "CMAKE_TOOLCHAIN_FILE": "C:/dev/vcpkg/scripts/buildsystems/vcpkg.cmake", "VCPKG_TARGET_TRIPLET": "x64-windows", "ENABLE_AV": "ON", "ENABLE_SHARED": "ON", "ENABLE_STATIC": "ON" } } ], "buildPresets": [ { "name": "vs2026-x64", "configurePreset": "vs2026-x64", "configuration": "Release" } ] }配置好后在 VS 顶部的配置下拉框里选vs2026-x64,直接点“生成”就行。出问题时 VS 底部的 CMake 输出面板会给出详细日志,方便定位。
4.3 产物在哪
编译安装完成后,检查这几个文件:
C:\dev\tox-install\include\tox\tox.h C:\dev\tox-install\lib\toxcore.lib C:\dev\tox-install\bin\toxcore.dll C:\dev\tox-install\bin\toxav.dll一个提醒:如果同时开了ENABLE_STATIC和ENABLE_SHARED,MSVC 下静态.lib和动态导入库.lib容易出现在同一目录且名字相近,很容易拿错。我习惯一次只开一种形态,或者安装后立刻用dir /s C:\dev\tox-install核对文件清单。
5. 踩坑实录:六个高频翻车点
5.1 “找不到编译器”不等于你没装 VS
现象:configure 阶段报CMake Error: No CMAKE_C_COMPILER could be found。
原因:大概率是 VS 只装了 .NET 工作负载,或者虽装了 C++ 负载但缺 MSVC 编译器组件;另一种可能是 CMake 版本太老,不认识 VS2026 这个生成器。
处理:
- 打开 VS Installer 补装“使用 C++ 的桌面开发”,确认里面含 MSVC 编译器和 Windows SDK;
- 命令行别用普通 PowerShell,换成“x64 Native Tools Command Prompt for VS2026”;
- 执行
winget upgrade CMake.CMake,把 CMake 升到最新,新版才认识新生成器。
5.2 依赖找不到:toolchain 没传、triplet 错位、包名写错
现象:configure 阶段报Could NOT find Sodium、Could NOT find Opus,或者 libvpx 找不到。
原因:这一条有三成是因为没传CMAKE_TOOLCHAIN_FILE,三成是 triplet 架构不一致,剩下三成是包名或缓存问题。
处理,按顺序查:
- 确认 CMake 命令里
CMAKE_TOOLCHAIN_FILE指向了vcpkg\scripts\buildsystems\vcpkg.cmake; - 确认
vcpkg install --triplet x64-windows和 CMake 侧-DVCPKG_TARGET_TRIPLET=x64-windows -A x64一致,别一个 x64 一个 x86; - 包名别写错,vcpkg 里是
opus不是libopus,是libsodium不是sodium; - 改了 toolchain 或 triplet 之后,必须删除
CMakeCache.txt再重新 configure,CMake 会把旧的查找结果缓存下来,不删就是白改。
5.3 NASM 缺失:vpx 构建失败,而且不会特别提醒你
现象:日志停在 libvpx 相关步骤,出现nasm或yasm字样错误;有的版本只是最后一步失败,有的直接卡死不动。
原因:libvpx 的 SIMD 汇编优化依赖 NASM,MSVC 不会自带这个工具。
处理:安装 NASM 并加入 PATH 后,删掉整个 build 目录重新 configure。为什么必须删?因为 CMake 会把“找不到 NASM”这个结果缓存起来,只重跑一次 configure 很可能会继续报错。如果明确不需要音视频,直接加-DENABLE_AV=OFF,这一步就彻底绕开了。
5.4 pthread 链接错误:旧版本的老账
现象:链接阶段报LNK2019: unresolved external symbol __imp_pthread_create,甚至一长串pthread_*符号都找不到;更早一点的话,编译阶段会直接报fatal error C1083: Cannot open include file: 'pthread.h'。
原因:早期 c-toxcore 实现里直接用了 POSIX 线程接口,而 MSVC 只有 Win32 线程和 C11 线程。主线近几年代码已经收敛这块,但如果你 clone 的是老分支或某个长期不更新的 fork,依然会撞上。
处理:
- 优先切新版本:
git fetch --tags,然后 checkout 最新的 release tag; - 必须编旧版时,给 MSVC 补一个 pthread 兼容实现(vcpkg 里搜 pthread 相关 port 装上),并把它的 include 和 lib 路径通过
CMAKE_INCLUDE_PATH、CMAKE_LIBRARY_PATH传给 CMake; - 如果只是测试协议功能,直接用新版本最省事,别在旧版上死磕。
5.5 RuntimeLibrary 冲突:LNK2038 全家桶
现象:链接阶段报LNK2038: mismatch detected for 'RuntimeLibrary',后面还跟着一堆看不懂的LNK2001。
原因:依赖库用了动态 CRT(/MD),你的工程却设成了静态 CRT(/MT);或者 Debug 和 Release 混着链接。vcpkg 默认x64-windows按 /MD 构建,toxcore 的默认配置也走 /MD,所以“全默认”反而没事,手贱去改运行库设置才容易出事。
处理:
- 保持默认,VS 工程里检查
配置属性 → C/C++ → 代码生成 → 运行库,确保是 /MD; - 想全静态链接:vcpkg 用
--triplet x64-windows-static(这个 triplet 会同时把 CRT 静态化),CMake 侧同步改-DVCPKG_TARGET_TRIPLET=x64-windows-static; - 永远 Debug 对 Debug,Release 对 Release,不要混。
5.6 编译成功但一运行就缺 DLL
现象:测试程序编译、链接全过,一运行报“由于找不到 toxcore.dll / libsodium.dll,无法继续执行代码”。
原因:动态库所在目录不在 PATH;而且 vcpkg 默认 triplet 的 libsodium、opus、libvpx 也是以 DLL 形式存在的,toxcore.dll 依赖它们,必须一起带上。
处理:
- 在 VS 开发者命令行里用
dumpbin /dependents C:\dev\tox-install\bin\toxcore.dll看看具体依赖谁; - 把下面目录里的 DLL 复制到 exe 旁边,或者加入 PATH:
C:\dev\tox-install\bin(toxcore.dll / toxav.dll)C:\dev\vcpkg\installed\x64-windows\bin(libsodium.dll / opus.dll / vpx.dll)
- 嫌麻烦就全静态构建:
-DENABLE_SHARED=OFF,vcpkg 用x64-windows-static,最终 exe 不需要外带这些业务 DLL(VC 运行库另行处理,用 vc_redist 或本地部署都可以)。
6. 验证库可用:写个三行冒烟程序
6.1 冒烟测试
编译成功不等于能用,我习惯写一个最小的 C 程序验证库真的可以链接:
#include <tox/tox.h> #include <stdio.h> int main(void) { printf("tox_version: %s\n", tox_version_str()); printf("compatible: %d\n", tox_version_is_compatible(tox_version_major(), tox_version_minor(), tox_version_patch())); return 0; }用 MSVC 编译:
cl /nologo /I C:\dev\tox-install\include main.c /link C:\dev\tox-install\lib\toxcore.lib运行前把 DLL 路径加好:
$env:PATH = "C:\dev\tox-install\bin;C:\dev\vcpkg\installed\x64-windows\bin;" + $env:PATH .\main.exe输出大概长这样,能打印出版本号说明核心库没问题:
tox_version: 0.2.x compatible: 16.2 你自己的工程怎么接
如果是 CMake 工程,不要手写一堆硬编码路径,用find_path和find_library更干净:
cmake_minimum_required(VERSION 3.20) project(tox_demo C) find_path(TOX_INCLUDE_DIR NAMES tox/tox.h REQUIRED) find_library(TOX_LIBRARY NAMES toxcore REQUIRED) add_executable(tox_demo main.c) target_include_directories(tox_demo PRIVATE ${TOX_INCLUDE_DIR}) target_link_libraries(tox_demo PRIVATE ${TOX_LIBRARY})如果find_library找不到库,用-DCMAKE_PREFIX_PATH指定 install 目录即可:
cmake -S . -B build -DCMAKE_PREFIX_PATH=C:\dev\tox-install动态链接的话,记得把依赖 DLL 放到可执行文件旁边,或者按 5.6 的方式处理 PATH。
6.3 交付建议
最后说点交付层面的经验。给别人发库的时候,明确两种形态:
- 动态交付:把 toxcore/toxav DLL 连同 vcpkg 的依赖 DLL 一起打进发布目录,文件多但升级方便;
- 静态交付:
ENABLE_STATIC=ON+ vcpkgx64-windows-static,生成物少,对方集成时几乎不需要处理 DLL,适合分发给不够熟悉的团队。
无论哪种,install 之后都养成一个习惯:dir /s C:\dev\tox-install把文件清单过一遍,别等到对方集成时才暴露缺文件的问题。
最后再分享一点我自己的体会。现在重新在 Windows 上编 c-toxcore,我会先把 vcpkg 升到最新,再决定ENABLE_AV开不开,最后固定用 CMakePresets 统一命令行和 VS 的行为。踩过的坑里,最冤枉的一次是改完 PATH 没开新终端,导致 NASM 版本验证通过但 CMake 还是找不到;最值钱的经验是“改了环境变量或依赖相关配置后,删掉 build 缓存重配一次”。这套流程看着长,理顺之后十分钟内就能出库,希望这篇能让你少走几趟弯路。