cmake Conan:如何从'conanfile.py'中获取依赖项的源文件夹?

yrdbyhpb  于 2023-01-20  发布在  其他
关注(0)|答案(1)|浏览(256)

我想创建一个可以下载的项目源代码的conan Package 器。
请注意,我不能修改该项目中的任何内容;我只是得到了一个URL,从那里可以下载它。
我知道如何通过在conanfile.pysource()方法中添加一些代码来下载和解压缩项目的源代码(使用tools模块)。
这个项目(下载并解压缩后)可以用cmake构建,也可以使用Boost。
所以我在build_requires中添加了boost/1.75(我随意选择了这个版本)。
在该项目的cmake配置阶段,可以将Boost的位置文件夹作为参数传递给cmake(例如-DWITH_BOOST=path_name)。
但是在build()方法中,我不知道如何获取conan缓存中安装Boost 1.75的文件夹,知道这一点后,我将把它传递给cmake.configure(...)调用。
有没有办法从conanfile.py中获取一个依赖项的包文件夹?也许可以使用self.build_requires['boost/1.75'].package_folder之类的东西?

jgzswidk

jgzswidk1#

获取依赖路径的最简单方法是:

from conans import ConanFile # for type hinting

# conan create
boost: ConanFile = self.dependencies.build["boost"]
boost.package_folder

但它并不总是有效的

# conan build (hacky)
self.deps_cpp_info["boost"].build_paths[0]
  • 它可能不是在所有步骤中都可用(我没有详细检查)

获取这些信息最可靠的方法是从conanbuildinfo.txt读取if--这个文件是在安装阶段创建的,你可以使用不同的生成器,比如-g json,以不同的格式使用它。

from conans.client.generators import TXTGenerator
with open("conanbuildinfo.txt", "r") as handle:
    contents = handle.read()
deps_cpp_info, deps_user_info, deps_env_info, user_info_build = TXTGenerator.loads(contents)

我在代码中找到的最后一种方法(这可以简化,但这就是我现在所能提供的):

import sys

import conans.errorsc
import conans.cli.exit_codes
from conans import ConanFile

from conans.client.cache.cache import ClientCache
from conans.client.conan_api import Conan
from conans.model.ref import PackageReference
from conans.paths.package_layouts.package_editable_layout import PackageEditableLayout

try:
    conan_api, _, _ = Conan.factory()
except conans.errors.ConanMigrationError:
    sys.exit(conans.cli.exit_codes.ERROR_MIGRATION)
except conans.errors.ConanException as error:
    sys.exit(conans.cli.exit_codes.ERROR_GENERAL)

def _discover_package_path(dependency_name: str) -> str:
    """Returns a package folder in local conan cache for specified dependency.
    Function is similar to:
    > conan info .\conan\conanfile_compiled.py --paths --only package_folder
    This implementation is based on _grab_info_data (Conan version 1.55.0-dev):
    >>> from conans.client.conan_command_output import CommandOutputer
    >>> CommandOutputer._grab_info_data
    """
    data, _ = conan_api.info(reference_or_path="conanfile.py")
    node = next(node for node in data.nodes if node.name == dependency_name)
    cache = ClientCache(conan_api.cache_folder, conan_api.out)
    layout = cache.package_layout(node.ref, node.conanfile.short_paths)
    if isinstance(layout, PackageEditableLayout):
        return node.conanfile.package_folder
    else:
        return layout.package(PackageReference(node.ref, node.package_id))

# _discover_package_path("cmake")

class MyDummy(ConanFile):
    name = "MyDummy"
    version = "0.0.1"
    requires = "boost/1.71.0"

    def build(self):
        print(80 * "#")
        print(_discover_package_path("boost"))
        print(80 * "#")

相关问题