You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Vcpkg+CMake构建含第三方库的共享库时编译报错求助

单文件CMake配置找不到fmt/color.h的问题排查

问题背景

作为CMake新手,尝试用Vcpkg+CMake构建依赖fmt、spdlog的共享库:

  • 单文件CMakeLists.txt配置编译时,出现找不到fmt/color.h的致命错误
  • 改用根目录+子目录的CMake结构时,编译可成功完成

文件结构:

  • 根目录下包含include文件夹、src文件夹
  • src文件夹内有main.cpp文件

报错的单文件CMakeLists.txt配置

cmake_minimum_required(VERSION 3.28)

project(Vcpkg)

set (CMAKE_CXX_STANDARD 20)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

find_package(fmt REQUIRED)  
find_package(spdlog REQUIRED)  

file(GLOB SOURCES src/*.cpp include/*.hpp)
add_library(Vcpkg SHARED ${SOURCES})
add_library(vcpkg::engine ALIAS Vcpkg)

target_include_directories(Vcpkg
    PUBLIC
        $<INSTALL_INTERFACE:include>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src)

add_executable(akash ${SOURCES})

SET(GCC_COVERAGE_COMPILE_FLAGS "-g -O0 -coverage -fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS   "-coverage -lgcov")
SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )

target_compile_features(akash PRIVATE cxx_std_20)
target_link_libraries(akash
    PRIVATE 
        vcpkg::engine
        fmt::fmt 
        spdlog::spdlog
)

错误信息

1/5] Scanning /home/akashdiphazra/Downloads/Vcpkg/src/main.cpp for CXX dependencies
FAILED: CMakeFiles/Vcpkg.dir/src/main.cpp.o.ddi 
/usr/bin/c++ -DVcpkg_EXPORTS -I/home/akashdiphazra/Downloads/Vcpkg/include -I/home/akashdiphazra/Downloads/Vcpkg/src -g -O0 -coverage -fprofile-arcs -ftest-coverage -g -std=gnu++20 -fPIC -fdiagnostics-color=always -E -x c++ /home/akashdiphazra/Downloads/Vcpkg/src/main.cpp -MT CMakeFiles/Vcpkg.dir/src/main.cpp.o.ddi -MD -MF CMakeFiles/Vcpkg.dir/src/main.cpp.o.ddi.d -fmodules-ts -fdeps-file=CMakeFiles/Vcpkg.dir/src/main.cpp.o.ddi -fdeps-target=CMakeFiles/Vcpkg.dir/src/main.cpp.o -fdeps-format=p1689r5 -o CMakeFiles/Vcpkg.dir/src/main.cpp.o.ddi.i
/home/akashdiphazra/Downloads/Vcpkg/src/main.cpp:1:10: fatal error: fmt/color.h: No such file or directory
    1 | #include <fmt/color.h>
      |          ^~~~~~~~~~~~~
compilation terminated.
ninja: build stopped: subcommand failed.
make: *** [Makefile:10: debug] Error 1

可成功编译的CMake配置

根目录CMakeLists.txt

cmake_minimum_required (VERSION 3.28)

project(Vcpkg)

find_package(fmt REQUIRED)
find_package(spdlog REQUIRED)

# Add sub directories
include_directories(include)
add_subdirectory(src)

set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

src/CMakeLists.txt

set (CMAKE_CXX_STANDARD 20)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

SET(GCC_COVERAGE_COMPILE_FLAGS "-g -O0 -coverage -fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS   "-coverage -lgcov")
SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )

add_executable(akash main.cpp)
target_compile_features(akash PRIVATE cxx_std_20)
target_link_libraries(akash fmt::fmt spdlog::spdlog)

问题原因分析

  1. 共享库目标未关联依赖:
    报错的配置中,仅给可执行文件akash链接了fmt::fmt和spdlog::spdlog,但共享库Vcpkg的源文件(包括main.cpp)同样依赖这些库的头文件。编译共享库目标时,CMake不会自动继承可执行文件的依赖,导致库编译过程无法找到fmt/color.h。

  2. 重复添加源文件:
    把src/*.cpp同时加到共享库Vcpkg和可执行文件akash中,属于重复编译源文件,不仅冗余,还会导致库和可执行文件的编译环境分离,依赖传递失效。

  3. 成功配置的对比:
    可成功的配置没有创建额外的共享库目标,直接给可执行文件akash链接依赖,编译时能直接获取fmt、spdlog的头文件路径,因此不会报错。


修复方案

修改单文件CMakeLists.txt,给共享库目标添加依赖链接,同时避免重复使用源文件:

cmake_minimum_required(VERSION 3.28)

project(Vcpkg)

set (CMAKE_CXX_STANDARD 20)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)

find_package(fmt REQUIRED)  
find_package(spdlog REQUIRED)  

# 仅给库添加源文件(可执行文件只链接库,不重复包含源文件)
file(GLOB LIB_SOURCES src/*.cpp include/*.hpp)
add_library(Vcpkg SHARED ${LIB_SOURCES})
add_library(vcpkg::engine ALIAS Vcpkg)

# 给共享库链接依赖,传递头文件路径
target_link_libraries(Vcpkg
    PRIVATE
        fmt::fmt
        spdlog::spdlog
)

target_include_directories(Vcpkg
    PUBLIC
        $<INSTALL_INTERFACE:include>
        $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
    PRIVATE
        ${CMAKE_CURRENT_SOURCE_DIR}/src)

# 可执行文件只需要库的别名,不需要重复源文件
add_executable(akash src/main.cpp)

SET(GCC_COVERAGE_COMPILE_FLAGS "-g -O0 -coverage -fprofile-arcs -ftest-coverage")
SET(GCC_COVERAGE_LINK_FLAGS   "-coverage -lgcov")
SET(CMAKE_CXX_FLAGS  "${CMAKE_CXX_FLAGS} ${GCC_COVERAGE_COMPILE_FLAGS}" )
SET(CMAKE_EXE_LINKER_FLAGS  "${CMAKE_EXE_LINKER_FLAGS} ${GCC_COVERAGE_LINK_FLAGS}" )

target_compile_features(akash PRIVATE cxx_std_20)
target_link_libraries(akash
    PRIVATE 
        vcpkg::engine
)

内容的提问来源于stack exchange,提问作者Akashdip Hazra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 00:12:17