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

创建并使用Conan包时遇问题:库目录未设置

问题:Conan包hjson库目录未同步导致链接失败

问题背景

为第三方工具hjson创建了Conan包,执行conan create .成功部署到~/.conan目录,但测试使用时链接器找不到库。查看生成的hjson-config.cmake发现hjson_LIB_DIRS未设置,尽管已在包的package_info中配置了cpp_info.libdirs。

相关代码

1. hjson的conanfile.py

class HjsonConan(ConanFile):
    name = "hjson"
    version = "2.2"
    url = "https://github.com/hjson/hjson-cpp"
    license="MIT"

    # Optional metadata
    description = "hjson C++ json library"

    # Binary configuration
    settings = "os", "compiler", "build_type", "arch"
    options = {"shared": [True, False], "fPIC": [True, False], "version": "ANY"}
    default_options = {"shared": False, "fPIC": True, "version": "2.2"}

    # Sources are located in the same place as this recipe, copy them to the recipe
    exports_sources = ("hjson-src/*")

    def source(self):
        # unpacks into ./hjson-src
        get(self,
            f"https://github.com/hjson/hjson-cpp/archive/refs/tags/{self.options.version}.tar.gz",
            destination='hjson-src',
            strip_root=True)

    def config_options(self):
        if self.settings.os == "Windows":
            del self.options.fPIC

    def layout(self):
        # Sets source=., build=build/Release, generators=build/generators
        cmake_layout(self)

    def generate(self):
        tc = CMakeToolchain(self)
        # Here is where to set CMake variables ("-DXYZ")
        tc.variables["HJSON_ENABLE_INSTALL"] = 1
        tc.generate()

    def build(self):
        cmake = CMake(self)
        cmake.configure(build_script_folder='hjson-src')
        cmake.build()

    def package(self):
        cmake = CMake(self)
        cmake.install()

    def package_info(self):
        self.cpp_info.libs = ["hjson"]
        # these are the defaults, here for clarity
        self.cpp_info.includedirs = ["include"]
        self.cpp_info.libdirs = ["lib"]

2. 测试用的conanfile.py

from conan import ConanFile
from conan.tools.cmake import CMake, cmake_layout
from conan.tools.build import cross_building


class HJsonTestConan(ConanFile):
    settings = "os", "compiler", "build_type", "arch"
    # VirtualBuildEnv and VirtualRunEnv can be avoided if "tools.env.virtualenv:auto_use" is defined
    # (it will be defined in Conan 2.0)
    generators = "CMakeDeps", "CMakeToolchain", "VirtualBuildEnv", "VirtualRunEnv"
    apply_env = False
    test_type = "explicit"

    def requirements(self):
        self.requires("hjson/2.2")

    def build(self):
        cmake = CMake(self)
        cmake.configure()
        cmake.build()

    def layout(self):
        cmake_layout(self)

    def test(self):
        if not cross_building(self):
            cmd = os.path.join(self.cpp.build.bindirs[0], "example")
            self.run(cmd, env="conanrun")

3. 测试用CMakeLists.txt

cmake_minimum_required(VERSION 3.15)
project(PackageTest CXX)

find_package(hjson CONFIG REQUIRED)

add_executable(example src/example.cpp)
set_property(TARGET example PROPERTY CXX_STANDARD 20)
include_directories(${hjson_INCLUDE_DIRS})
link_directories(${hjson_LIB_DIRS})
target_link_libraries(example hjson)

生成的hjson-config.cmake内容

set(hjson_VERSION_STRING "2.2")
set(hjson_INCLUDE_DIRS ${hjson_INCLUDE_DIRS_RELEASE} )
set(hjson_INCLUDE_DIR ${hjson_INCLUDE_DIRS_RELEASE} )
set(hjson_LIBRARIES ${hjson_LIBRARIES_RELEASE} )
set(hjson_DEFINITIONS ${hjson_DEFINITIONS_RELEASE} )

Conan包结构

~/.conan/data/hjson/2.2/_/_/package/37c9d02f...91ef
├── conaninfo.txt
├── conanmanifest.txt
├── include
│  └── hjson
│     └── hjson.h
└── lib
   ├── hjson
   │  ├── hjson-config-version.cmake
   │  ├── hjson-config.cmake
   │  ├── hjson-release.cmake
   │  └── hjson.cmake
   └── libhjson.a

原因分析与解决方法

核心原因

问题出在测试工程优先使用了hjson官方自带的CMake配置文件,而非Conan生成的CMakeDeps配置。执行cmake.install()时,hjson源码自带的hjson-config.cmake会被安装到包的lib/hjson目录,当测试工程执行find_package(hjson CONFIG REQUIRED)时,会优先加载这个官方配置,而官方配置里没有定义hjson_LIB_DIRS变量。

解决步骤

方案1:修改测试工程CMakeLists.txt(推荐,符合现代CMake实践)

官方hjson的CMake配置已经提供了hjson::hjson目标,无需手动设置头文件和库路径,直接链接目标即可:

cmake_minimum_required(VERSION 3.15)
project(PackageTest CXX)

find_package(hjson CONFIG REQUIRED)

add_executable(example src/example.cpp)
set_property(TARGET example PROPERTY CXX_STANDARD 20)
# 直接链接官方提供的目标,自动处理头文件和库路径
target_link_libraries(example PRIVATE hjson::hjson)

方案2:禁用官方CMake配置文件安装,使用Conan生成的配置

修改conanfile.py的generate方法,添加禁用官方CMake配置安装的参数:

def generate(self):
    tc = CMakeToolchain(self)
    tc.variables["HJSON_ENABLE_INSTALL"] = 1
    # 禁用安装官方CMake配置文件,避免干扰Conan的CMakeDeps
    tc.variables["HJSON_INSTALL_CMAKE_CONFIG"] = 0
    tc.generate()

重新执行conan create .创建包,此时Conan会生成包含正确hjson_LIB_DIRS的配置文件,原测试工程的CMakeLists.txt可正常使用。

备选方案:手动删除官方CMake配置文件

如果hjson源码没有HJSON_INSTALL_CMAKE_CONFIG选项,可在package步骤中删除安装的官方配置:

def package(self):
    cmake = CMake(self)
    cmake.install()
    # 删除官方安装的CMake配置目录
    import shutil
    shutil.rmtree(os.path.join(self.package_folder, "lib", "hjson"))

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 18:15:41