记录一次踩坑过程(clion + cmake + vcpkg) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
zcion
V2EX    C++

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

  •  
  •   zcion 55 天前 1822 次点击
    这是一个创建于 55 天前的主题,其中的信息可能已经有所发展或是发生改变。

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

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

    CMAKE_TOOLCHAIN_FILE 举例,使用 vcpkg + code>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 中的值是否有问题

    5 条回复    2025-08-15 10:02:26 +08:00
    ashong
        1
    ashong  
       55 天前 via iPhone
    VCPKG_TARGET_TRIPLET 设置强制就可以了

    用 presets 更省事
    hwdq0012
        2
    hwdq0012  
       55 天前
    文档里好像有要求要写在前面吧,我找找
    hwdq0012
        3
    hwdq0012  
       55 天前
    @hwdq0012 #2 https://learn.microsoft.com/zh-cn/vcpkg/get_started/get-started?pivots=shell-powershell
    文档变好快, 这个 preset 我之前都不知道, 不过我一般都用清单模式不同的项目的依赖编译到不同的目录,再手动设置进去,cmake_toolchain_file 我一般都指向自己的交叉编译工具链文件
    hwdq0012
        4
    hwdq0012  
       55 天前
    hwdq0012
        5
    hwdq0012  
       55 天前
    @hwdq0012 #3
    CMake Presets:由 CMake 从 3.19+ 支持。
    vcpkg 官方推荐使用 Presets:大约从 2023 年开始逐步推广,20242025 的官方文档中明确使用示例。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     1986 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 23ms UTC 16:11 PVG 00:11 LAX 09:11 JFK 12:11
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86