最稳妥的方式是使用find_package(tbb required config)并链接tbb::tbb,因其能自动适配路径、构建类型及组件;若无tbbconfig.cmake,则用find_path与find_library手动定位头文件和库,再通过target_include_directories和target_link_libraries引入,同时需显式处理debug/release对应的dll复制。

find_package 是 Windows 上链接第三方库最稳妥的方式,但直接写 target_link_libraries(my_app tbb) 很可能在不同机器上失败——它依赖系统路径、头文件位置、甚至库的命名规则(比如 tbb.dll vs tbb.lib vs libtbb.a),而 Windows 没有统一的默认安装位置。
为什么不能直接用 target_link_libraries(my_app tbb)
这条命令会让 CMake 去默认路径(如 C:/Program Files/tbb/lib 或环境变量 LIB 路径)找 tbb.lib,同时假定头文件在 C:/Program Files/tbb/include。但现实是:
- 你装的 tbb 可能在
C:/Users/xxx/tbb-2021.5,而别人在D:/dev/libs/tbb - 你用的是预编译二进制包,里面只有
tbb.dll和tbb.lib,但没提供tbbConfig.cmake文件,find_package(tbb)就会失败 - VS 编译器对 Debug/Release 库名区分严格:
tbb.lib(Release)和tbb_debug.lib(Debug),硬写tbb会导致 Debug 构建链接失败
find_package(... CONFIG) 才是 Windows 友好方案
只要第三方库提供了 XXXConfig.cmake(比如 vcpkg、conan 或官方预编译包通常自带),就优先走这条路。它能自动适配路径、组件、构建类型:
- 先确认你手上的 tbb 是否含
tbbConfig.cmake:打开解压目录,搜*Config.cmake或*-config.cmake - 如果找到了,设置
tbb_DIR指向其所在目录(不是根目录,而是包含tbbConfig.cmake的那个子目录,通常是lib/cmake/tbb/) - 写法示例:
set(tbb_DIR "C:/Users/archibate/installed/tbb/lib/cmake/tbb") find_package(TBB REQUIRED CONFIG) target_link_libraries(my_app PRIVATE TBB::tbb)
注意:TBB::tbb 是 IMPORTED target 名,不是字符串 "tbb";大小写敏感,且必须用 :: 命名空间形式。
找不到 XXXConfig.cmake?用 find_library + find_path 手动定位
这是 Windows 下最常 fallback 的方式,比硬写绝对路径安全,也比 link_directories 更可控:
-
find_path查头文件目录(对应#include <tbb></tbb>) -
find_library查.lib(不是.dll!链接时需要 .lib,运行时才要 .dll) - 把结果传给
target_include_directories和target_link_libraries,避免污染全局作用域
find_path(TBB_INCLUDE_DIR NAMES tbb/parallel_for.h HINTS "C:/Users/archibate/installed/tbb/include")
find_library(TBB_LIBRARY NAMES tbb tbb_debug HINTS "C:/Users/archibate/installed/tbb/lib")
if(NOT TBB_INCLUDE_DIR OR NOT TBB_LIBRARY)
message(FATAL_ERROR "TBB not found: include=${TBB_INCLUDE_DIR}, lib=${TBB_LIBRARY}")
endif()
target_include_directories(my_app PRIVATE ${TBB_INCLUDE_DIR})
target_link_libraries(my_app PRIVATE ${TBB_LIBRARY})
关键点:HINTS 支持多个路径,也可用 PATHS 强制搜索;NAMES 列出所有可能的库名(tbb、tbb_debug、tbb_preview 等),让 CMake 自动选匹配当前构建类型的那个。
运行时 dll 怎么放?别只靠 PATH
Windows 链接成功 ≠ 运行成功。tbb.dll 必须被加载器找到,常见做法:
- 把
tbb.dll复制到可执行文件同目录(cmake --install时用file(COPY ...)或INSTALL(DIRECTORY ...)) - 在 CMake 中用
add_custom_command在 build 后自动复制:
add_custom_command(TARGET my_app POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different
"$<tbb>/tbb.dll"
"$<my_app>/tbb.dll")</my_app></tbb>
注意:$<tbb></tbb> 仅在 tbb 是 IMPORTED target 时有效;若手动找库,则需写死路径或用 get_filename_component 提取目录。
真正容易被忽略的是:Debug 和 Release 的 dll 名往往不同(tbb_debug.dll vs tbb.dll),而 Visual Studio 默认不自动复制任何 dll —— 不显式处理,程序双击就报“找不到 tbb.dll”。











