记录一次踩坑过程(clion + cmake + vcpkg)

26 天前
 zcion

首先结论放这里:编写 cmake 文件时,project(xxx) 放在越后边越好,避免在它之后定义和构建相关的宏变量

好的,下边是踩坑经历: 楼主在写一个程序时,突发奇想的想分别使用 vs 工具链和 mingw 工具链跑下代码,所需要的库文件都是用 vcpkg 下载的。

CMAKE_TOOLCHAIN_FILE 举例,使用 vcpkg + cmake,就需要定义这个值(指明你的 vcpkg.cmake 放在哪个路径下,通常是 xxx/vcpkg/scripts/buildsystems/vcpkg.cmake)。要定义这个值,要么就是在执行 cmake 构建命令时加上 -DCMAKE_TOOLCHAIN_FILE 参数,要么就是直接在 cmake 文件中指定。第二种方法很好理解,直接在 cmake 文件定义就行( clion 在构建时会将其添加进 cache variable),而第一种,如果是在 clion 中,你就需要在如下图位置指定:

那么问题就来了,由于楼主需要分别使用 msvcgcc 编译,所以需要定义 VCPKG_TARGET_TRIPLET 来选用 vcpkg 中库文件的 triplet ,第一次用 msvc 编译项目,没有任何问题,但换成 mingw 后就出现莫名其妙的问题(例如 cmake 构建不成功,构建成功但链接时找不到对应的 lib )。在进行了一系列的排查发现,虽然我在 cmake 中指定了 set(VCPKG_TARGET_TRIPLET x64-mingw-dynamic),但 clion 的 cache variable 中的 VCPKG_TARGET_TRIPLET 的值雷打不动的为 x64-windows(因为先用的是 vs 工具链的,所以 clion 一直用的是缓存的值)。在经过很长一段时间的折磨后,我突发奇想的将所有设计 vcpkg 的宏定义提到了 cmake 文件的最前边,然后问题就解决了。

# 从原先的这样
cmake_minimum_required(VERSION 3.30)
project(myproject)
set(CMAKE_TOOLCHAIN_FILE "D:/development-tool/vcpkg/scripts/buildsystems/vcpkg.cmake")
set(VCPKG_TARGET_TRIPLET x64-mingw-dynamic)
# ...

# 变成这样
cmake_minimum_required(VERSION 3.30)
set(CMAKE_TOOLCHAIN_FILE "D:/development-tool/vcpkg/scripts/buildsystems/vcpkg.cmake")
set(VCPKG_TARGET_TRIPLET x64-mingw-dynamic)
# ...
project(myproject)
# ...

最后想通了,在 project() 前定义宏,这些宏就能够在项目在构建前使用,这样 clion 就能够先写入 cache variable,这样就确保项目构建的行为是根据 cmake 文件中来的。反之在 project() 后定义,这些宏就变为在项目构建过程中才能使用,这就导致了 clion 需要在构建前指定 vcpkg 某些宏找不到,所以 clion 用的是缓存的值。

相信有一部分人和我一样,在开始写 cmake 时,喜欢用默认的模板来写,而默认模板的 project() 又是最先写的,等到项目逐渐的开发,需要往 cmake 中假如越来越多东西,这些东西很容易就加到 project() 后,然后一些在构建前需要用到的宏无法被识别,从而引发一系列问题。

这个点可能是 cmake 很常规的一个点,但如果忽略了,就可能像我一样,在 google->ai 后陷入“明明都是按照语法来的,怎么死活就跑不起来”,然后无能狂怒数个小时的情况。

最后再分享点心得,如果什么都看着正常,但项目就是跑不起来,可以看看 cache variable 中的值是否有问题

1567 次点击
所在节点    C++
5 条回复
ashong
26 天前
VCPKG_TARGET_TRIPLET 设置强制就可以了

用 presets 更省事
hwdq0012
26 天前
文档里好像有要求要写在前面吧,我找找
hwdq0012
26 天前
@hwdq0012 #2 https://learn.microsoft.com/zh-cn/vcpkg/get_started/get-started?pivots=shell-powershell
文档变好快, 这个 preset 我之前都不知道, 不过我一般都用清单模式不同的项目的依赖编译到不同的目录,再手动设置进去,cmake_toolchain_file 我一般都指向自己的交叉编译工具链文件
hwdq0012
26 天前
hwdq0012
26 天前
@hwdq0012 #3
CMake Presets:由 CMake 从 3.19+ 支持。
vcpkg 官方推荐使用 Presets:大约从 2023 年开始逐步推广,2024–2025 的官方文档中明确使用示例。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/1152503

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX