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

如何在项目子目录中正确集成jsoncpp并解决编译头文件缺失错误

问题描述

我的项目目录结构如下:

WeaselTestApp
    --build
       ...
    --weasel
        ...
        --CMakeLists.txt
   --main.cpp
   --CMakeLists.txt
   --conanfile.txt

根目录CMakeLists.txt内容:

cmake_minimum_required(VERSION 3.16)
project(WeaselTestApp LANGUAGES CXX)
add_executable(WeaselTestApp main.cpp)

set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)

enable_testing()
add_subdirectory(weasel)
target_link_libraries(WeaselTestApp PRIVATE Weasel)

weasel子目录的CMakeLists.txt内容:

add_library(Weasel Utils.cpp HttpMethod.cpp HttpStatus.cpp Request.cpp Response.cpp Router.cpp Server.cpp)

include_directories(${CONAN_INCLUDE_DIRS_JSONCPP})
set(jsoncpp_DIR "/home/emmanuel/weasle/build")
find_package(jsoncpp REQUIRED)

target_link_libraries(Weasel PRIVATE jsoncpp)

根目录conanfile.txt内容:

[requires]
jsoncpp/1.9.5
gtest/1.11.0

[generators]
CMakeDeps
CMakeToolchain
cmake_find_package

运行cmake --build /home/user/weasle/build时出现编译错误:

[ 10%] Building CXX object weasel/CMakeFiles/Weasel.dir/Utils.cpp.o
[ 20%] Building CXX object weasel/CMakeFiles/Weasel.dir/HttpMethod.cpp.o
[ 30%] Building CXX object weasel/CMakeFiles/Weasel.dir/HttpStatus.cpp.o
[ 40%] Building CXX object weasel/CMakeFiles/Weasel.dir/Request.cpp.o
In file included from /home/user/weasle/weasel/Request.cpp:1:
/home/user/weasle/weasel/Request.h:5:10: fatal error: json/json.h: No such file or directory
    5 | #include <json/json.h>
      |          ^~~~~~~~~~~~~
compilation terminated.
gmake[2]: *** [weasel/CMakeFiles/Weasel.dir/build.make:118: weasel/CMakeFiles/Weasel.dir/Request.cpp.o] Error 1
gmake[1]: *** [CMakeFiles/Makefile2:126: weasel/CMakeFiles/Weasel.dir/all] Error 2
gmake: *** [Makefile:101: all] Error 2

我计划将来把weasel目录做成独立包,因此不想在根目录CMake中处理jsoncpp,请问如何在项目中正确使用jsoncpp?


解决方案

1. 修正Weasel子目录的CMake配置

核心是移除硬编码路径,使用Conan生成的标准化配置,并用目标级设置替代全局设置:

修改weasel/CMakeLists.txt为:

add_library(Weasel Utils.cpp HttpMethod.cpp HttpStatus.cpp Request.cpp Response.cpp Router.cpp Server.cpp)

# 依赖Conan生成的CMakeDeps配置自动查找jsoncpp,无需硬编码路径
find_package(jsoncpp REQUIRED)

# 仅给Weasel目标添加jsoncpp的包含路径,避免污染全局环境
target_include_directories(Weasel PRIVATE ${jsoncpp_INCLUDE_DIRS})

# 使用Conan生成的命名空间目标链接jsoncpp(官方推荐的标准化写法)
target_link_libraries(Weasel PRIVATE jsoncpp::jsoncpp)

2. 执行正确的编译流程

编译前必须先在build目录完成Conan依赖安装,生成正确的依赖配置文件:

cd /home/user/weasle/build
conan install .. --build=missing
cmake ..
cmake --build .

3. 为Weasel独立成包提前适配

如果将来要把Weasel做成独立CMake包,可在weasel/CMakeLists.txt末尾添加以下配置(用于生成包的元配置文件):

include(CMakePackageConfigHelpers)
write_basic_package_version_file(
    WeaselConfigVersion.cmake
    VERSION 0.1.0
    COMPATIBILITY SameMajorVersion
)

install(TARGETS Weasel
    EXPORT WeaselTargets
    LIBRARY DESTINATION lib
    ARCHIVE DESTINATION lib
    RUNTIME DESTINATION bin
    INCLUDES DESTINATION include
)

install(EXPORT WeaselTargets
    FILE WeaselTargets.cmake
    NAMESPACE Weasel::
    DESTINATION lib/cmake/Weasel
)

# 需在weasel目录下新建WeaselConfig.cmake文件,内容见下方
install(FILES
    "${CMAKE_CURRENT_BINARY_DIR}/WeaselConfigVersion.cmake"
    WeaselConfig.cmake
    DESTINATION lib/cmake/Weasel
)

同时在weasel目录下创建WeaselConfig.cmake,内容:

include(CMakeFindDependencyMacro)
# 当Weasel作为独立包被引入时,自动查找依赖的jsoncpp
find_dependency(jsoncpp REQUIRED)

include("${CMAKE_CURRENT_LIST_DIR}/WeaselTargets.cmake")

错误原因说明

  • 硬编码jsoncpp_DIR会导致路径适配问题,Conan的CMakeDeps生成器已经会自动配置依赖路径,无需手动指定。
  • 全局的include_directories不如目标级别的target_include_directories灵活,后者只会影响Weasel自身,符合模块化要求。
  • 直接链接jsoncpp而非jsoncpp::jsoncpp不符合Conan的标准化目标命名规则,后者是Conan生成的官方推荐目标。

内容的提问来源于stack exchange,提问作者Emmanuel Amodu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 15:45:20